services/metrics/tests/xpcshell/test_metrics_storage.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

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 });

mercurial