Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/publicdomain/zero/1.0/ */
4 "use strict";
6 const {utils: Cu} = Components;
8 Cu.import("resource://gre/modules/Promise.jsm");
9 Cu.import("resource://gre/modules/Metrics.jsm");
10 Cu.import("resource://services-common/utils.js");
13 const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
16 function run_test() {
17 run_next_test();
18 }
20 add_test(function test_days_date_conversion() {
21 let toDays = Metrics.dateToDays;
22 let toDate = Metrics.daysToDate;
24 let d = new Date(0);
25 do_check_eq(toDays(d), 0);
27 d = new Date(MILLISECONDS_PER_DAY);
28 do_check_eq(toDays(d), 1);
30 d = new Date(MILLISECONDS_PER_DAY - 1);
31 do_check_eq(toDays(d), 0);
33 d = new Date("1970-12-31T23:59:59.999Z");
34 do_check_eq(toDays(d), 364);
36 d = new Date("1971-01-01T00:00:00Z");
37 do_check_eq(toDays(d), 365);
39 d = toDate(0);
40 do_check_eq(d.getTime(), 0);
42 d = toDate(1);
43 do_check_eq(d.getTime(), MILLISECONDS_PER_DAY);
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);
54 run_next_test();
55 });
57 add_task(function test_get_sqlite_backend() {
58 let backend = yield Metrics.Storage("get_sqlite_backend.sqlite");
60 do_check_neq(backend._connection, null);
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);
69 yield backend.close();
70 do_check_null(backend._connection);
71 });
73 add_task(function test_reconnect() {
74 let backend = yield Metrics.Storage("reconnect");
75 yield backend.close();
77 let backend2 = yield Metrics.Storage("reconnect");
78 yield backend2.close();
79 });
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();
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 }
95 do_check_null(backend2);
96 do_check_true(failed);
97 });
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;
104 yield backend.setAutoCheckpoint(0);
105 do_check_eq(c._statementCounter, count + 1);
107 let rows = yield c.execute("PRAGMA wal_autocheckpoint");
108 do_check_eq(rows[0].getResultByIndex(0), 0);
109 count = c._statementCounter;
111 yield backend.setAutoCheckpoint(1);
112 do_check_eq(c._statementCounter, count + 1);
114 rows = yield c.execute("PRAGMA wal_autocheckpoint");
115 do_check_eq(rows[0].getResultByIndex(0), backend._enabledWALCheckpointPages);
116 count = c._statementCounter;
118 yield backend.checkpoint();
119 do_check_eq(c._statementCounter, count + 1);
121 yield backend.checkpoint();
122 do_check_eq(c._statementCounter, count + 2);
124 yield backend.close();
125 });
127 add_task(function test_measurement_registration() {
128 let backend = yield Metrics.Storage("measurement_registration");
130 do_check_false(backend.hasProvider("foo"));
131 do_check_false(backend.hasMeasurement("foo", "bar", 1));
133 let id = yield backend.registerMeasurement("foo", "bar", 1);
134 do_check_eq(id, 1);
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));
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);
146 yield backend.close();
147 });
149 add_task(function test_field_registration_basic() {
150 let backend = yield Metrics.Storage("field_registration_basic");
152 do_check_false(backend.hasField("foo", "bar", 1, "baz"));
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"));
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"));
163 let bar2ID = yield backend.registerMeasurement("foo", "bar2", 1);
165 yield backend.registerField(bar2ID, "baz",
166 backend.FIELD_DAILY_DISCRETE_NUMERIC);
168 do_check_true(backend.hasField("foo", "bar2", 1, "baz"));
170 yield backend.close();
171 });
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");
177 let mID = yield backend.registerMeasurement("bar", "bar", 1);
179 let id = yield backend.registerField(mID, "baz",
180 backend.FIELD_DAILY_COUNTER);
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 }
191 do_check_true(caught);
193 yield backend.close();
194 });
196 add_task(function test_field_registration_repopulation() {
197 let backend = yield Metrics.Storage("field_registration_repopulation");
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);
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);
208 yield backend.close();
210 backend = yield Metrics.Storage("field_registration_repopulation");
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);
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);
230 yield backend.close();
231 });
233 add_task(function test_enqueue_operation_execution_order() {
234 let backend = yield Metrics.Storage("enqueue_operation_execution_order");
236 let executionCount = 0;
238 let fns = {
239 op1: function () {
240 do_check_eq(executionCount, 1);
241 },
243 op2: function () {
244 do_check_eq(executionCount, 2);
245 },
247 op3: function () {
248 do_check_eq(executionCount, 3);
249 },
250 };
252 function enqueuedOperation(fn) {
253 let deferred = Promise.defer();
255 CommonUtils.nextTick(function onNextTick() {
256 executionCount++;
257 fn();
258 deferred.resolve();
259 });
261 return deferred.promise;
262 }
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 }
270 for (let promise of promises) {
271 yield promise;
272 }
274 yield backend.close();
275 });
277 add_task(function test_enqueue_operation_many() {
278 let backend = yield Metrics.Storage("enqueue_operation_many");
280 let promises = [];
281 for (let i = 0; i < 100; i++) {
282 promises.push(backend.registerMeasurement("foo", "bar" + i, 1));
283 }
285 for (let promise of promises) {
286 yield promise;
287 }
289 yield backend.close();
290 });
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");
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();
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 }
307 let deferred = Promise.defer();
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++;
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 }
330 yield deferred.promise;
331 yield backend.close();
332 });
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");
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();
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 });
350 let promise = backend.enqueueOperation(function () {
351 return backend.incrementDailyCounterFromFieldID(fID, now);
352 });
354 yield deferred.promise;
355 yield promise;
357 let count = yield backend.getDailyCounterCountFromFieldID(fID, now);
358 do_check_eq(count, 1);
359 yield backend.close();
360 });
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");
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();
370 let deferred = Promise.defer();
371 backend.enqueueOperation(function reject() {
372 let d = Promise.defer();
374 CommonUtils.nextTick(function nextTick() {
375 d.reject("I failed.");
376 });
378 return d.promise;
379 }).then(do_throw, function onError(error) {
380 deferred.resolve();
381 });
383 let promise = backend.enqueueOperation(function () {
384 return backend.incrementDailyCounterFromFieldID(fID, now);
385 });
387 yield deferred.promise;
388 yield promise;
390 let count = yield backend.getDailyCounterCountFromFieldID(fID, now);
391 do_check_eq(count, 1);
392 yield backend.close();
393 });
395 add_task(function test_enqueue_transaction() {
396 let backend = yield Metrics.Storage("enqueue_transaction");
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();
402 yield backend.incrementDailyCounterFromFieldID(fID, now);
404 yield backend.enqueueTransaction(function transaction() {
405 yield backend.incrementDailyCounterFromFieldID(fID, now);
406 });
408 let count = yield backend.getDailyCounterCountFromFieldID(fID, now);
409 do_check_eq(count, 2);
411 let errored = false;
412 try {
413 yield backend.enqueueTransaction(function aborted() {
414 yield backend.incrementDailyCounterFromFieldID(fID, now);
416 throw new Error("Some error.");
417 });
418 } catch (ex) {
419 errored = true;
420 } finally {
421 do_check_true(errored);
422 }
424 count = yield backend.getDailyCounterCountFromFieldID(fID, now);
425 do_check_eq(count, 2);
427 yield backend.close();
428 });
430 add_task(function test_increment_daily_counter_basic() {
431 let backend = yield Metrics.Storage("increment_daily_counter_basic");
433 let mID = yield backend.registerMeasurement("foo", "bar", 1);
435 let fieldID = yield backend.registerField(mID, "baz",
436 backend.FIELD_DAILY_COUNTER);
438 let now = new Date();
439 yield backend.incrementDailyCounterFromFieldID(fieldID, now);
441 let count = yield backend.getDailyCounterCountFromFieldID(fieldID, now);
442 do_check_eq(count, 1);
444 yield backend.incrementDailyCounterFromFieldID(fieldID, now);
445 count = yield backend.getDailyCounterCountFromFieldID(fieldID, now);
446 do_check_eq(count, 2);
448 yield backend.incrementDailyCounterFromFieldID(fieldID, now, 10);
449 count = yield backend.getDailyCounterCountFromFieldID(fieldID, now);
450 do_check_eq(count, 12);
452 yield backend.close();
453 });
455 add_task(function test_increment_daily_counter_multiple_days() {
456 let backend = yield Metrics.Storage("increment_daily_counter_multiple_days");
458 let mID = yield backend.registerMeasurement("foo", "bar", 1);
459 let fieldID = yield backend.registerField(mID, "baz",
460 backend.FIELD_DAILY_COUNTER);
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 }
468 for (let day of days) {
469 yield backend.incrementDailyCounterFromFieldID(fieldID, day);
470 }
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 }
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);
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 }
489 yield backend.close();
490 });
492 add_task(function test_last_values() {
493 let backend = yield Metrics.Storage("set_last");
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);
503 yield backend.setLastNumericFromFieldID(numberID, 42, now);
504 yield backend.setLastTextFromFieldID(textID, "hello world", now);
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);
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");
518 let missingID = yield backend.registerField(mID, "missing",
519 backend.FIELD_LAST_NUMERIC);
520 do_check_null(yield backend.getLastNumericFromFieldID(missingID));
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");
529 yield backend.close();
530 });
532 add_task(function test_discrete_values_basic() {
533 let backend = yield Metrics.Storage("discrete_values_basic");
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);
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 }
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);
557 for (let i = 0; i < expectedNumeric.length; i++) {
558 do_check_eq(values.getDay(now)[i], expectedNumeric[i]);
559 }
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);
567 for (let i = 0; i < expectedText.length; i++) {
568 do_check_eq(values.getDay(now)[i], expectedText[i]);
569 }
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"));
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);
583 for (let i = 0; i < expectedNumeric.length; i++) {
584 do_check_eq(numeric.getDay(now)[i], expectedNumeric[i]);
585 }
587 for (let i = 0; i < expectedText.length; i++) {
588 do_check_eq(text.getDay(now)[i], expectedText[i]);
589 }
591 yield backend.close();
592 });
594 add_task(function test_discrete_values_multiple_days() {
595 let backend = yield Metrics.Storage("discrete_values_multiple_days");
597 let mID = yield backend.registerMeasurement("foo", "bar", 1);
598 let id = yield backend.registerField(mID, "baz",
599 backend.FIELD_DAILY_DISCRETE_NUMERIC);
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);
607 yield backend.addDailyDiscreteNumericFromFieldID(id, i, date);
608 }
610 let values = yield backend.getDailyDiscreteNumericFromFieldID(id);
611 do_check_eq(values.size, 50);
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 }
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 }
633 yield backend.close();
634 });
636 add_task(function test_daily_last_values() {
637 let backend = yield Metrics.Storage("daily_last_values");
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);
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);
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);
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);
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");
668 yield backend.setDailyLastNumericFromFieldID(numericID, 4, yesterday);
669 days = yield backend.getDailyLastNumericFromFieldID(numericID);
670 do_check_eq(days.getDay(yesterday), 4);
672 yield backend.setDailyLastTextFromFieldID(textID, "biz", yesterday);
673 days = yield backend.getDailyLastTextFromFieldID(textID);
674 do_check_eq(days.getDay(yesterday), "biz");
676 days = yield backend.getDailyLastNumericFromFieldID(numericID, yesterday);
677 do_check_eq(days.size, 1);
678 do_check_eq(days.getDay(yesterday), 4);
680 days = yield backend.getDailyLastTextFromFieldID(textID, yesterday);
681 do_check_eq(days.size, 1);
682 do_check_eq(days.getDay(yesterday), "biz");
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");
699 yield backend.close();
700 });
702 add_task(function test_prune_data_before() {
703 let backend = yield Metrics.Storage("prune_data_before");
705 let mID = yield backend.registerMeasurement("foo", "bar", 1);
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);
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);
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);
746 let days = yield backend.getDailyCounterCountsFromFieldID(counterID);
747 do_check_eq(days.size, 3);
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));
754 do_check_null(yield backend.getLastTextFromFieldID(text1ID));
755 do_check_null(yield backend.getLastNumericFromFieldID(numeric1ID));
757 let result = yield backend.getLastTextFromFieldID(text2ID);
758 do_check_true(Array.isArray(result));
759 do_check_eq(result[1], "world");
761 result = yield backend.getLastNumericFromFieldID(numeric2ID);
762 do_check_true(Array.isArray(result));
763 do_check_eq(result[1], 43);
765 result = yield backend.getDailyLastNumericFromFieldID(numeric3ID);
766 do_check_eq(result.size, 1);
767 do_check_true(result.hasDay(yesterday));
769 result = yield backend.getDailyLastTextFromFieldID(text3ID);
770 do_check_eq(result.size, 1);
771 do_check_true(result.hasDay(yesterday));
773 yield backend.close();
774 });
776 add_task(function test_provider_state() {
777 let backend = yield Metrics.Storage("provider_state");
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");
784 yield backend.setProviderState("foo", "apple", "pear");
785 value = yield backend.getProviderState("foo", "apple");
786 do_check_eq(value, "pear");
788 yield backend.close();
789 });
791 add_task(function test_get_measurement_values() {
792 let backend = yield Metrics.Storage("get_measurement_values");
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);
803 let now = new Date();
804 let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY);
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);
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");
837 yield backend.close();
838 });