|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 "use strict"; |
|
5 |
|
6 const {utils: Cu} = Components; |
|
7 |
|
8 Cu.import("resource://gre/modules/Promise.jsm"); |
|
9 Cu.import("resource://gre/modules/Metrics.jsm"); |
|
10 Cu.import("resource://services-common/utils.js"); |
|
11 |
|
12 |
|
13 const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; |
|
14 |
|
15 |
|
16 function run_test() { |
|
17 run_next_test(); |
|
18 } |
|
19 |
|
20 add_test(function test_days_date_conversion() { |
|
21 let toDays = Metrics.dateToDays; |
|
22 let toDate = Metrics.daysToDate; |
|
23 |
|
24 let d = new Date(0); |
|
25 do_check_eq(toDays(d), 0); |
|
26 |
|
27 d = new Date(MILLISECONDS_PER_DAY); |
|
28 do_check_eq(toDays(d), 1); |
|
29 |
|
30 d = new Date(MILLISECONDS_PER_DAY - 1); |
|
31 do_check_eq(toDays(d), 0); |
|
32 |
|
33 d = new Date("1970-12-31T23:59:59.999Z"); |
|
34 do_check_eq(toDays(d), 364); |
|
35 |
|
36 d = new Date("1971-01-01T00:00:00Z"); |
|
37 do_check_eq(toDays(d), 365); |
|
38 |
|
39 d = toDate(0); |
|
40 do_check_eq(d.getTime(), 0); |
|
41 |
|
42 d = toDate(1); |
|
43 do_check_eq(d.getTime(), MILLISECONDS_PER_DAY); |
|
44 |
|
45 d = toDate(365); |
|
46 do_check_eq(d.getUTCFullYear(), 1971); |
|
47 do_check_eq(d.getUTCMonth(), 0); |
|
48 do_check_eq(d.getUTCDate(), 1); |
|
49 do_check_eq(d.getUTCHours(), 0); |
|
50 do_check_eq(d.getUTCMinutes(), 0); |
|
51 do_check_eq(d.getUTCSeconds(), 0); |
|
52 do_check_eq(d.getUTCMilliseconds(), 0); |
|
53 |
|
54 run_next_test(); |
|
55 }); |
|
56 |
|
57 add_task(function test_get_sqlite_backend() { |
|
58 let backend = yield Metrics.Storage("get_sqlite_backend.sqlite"); |
|
59 |
|
60 do_check_neq(backend._connection, null); |
|
61 |
|
62 // Ensure WAL and auto checkpoint are enabled. |
|
63 do_check_neq(backend._enabledWALCheckpointPages, null); |
|
64 let rows = yield backend._connection.execute("PRAGMA journal_mode"); |
|
65 do_check_eq(rows[0].getResultByIndex(0), "wal"); |
|
66 rows = yield backend._connection.execute("PRAGMA wal_autocheckpoint"); |
|
67 do_check_eq(rows[0].getResultByIndex(0), backend._enabledWALCheckpointPages); |
|
68 |
|
69 yield backend.close(); |
|
70 do_check_null(backend._connection); |
|
71 }); |
|
72 |
|
73 add_task(function test_reconnect() { |
|
74 let backend = yield Metrics.Storage("reconnect"); |
|
75 yield backend.close(); |
|
76 |
|
77 let backend2 = yield Metrics.Storage("reconnect"); |
|
78 yield backend2.close(); |
|
79 }); |
|
80 |
|
81 add_task(function test_future_schema_errors() { |
|
82 let backend = yield Metrics.Storage("future_schema_errors"); |
|
83 yield backend._connection.setSchemaVersion(2); |
|
84 yield backend.close(); |
|
85 |
|
86 let backend2; |
|
87 let failed = false; |
|
88 try { |
|
89 backend2 = yield Metrics.Storage("future_schema_errors"); |
|
90 } catch (ex) { |
|
91 failed = true; |
|
92 do_check_true(ex.message.startsWith("Unknown database schema")); |
|
93 } |
|
94 |
|
95 do_check_null(backend2); |
|
96 do_check_true(failed); |
|
97 }); |
|
98 |
|
99 add_task(function test_checkpoint_apis() { |
|
100 let backend = yield Metrics.Storage("checkpoint_apis"); |
|
101 let c = backend._connection; |
|
102 let count = c._statementCounter; |
|
103 |
|
104 yield backend.setAutoCheckpoint(0); |
|
105 do_check_eq(c._statementCounter, count + 1); |
|
106 |
|
107 let rows = yield c.execute("PRAGMA wal_autocheckpoint"); |
|
108 do_check_eq(rows[0].getResultByIndex(0), 0); |
|
109 count = c._statementCounter; |
|
110 |
|
111 yield backend.setAutoCheckpoint(1); |
|
112 do_check_eq(c._statementCounter, count + 1); |
|
113 |
|
114 rows = yield c.execute("PRAGMA wal_autocheckpoint"); |
|
115 do_check_eq(rows[0].getResultByIndex(0), backend._enabledWALCheckpointPages); |
|
116 count = c._statementCounter; |
|
117 |
|
118 yield backend.checkpoint(); |
|
119 do_check_eq(c._statementCounter, count + 1); |
|
120 |
|
121 yield backend.checkpoint(); |
|
122 do_check_eq(c._statementCounter, count + 2); |
|
123 |
|
124 yield backend.close(); |
|
125 }); |
|
126 |
|
127 add_task(function test_measurement_registration() { |
|
128 let backend = yield Metrics.Storage("measurement_registration"); |
|
129 |
|
130 do_check_false(backend.hasProvider("foo")); |
|
131 do_check_false(backend.hasMeasurement("foo", "bar", 1)); |
|
132 |
|
133 let id = yield backend.registerMeasurement("foo", "bar", 1); |
|
134 do_check_eq(id, 1); |
|
135 |
|
136 do_check_true(backend.hasProvider("foo")); |
|
137 do_check_true(backend.hasMeasurement("foo", "bar", 1)); |
|
138 do_check_eq(backend.measurementID("foo", "bar", 1), id); |
|
139 do_check_false(backend.hasMeasurement("foo", "bar", 2)); |
|
140 |
|
141 let id2 = yield backend.registerMeasurement("foo", "bar", 2); |
|
142 do_check_eq(id2, 2); |
|
143 do_check_true(backend.hasMeasurement("foo", "bar", 2)); |
|
144 do_check_eq(backend.measurementID("foo", "bar", 2), id2); |
|
145 |
|
146 yield backend.close(); |
|
147 }); |
|
148 |
|
149 add_task(function test_field_registration_basic() { |
|
150 let backend = yield Metrics.Storage("field_registration_basic"); |
|
151 |
|
152 do_check_false(backend.hasField("foo", "bar", 1, "baz")); |
|
153 |
|
154 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
155 do_check_false(backend.hasField("foo", "bar", 1, "baz")); |
|
156 do_check_false(backend.hasFieldFromMeasurement(mID, "baz")); |
|
157 |
|
158 let bazID = yield backend.registerField(mID, "baz", |
|
159 backend.FIELD_DAILY_COUNTER); |
|
160 do_check_true(backend.hasField("foo", "bar", 1, "baz")); |
|
161 do_check_true(backend.hasFieldFromMeasurement(mID, "baz")); |
|
162 |
|
163 let bar2ID = yield backend.registerMeasurement("foo", "bar2", 1); |
|
164 |
|
165 yield backend.registerField(bar2ID, "baz", |
|
166 backend.FIELD_DAILY_DISCRETE_NUMERIC); |
|
167 |
|
168 do_check_true(backend.hasField("foo", "bar2", 1, "baz")); |
|
169 |
|
170 yield backend.close(); |
|
171 }); |
|
172 |
|
173 // Ensure changes types of fields results in fatal error. |
|
174 add_task(function test_field_registration_changed_type() { |
|
175 let backend = yield Metrics.Storage("field_registration_changed_type"); |
|
176 |
|
177 let mID = yield backend.registerMeasurement("bar", "bar", 1); |
|
178 |
|
179 let id = yield backend.registerField(mID, "baz", |
|
180 backend.FIELD_DAILY_COUNTER); |
|
181 |
|
182 let caught = false; |
|
183 try { |
|
184 yield backend.registerField(mID, "baz", |
|
185 backend.FIELD_DAILY_DISCRETE_NUMERIC); |
|
186 } catch (ex) { |
|
187 caught = true; |
|
188 do_check_true(ex.message.startsWith("Field already defined with different type")); |
|
189 } |
|
190 |
|
191 do_check_true(caught); |
|
192 |
|
193 yield backend.close(); |
|
194 }); |
|
195 |
|
196 add_task(function test_field_registration_repopulation() { |
|
197 let backend = yield Metrics.Storage("field_registration_repopulation"); |
|
198 |
|
199 let mID1 = yield backend.registerMeasurement("foo", "bar", 1); |
|
200 let mID2 = yield backend.registerMeasurement("foo", "bar", 2); |
|
201 let mID3 = yield backend.registerMeasurement("foo", "biz", 1); |
|
202 let mID4 = yield backend.registerMeasurement("baz", "foo", 1); |
|
203 |
|
204 let fID1 = yield backend.registerField(mID1, "foo", backend.FIELD_DAILY_COUNTER); |
|
205 let fID2 = yield backend.registerField(mID1, "bar", backend.FIELD_DAILY_DISCRETE_NUMERIC); |
|
206 let fID3 = yield backend.registerField(mID4, "foo", backend.FIELD_LAST_TEXT); |
|
207 |
|
208 yield backend.close(); |
|
209 |
|
210 backend = yield Metrics.Storage("field_registration_repopulation"); |
|
211 |
|
212 do_check_true(backend.hasProvider("foo")); |
|
213 do_check_true(backend.hasProvider("baz")); |
|
214 do_check_true(backend.hasMeasurement("foo", "bar", 1)); |
|
215 do_check_eq(backend.measurementID("foo", "bar", 1), mID1); |
|
216 do_check_true(backend.hasMeasurement("foo", "bar", 2)); |
|
217 do_check_eq(backend.measurementID("foo", "bar", 2), mID2); |
|
218 do_check_true(backend.hasMeasurement("foo", "biz", 1)); |
|
219 do_check_eq(backend.measurementID("foo", "biz", 1), mID3); |
|
220 do_check_true(backend.hasMeasurement("baz", "foo", 1)); |
|
221 do_check_eq(backend.measurementID("baz", "foo", 1), mID4); |
|
222 |
|
223 do_check_true(backend.hasField("foo", "bar", 1, "foo")); |
|
224 do_check_eq(backend.fieldID("foo", "bar", 1, "foo"), fID1); |
|
225 do_check_true(backend.hasField("foo", "bar", 1, "bar")); |
|
226 do_check_eq(backend.fieldID("foo", "bar", 1, "bar"), fID2); |
|
227 do_check_true(backend.hasField("baz", "foo", 1, "foo")); |
|
228 do_check_eq(backend.fieldID("baz", "foo", 1, "foo"), fID3); |
|
229 |
|
230 yield backend.close(); |
|
231 }); |
|
232 |
|
233 add_task(function test_enqueue_operation_execution_order() { |
|
234 let backend = yield Metrics.Storage("enqueue_operation_execution_order"); |
|
235 |
|
236 let executionCount = 0; |
|
237 |
|
238 let fns = { |
|
239 op1: function () { |
|
240 do_check_eq(executionCount, 1); |
|
241 }, |
|
242 |
|
243 op2: function () { |
|
244 do_check_eq(executionCount, 2); |
|
245 }, |
|
246 |
|
247 op3: function () { |
|
248 do_check_eq(executionCount, 3); |
|
249 }, |
|
250 }; |
|
251 |
|
252 function enqueuedOperation(fn) { |
|
253 let deferred = Promise.defer(); |
|
254 |
|
255 CommonUtils.nextTick(function onNextTick() { |
|
256 executionCount++; |
|
257 fn(); |
|
258 deferred.resolve(); |
|
259 }); |
|
260 |
|
261 return deferred.promise; |
|
262 } |
|
263 |
|
264 let promises = []; |
|
265 for (let i = 1; i <= 3; i++) { |
|
266 let fn = fns["op" + i]; |
|
267 promises.push(backend.enqueueOperation(enqueuedOperation.bind(this, fn))); |
|
268 } |
|
269 |
|
270 for (let promise of promises) { |
|
271 yield promise; |
|
272 } |
|
273 |
|
274 yield backend.close(); |
|
275 }); |
|
276 |
|
277 add_task(function test_enqueue_operation_many() { |
|
278 let backend = yield Metrics.Storage("enqueue_operation_many"); |
|
279 |
|
280 let promises = []; |
|
281 for (let i = 0; i < 100; i++) { |
|
282 promises.push(backend.registerMeasurement("foo", "bar" + i, 1)); |
|
283 } |
|
284 |
|
285 for (let promise of promises) { |
|
286 yield promise; |
|
287 } |
|
288 |
|
289 yield backend.close(); |
|
290 }); |
|
291 |
|
292 // If the operation did not return a promise, everything should still execute. |
|
293 add_task(function test_enqueue_operation_no_return_promise() { |
|
294 let backend = yield Metrics.Storage("enqueue_operation_no_return_promise"); |
|
295 |
|
296 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
297 let fID = yield backend.registerField(mID, "baz", backend.FIELD_DAILY_COUNTER); |
|
298 let now = new Date(); |
|
299 |
|
300 let promises = []; |
|
301 for (let i = 0; i < 10; i++) { |
|
302 promises.push(backend.enqueueOperation(function op() { |
|
303 backend.incrementDailyCounterFromFieldID(fID, now); |
|
304 })); |
|
305 } |
|
306 |
|
307 let deferred = Promise.defer(); |
|
308 |
|
309 let finished = 0; |
|
310 for (let promise of promises) { |
|
311 promise.then( |
|
312 do_throw.bind(this, "Unexpected resolve."), |
|
313 function onError() { |
|
314 finished++; |
|
315 |
|
316 if (finished == promises.length) { |
|
317 backend.getDailyCounterCountFromFieldID(fID, now).then(function onCount(count) { |
|
318 // There should not be a race condition here because storage |
|
319 // serializes all statements. So, for the getDailyCounterCount |
|
320 // query to finish means that all counter update statements must |
|
321 // have completed. |
|
322 do_check_eq(count, promises.length); |
|
323 deferred.resolve(); |
|
324 }); |
|
325 } |
|
326 } |
|
327 ); |
|
328 } |
|
329 |
|
330 yield deferred.promise; |
|
331 yield backend.close(); |
|
332 }); |
|
333 |
|
334 // If an operation throws, subsequent operations should still execute. |
|
335 add_task(function test_enqueue_operation_throw_exception() { |
|
336 let backend = yield Metrics.Storage("enqueue_operation_rejected_promise"); |
|
337 |
|
338 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
339 let fID = yield backend.registerField(mID, "baz", backend.FIELD_DAILY_COUNTER); |
|
340 let now = new Date(); |
|
341 |
|
342 let deferred = Promise.defer(); |
|
343 backend.enqueueOperation(function bad() { |
|
344 throw new Error("I failed."); |
|
345 }).then(do_throw, function onError(error) { |
|
346 do_check_true(error.message.contains("I failed.")); |
|
347 deferred.resolve(); |
|
348 }); |
|
349 |
|
350 let promise = backend.enqueueOperation(function () { |
|
351 return backend.incrementDailyCounterFromFieldID(fID, now); |
|
352 }); |
|
353 |
|
354 yield deferred.promise; |
|
355 yield promise; |
|
356 |
|
357 let count = yield backend.getDailyCounterCountFromFieldID(fID, now); |
|
358 do_check_eq(count, 1); |
|
359 yield backend.close(); |
|
360 }); |
|
361 |
|
362 // If an operation rejects, subsequent operations should still execute. |
|
363 add_task(function test_enqueue_operation_reject_promise() { |
|
364 let backend = yield Metrics.Storage("enqueue_operation_reject_promise"); |
|
365 |
|
366 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
367 let fID = yield backend.registerField(mID, "baz", backend.FIELD_DAILY_COUNTER); |
|
368 let now = new Date(); |
|
369 |
|
370 let deferred = Promise.defer(); |
|
371 backend.enqueueOperation(function reject() { |
|
372 let d = Promise.defer(); |
|
373 |
|
374 CommonUtils.nextTick(function nextTick() { |
|
375 d.reject("I failed."); |
|
376 }); |
|
377 |
|
378 return d.promise; |
|
379 }).then(do_throw, function onError(error) { |
|
380 deferred.resolve(); |
|
381 }); |
|
382 |
|
383 let promise = backend.enqueueOperation(function () { |
|
384 return backend.incrementDailyCounterFromFieldID(fID, now); |
|
385 }); |
|
386 |
|
387 yield deferred.promise; |
|
388 yield promise; |
|
389 |
|
390 let count = yield backend.getDailyCounterCountFromFieldID(fID, now); |
|
391 do_check_eq(count, 1); |
|
392 yield backend.close(); |
|
393 }); |
|
394 |
|
395 add_task(function test_enqueue_transaction() { |
|
396 let backend = yield Metrics.Storage("enqueue_transaction"); |
|
397 |
|
398 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
399 let fID = yield backend.registerField(mID, "baz", backend.FIELD_DAILY_COUNTER); |
|
400 let now = new Date(); |
|
401 |
|
402 yield backend.incrementDailyCounterFromFieldID(fID, now); |
|
403 |
|
404 yield backend.enqueueTransaction(function transaction() { |
|
405 yield backend.incrementDailyCounterFromFieldID(fID, now); |
|
406 }); |
|
407 |
|
408 let count = yield backend.getDailyCounterCountFromFieldID(fID, now); |
|
409 do_check_eq(count, 2); |
|
410 |
|
411 let errored = false; |
|
412 try { |
|
413 yield backend.enqueueTransaction(function aborted() { |
|
414 yield backend.incrementDailyCounterFromFieldID(fID, now); |
|
415 |
|
416 throw new Error("Some error."); |
|
417 }); |
|
418 } catch (ex) { |
|
419 errored = true; |
|
420 } finally { |
|
421 do_check_true(errored); |
|
422 } |
|
423 |
|
424 count = yield backend.getDailyCounterCountFromFieldID(fID, now); |
|
425 do_check_eq(count, 2); |
|
426 |
|
427 yield backend.close(); |
|
428 }); |
|
429 |
|
430 add_task(function test_increment_daily_counter_basic() { |
|
431 let backend = yield Metrics.Storage("increment_daily_counter_basic"); |
|
432 |
|
433 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
434 |
|
435 let fieldID = yield backend.registerField(mID, "baz", |
|
436 backend.FIELD_DAILY_COUNTER); |
|
437 |
|
438 let now = new Date(); |
|
439 yield backend.incrementDailyCounterFromFieldID(fieldID, now); |
|
440 |
|
441 let count = yield backend.getDailyCounterCountFromFieldID(fieldID, now); |
|
442 do_check_eq(count, 1); |
|
443 |
|
444 yield backend.incrementDailyCounterFromFieldID(fieldID, now); |
|
445 count = yield backend.getDailyCounterCountFromFieldID(fieldID, now); |
|
446 do_check_eq(count, 2); |
|
447 |
|
448 yield backend.incrementDailyCounterFromFieldID(fieldID, now, 10); |
|
449 count = yield backend.getDailyCounterCountFromFieldID(fieldID, now); |
|
450 do_check_eq(count, 12); |
|
451 |
|
452 yield backend.close(); |
|
453 }); |
|
454 |
|
455 add_task(function test_increment_daily_counter_multiple_days() { |
|
456 let backend = yield Metrics.Storage("increment_daily_counter_multiple_days"); |
|
457 |
|
458 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
459 let fieldID = yield backend.registerField(mID, "baz", |
|
460 backend.FIELD_DAILY_COUNTER); |
|
461 |
|
462 let days = []; |
|
463 let now = Date.now(); |
|
464 for (let i = 0; i < 100; i++) { |
|
465 days.push(new Date(now - i * MILLISECONDS_PER_DAY)); |
|
466 } |
|
467 |
|
468 for (let day of days) { |
|
469 yield backend.incrementDailyCounterFromFieldID(fieldID, day); |
|
470 } |
|
471 |
|
472 let result = yield backend.getDailyCounterCountsFromFieldID(fieldID); |
|
473 do_check_eq(result.size, 100); |
|
474 for (let day of days) { |
|
475 do_check_true(result.hasDay(day)); |
|
476 do_check_eq(result.getDay(day), 1); |
|
477 } |
|
478 |
|
479 let fields = yield backend.getMeasurementDailyCountersFromMeasurementID(mID); |
|
480 do_check_eq(fields.size, 1); |
|
481 do_check_true(fields.has("baz")); |
|
482 do_check_eq(fields.get("baz").size, 100); |
|
483 |
|
484 for (let day of days) { |
|
485 do_check_true(fields.get("baz").hasDay(day)); |
|
486 do_check_eq(fields.get("baz").getDay(day), 1); |
|
487 } |
|
488 |
|
489 yield backend.close(); |
|
490 }); |
|
491 |
|
492 add_task(function test_last_values() { |
|
493 let backend = yield Metrics.Storage("set_last"); |
|
494 |
|
495 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
496 let numberID = yield backend.registerField(mID, "number", |
|
497 backend.FIELD_LAST_NUMERIC); |
|
498 let textID = yield backend.registerField(mID, "text", |
|
499 backend.FIELD_LAST_TEXT); |
|
500 let now = new Date(); |
|
501 let nowDay = new Date(Math.floor(now.getTime() / MILLISECONDS_PER_DAY) * MILLISECONDS_PER_DAY); |
|
502 |
|
503 yield backend.setLastNumericFromFieldID(numberID, 42, now); |
|
504 yield backend.setLastTextFromFieldID(textID, "hello world", now); |
|
505 |
|
506 let result = yield backend.getLastNumericFromFieldID(numberID); |
|
507 do_check_true(Array.isArray(result)); |
|
508 do_check_eq(result[0].getTime(), nowDay.getTime()); |
|
509 do_check_eq(typeof(result[1]), "number"); |
|
510 do_check_eq(result[1], 42); |
|
511 |
|
512 result = yield backend.getLastTextFromFieldID(textID); |
|
513 do_check_true(Array.isArray(result)); |
|
514 do_check_eq(result[0].getTime(), nowDay.getTime()); |
|
515 do_check_eq(typeof(result[1]), "string"); |
|
516 do_check_eq(result[1], "hello world"); |
|
517 |
|
518 let missingID = yield backend.registerField(mID, "missing", |
|
519 backend.FIELD_LAST_NUMERIC); |
|
520 do_check_null(yield backend.getLastNumericFromFieldID(missingID)); |
|
521 |
|
522 let fields = yield backend.getMeasurementLastValuesFromMeasurementID(mID); |
|
523 do_check_eq(fields.size, 2); |
|
524 do_check_true(fields.has("number")); |
|
525 do_check_true(fields.has("text")); |
|
526 do_check_eq(fields.get("number")[1], 42); |
|
527 do_check_eq(fields.get("text")[1], "hello world"); |
|
528 |
|
529 yield backend.close(); |
|
530 }); |
|
531 |
|
532 add_task(function test_discrete_values_basic() { |
|
533 let backend = yield Metrics.Storage("discrete_values_basic"); |
|
534 |
|
535 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
536 let numericID = yield backend.registerField(mID, "numeric", |
|
537 backend.FIELD_DAILY_DISCRETE_NUMERIC); |
|
538 let textID = yield backend.registerField(mID, "text", |
|
539 backend.FIELD_DAILY_DISCRETE_TEXT); |
|
540 |
|
541 let now = new Date(); |
|
542 let expectedNumeric = []; |
|
543 let expectedText = []; |
|
544 for (let i = 0; i < 100; i++) { |
|
545 expectedNumeric.push(i); |
|
546 expectedText.push("value" + i); |
|
547 yield backend.addDailyDiscreteNumericFromFieldID(numericID, i, now); |
|
548 yield backend.addDailyDiscreteTextFromFieldID(textID, "value" + i, now); |
|
549 } |
|
550 |
|
551 let values = yield backend.getDailyDiscreteNumericFromFieldID(numericID); |
|
552 do_check_eq(values.size, 1); |
|
553 do_check_true(values.hasDay(now)); |
|
554 do_check_true(Array.isArray(values.getDay(now))); |
|
555 do_check_eq(values.getDay(now).length, expectedNumeric.length); |
|
556 |
|
557 for (let i = 0; i < expectedNumeric.length; i++) { |
|
558 do_check_eq(values.getDay(now)[i], expectedNumeric[i]); |
|
559 } |
|
560 |
|
561 values = yield backend.getDailyDiscreteTextFromFieldID(textID); |
|
562 do_check_eq(values.size, 1); |
|
563 do_check_true(values.hasDay(now)); |
|
564 do_check_true(Array.isArray(values.getDay(now))); |
|
565 do_check_eq(values.getDay(now).length, expectedText.length); |
|
566 |
|
567 for (let i = 0; i < expectedText.length; i++) { |
|
568 do_check_eq(values.getDay(now)[i], expectedText[i]); |
|
569 } |
|
570 |
|
571 let fields = yield backend.getMeasurementDailyDiscreteValuesFromMeasurementID(mID); |
|
572 do_check_eq(fields.size, 2); |
|
573 do_check_true(fields.has("numeric")); |
|
574 do_check_true(fields.has("text")); |
|
575 |
|
576 let numeric = fields.get("numeric"); |
|
577 let text = fields.get("text"); |
|
578 do_check_true(numeric.hasDay(now)); |
|
579 do_check_true(text.hasDay(now)); |
|
580 do_check_eq(numeric.getDay(now).length, expectedNumeric.length); |
|
581 do_check_eq(text.getDay(now).length, expectedText.length); |
|
582 |
|
583 for (let i = 0; i < expectedNumeric.length; i++) { |
|
584 do_check_eq(numeric.getDay(now)[i], expectedNumeric[i]); |
|
585 } |
|
586 |
|
587 for (let i = 0; i < expectedText.length; i++) { |
|
588 do_check_eq(text.getDay(now)[i], expectedText[i]); |
|
589 } |
|
590 |
|
591 yield backend.close(); |
|
592 }); |
|
593 |
|
594 add_task(function test_discrete_values_multiple_days() { |
|
595 let backend = yield Metrics.Storage("discrete_values_multiple_days"); |
|
596 |
|
597 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
598 let id = yield backend.registerField(mID, "baz", |
|
599 backend.FIELD_DAILY_DISCRETE_NUMERIC); |
|
600 |
|
601 let now = new Date(); |
|
602 let dates = []; |
|
603 for (let i = 0; i < 50; i++) { |
|
604 let date = new Date(now.getTime() + i * MILLISECONDS_PER_DAY); |
|
605 dates.push(date); |
|
606 |
|
607 yield backend.addDailyDiscreteNumericFromFieldID(id, i, date); |
|
608 } |
|
609 |
|
610 let values = yield backend.getDailyDiscreteNumericFromFieldID(id); |
|
611 do_check_eq(values.size, 50); |
|
612 |
|
613 let i = 0; |
|
614 for (let date of dates) { |
|
615 do_check_true(values.hasDay(date)); |
|
616 do_check_eq(values.getDay(date)[0], i); |
|
617 i++; |
|
618 } |
|
619 |
|
620 let fields = yield backend.getMeasurementDailyDiscreteValuesFromMeasurementID(mID); |
|
621 do_check_eq(fields.size, 1); |
|
622 do_check_true(fields.has("baz")); |
|
623 let baz = fields.get("baz"); |
|
624 do_check_eq(baz.size, 50); |
|
625 i = 0; |
|
626 for (let date of dates) { |
|
627 do_check_true(baz.hasDay(date)); |
|
628 do_check_eq(baz.getDay(date).length, 1); |
|
629 do_check_eq(baz.getDay(date)[0], i); |
|
630 i++; |
|
631 } |
|
632 |
|
633 yield backend.close(); |
|
634 }); |
|
635 |
|
636 add_task(function test_daily_last_values() { |
|
637 let backend = yield Metrics.Storage("daily_last_values"); |
|
638 |
|
639 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
640 let numericID = yield backend.registerField(mID, "numeric", |
|
641 backend.FIELD_DAILY_LAST_NUMERIC); |
|
642 let textID = yield backend.registerField(mID, "text", |
|
643 backend.FIELD_DAILY_LAST_TEXT); |
|
644 |
|
645 let now = new Date(); |
|
646 let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); |
|
647 let dayBefore = new Date(yesterday.getTime() - MILLISECONDS_PER_DAY); |
|
648 |
|
649 yield backend.setDailyLastNumericFromFieldID(numericID, 1, yesterday); |
|
650 yield backend.setDailyLastNumericFromFieldID(numericID, 2, now); |
|
651 yield backend.setDailyLastNumericFromFieldID(numericID, 3, dayBefore); |
|
652 yield backend.setDailyLastTextFromFieldID(textID, "foo", now); |
|
653 yield backend.setDailyLastTextFromFieldID(textID, "bar", yesterday); |
|
654 yield backend.setDailyLastTextFromFieldID(textID, "baz", dayBefore); |
|
655 |
|
656 let days = yield backend.getDailyLastNumericFromFieldID(numericID); |
|
657 do_check_eq(days.size, 3); |
|
658 do_check_eq(days.getDay(yesterday), 1); |
|
659 do_check_eq(days.getDay(now), 2); |
|
660 do_check_eq(days.getDay(dayBefore), 3); |
|
661 |
|
662 days = yield backend.getDailyLastTextFromFieldID(textID); |
|
663 do_check_eq(days.size, 3); |
|
664 do_check_eq(days.getDay(now), "foo"); |
|
665 do_check_eq(days.getDay(yesterday), "bar"); |
|
666 do_check_eq(days.getDay(dayBefore), "baz"); |
|
667 |
|
668 yield backend.setDailyLastNumericFromFieldID(numericID, 4, yesterday); |
|
669 days = yield backend.getDailyLastNumericFromFieldID(numericID); |
|
670 do_check_eq(days.getDay(yesterday), 4); |
|
671 |
|
672 yield backend.setDailyLastTextFromFieldID(textID, "biz", yesterday); |
|
673 days = yield backend.getDailyLastTextFromFieldID(textID); |
|
674 do_check_eq(days.getDay(yesterday), "biz"); |
|
675 |
|
676 days = yield backend.getDailyLastNumericFromFieldID(numericID, yesterday); |
|
677 do_check_eq(days.size, 1); |
|
678 do_check_eq(days.getDay(yesterday), 4); |
|
679 |
|
680 days = yield backend.getDailyLastTextFromFieldID(textID, yesterday); |
|
681 do_check_eq(days.size, 1); |
|
682 do_check_eq(days.getDay(yesterday), "biz"); |
|
683 |
|
684 let fields = yield backend.getMeasurementDailyLastValuesFromMeasurementID(mID); |
|
685 do_check_eq(fields.size, 2); |
|
686 do_check_true(fields.has("numeric")); |
|
687 do_check_true(fields.has("text")); |
|
688 let numeric = fields.get("numeric"); |
|
689 let text = fields.get("text"); |
|
690 do_check_true(numeric.hasDay(yesterday)); |
|
691 do_check_true(numeric.hasDay(dayBefore)); |
|
692 do_check_true(numeric.hasDay(now)); |
|
693 do_check_true(text.hasDay(yesterday)); |
|
694 do_check_true(text.hasDay(dayBefore)); |
|
695 do_check_true(text.hasDay(now)); |
|
696 do_check_eq(numeric.getDay(yesterday), 4); |
|
697 do_check_eq(text.getDay(yesterday), "biz"); |
|
698 |
|
699 yield backend.close(); |
|
700 }); |
|
701 |
|
702 add_task(function test_prune_data_before() { |
|
703 let backend = yield Metrics.Storage("prune_data_before"); |
|
704 |
|
705 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
706 |
|
707 let counterID = yield backend.registerField(mID, "baz", |
|
708 backend.FIELD_DAILY_COUNTER); |
|
709 let text1ID = yield backend.registerField(mID, "one_text_1", |
|
710 backend.FIELD_LAST_TEXT); |
|
711 let text2ID = yield backend.registerField(mID, "one_text_2", |
|
712 backend.FIELD_LAST_TEXT); |
|
713 let numeric1ID = yield backend.registerField(mID, "one_numeric_1", |
|
714 backend.FIELD_LAST_NUMERIC); |
|
715 let numeric2ID = yield backend.registerField(mID, "one_numeric_2", |
|
716 backend.FIELD_LAST_NUMERIC); |
|
717 let text3ID = yield backend.registerField(mID, "daily_last_text_1", |
|
718 backend.FIELD_DAILY_LAST_TEXT); |
|
719 let text4ID = yield backend.registerField(mID, "daily_last_text_2", |
|
720 backend.FIELD_DAILY_LAST_TEXT); |
|
721 let numeric3ID = yield backend.registerField(mID, "daily_last_numeric_1", |
|
722 backend.FIELD_DAILY_LAST_NUMERIC); |
|
723 let numeric4ID = yield backend.registerField(mID, "daily_last_numeric_2", |
|
724 backend.FIELD_DAILY_LAST_NUMERIC); |
|
725 |
|
726 let now = new Date(); |
|
727 let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); |
|
728 let dayBefore = new Date(yesterday.getTime() - MILLISECONDS_PER_DAY); |
|
729 |
|
730 yield backend.incrementDailyCounterFromFieldID(counterID, now); |
|
731 yield backend.incrementDailyCounterFromFieldID(counterID, yesterday); |
|
732 yield backend.incrementDailyCounterFromFieldID(counterID, dayBefore); |
|
733 yield backend.setLastTextFromFieldID(text1ID, "hello", dayBefore); |
|
734 yield backend.setLastTextFromFieldID(text2ID, "world", yesterday); |
|
735 yield backend.setLastNumericFromFieldID(numeric1ID, 42, dayBefore); |
|
736 yield backend.setLastNumericFromFieldID(numeric2ID, 43, yesterday); |
|
737 yield backend.setDailyLastTextFromFieldID(text3ID, "foo", dayBefore); |
|
738 yield backend.setDailyLastTextFromFieldID(text3ID, "bar", yesterday); |
|
739 yield backend.setDailyLastTextFromFieldID(text4ID, "hello", dayBefore); |
|
740 yield backend.setDailyLastTextFromFieldID(text4ID, "world", yesterday); |
|
741 yield backend.setDailyLastNumericFromFieldID(numeric3ID, 40, dayBefore); |
|
742 yield backend.setDailyLastNumericFromFieldID(numeric3ID, 41, yesterday); |
|
743 yield backend.setDailyLastNumericFromFieldID(numeric4ID, 42, dayBefore); |
|
744 yield backend.setDailyLastNumericFromFieldID(numeric4ID, 43, yesterday); |
|
745 |
|
746 let days = yield backend.getDailyCounterCountsFromFieldID(counterID); |
|
747 do_check_eq(days.size, 3); |
|
748 |
|
749 yield backend.pruneDataBefore(yesterday); |
|
750 days = yield backend.getDailyCounterCountsFromFieldID(counterID); |
|
751 do_check_eq(days.size, 2); |
|
752 do_check_false(days.hasDay(dayBefore)); |
|
753 |
|
754 do_check_null(yield backend.getLastTextFromFieldID(text1ID)); |
|
755 do_check_null(yield backend.getLastNumericFromFieldID(numeric1ID)); |
|
756 |
|
757 let result = yield backend.getLastTextFromFieldID(text2ID); |
|
758 do_check_true(Array.isArray(result)); |
|
759 do_check_eq(result[1], "world"); |
|
760 |
|
761 result = yield backend.getLastNumericFromFieldID(numeric2ID); |
|
762 do_check_true(Array.isArray(result)); |
|
763 do_check_eq(result[1], 43); |
|
764 |
|
765 result = yield backend.getDailyLastNumericFromFieldID(numeric3ID); |
|
766 do_check_eq(result.size, 1); |
|
767 do_check_true(result.hasDay(yesterday)); |
|
768 |
|
769 result = yield backend.getDailyLastTextFromFieldID(text3ID); |
|
770 do_check_eq(result.size, 1); |
|
771 do_check_true(result.hasDay(yesterday)); |
|
772 |
|
773 yield backend.close(); |
|
774 }); |
|
775 |
|
776 add_task(function test_provider_state() { |
|
777 let backend = yield Metrics.Storage("provider_state"); |
|
778 |
|
779 yield backend.registerMeasurement("foo", "bar", 1); |
|
780 yield backend.setProviderState("foo", "apple", "orange"); |
|
781 let value = yield backend.getProviderState("foo", "apple"); |
|
782 do_check_eq(value, "orange"); |
|
783 |
|
784 yield backend.setProviderState("foo", "apple", "pear"); |
|
785 value = yield backend.getProviderState("foo", "apple"); |
|
786 do_check_eq(value, "pear"); |
|
787 |
|
788 yield backend.close(); |
|
789 }); |
|
790 |
|
791 add_task(function test_get_measurement_values() { |
|
792 let backend = yield Metrics.Storage("get_measurement_values"); |
|
793 |
|
794 let mID = yield backend.registerMeasurement("foo", "bar", 1); |
|
795 let id1 = yield backend.registerField(mID, "id1", backend.FIELD_DAILY_COUNTER); |
|
796 let id2 = yield backend.registerField(mID, "id2", backend.FIELD_DAILY_DISCRETE_NUMERIC); |
|
797 let id3 = yield backend.registerField(mID, "id3", backend.FIELD_DAILY_DISCRETE_TEXT); |
|
798 let id4 = yield backend.registerField(mID, "id4", backend.FIELD_DAILY_LAST_NUMERIC); |
|
799 let id5 = yield backend.registerField(mID, "id5", backend.FIELD_DAILY_LAST_TEXT); |
|
800 let id6 = yield backend.registerField(mID, "id6", backend.FIELD_LAST_NUMERIC); |
|
801 let id7 = yield backend.registerField(mID, "id7", backend.FIELD_LAST_TEXT); |
|
802 |
|
803 let now = new Date(); |
|
804 let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); |
|
805 |
|
806 yield backend.incrementDailyCounterFromFieldID(id1, now); |
|
807 yield backend.addDailyDiscreteNumericFromFieldID(id2, 3, now); |
|
808 yield backend.addDailyDiscreteNumericFromFieldID(id2, 4, now); |
|
809 yield backend.addDailyDiscreteNumericFromFieldID(id2, 5, yesterday); |
|
810 yield backend.addDailyDiscreteNumericFromFieldID(id2, 6, yesterday); |
|
811 yield backend.addDailyDiscreteTextFromFieldID(id3, "1", now); |
|
812 yield backend.addDailyDiscreteTextFromFieldID(id3, "2", now); |
|
813 yield backend.addDailyDiscreteTextFromFieldID(id3, "3", yesterday); |
|
814 yield backend.addDailyDiscreteTextFromFieldID(id3, "4", yesterday); |
|
815 yield backend.setDailyLastNumericFromFieldID(id4, 1, now); |
|
816 yield backend.setDailyLastNumericFromFieldID(id4, 2, yesterday); |
|
817 yield backend.setDailyLastTextFromFieldID(id5, "foo", now); |
|
818 yield backend.setDailyLastTextFromFieldID(id5, "bar", yesterday); |
|
819 yield backend.setLastNumericFromFieldID(id6, 42, now); |
|
820 yield backend.setLastTextFromFieldID(id7, "foo", now); |
|
821 |
|
822 let fields = yield backend.getMeasurementValues(mID); |
|
823 do_check_eq(Object.keys(fields).length, 2); |
|
824 do_check_true("days" in fields); |
|
825 do_check_true("singular" in fields); |
|
826 do_check_eq(fields.days.size, 2); |
|
827 do_check_true(fields.days.hasDay(now)); |
|
828 do_check_true(fields.days.hasDay(yesterday)); |
|
829 do_check_eq(fields.days.getDay(now).size, 5); |
|
830 do_check_eq(fields.days.getDay(yesterday).size, 4); |
|
831 do_check_eq(fields.days.getDay(now).get("id3")[0], 1); |
|
832 do_check_eq(fields.days.getDay(yesterday).get("id4"), 2); |
|
833 do_check_eq(fields.singular.size, 2); |
|
834 do_check_eq(fields.singular.get("id6")[1], 42); |
|
835 do_check_eq(fields.singular.get("id7")[1], "foo"); |
|
836 |
|
837 yield backend.close(); |
|
838 }); |
|
839 |