michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: const {utils: Cu} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/Metrics.jsm"); michael@0: Cu.import("resource://gre/modules/Preferences.jsm"); michael@0: Cu.import("resource://gre/modules/Task.jsm"); michael@0: Cu.import("resource://testing-common/services/metrics/mocks.jsm"); michael@0: michael@0: michael@0: const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; michael@0: michael@0: michael@0: function getProvider(storageName) { michael@0: return Task.spawn(function () { michael@0: let provider = new DummyProvider(); michael@0: let storage = yield Metrics.Storage(storageName); michael@0: michael@0: yield provider.init(storage); michael@0: michael@0: throw new Task.Result(provider); michael@0: }); michael@0: } michael@0: michael@0: michael@0: function run_test() { michael@0: run_next_test(); michael@0: }; michael@0: michael@0: add_test(function test_constructor() { michael@0: let failed = false; michael@0: try { michael@0: new Metrics.Provider(); michael@0: } catch(ex) { michael@0: do_check_true(ex.message.startsWith("Provider must define a name")); michael@0: failed = true; michael@0: } michael@0: finally { michael@0: do_check_true(failed); michael@0: } michael@0: michael@0: run_next_test(); michael@0: }); michael@0: michael@0: add_task(function test_init() { michael@0: let provider = new DummyProvider(); michael@0: let storage = yield Metrics.Storage("init"); michael@0: michael@0: yield provider.init(storage); michael@0: michael@0: let m = provider.getMeasurement("DummyMeasurement", 1); michael@0: do_check_true(m instanceof Metrics.Measurement); michael@0: do_check_eq(m.id, 1); michael@0: do_check_eq(Object.keys(m._fields).length, 7); michael@0: do_check_true(m.hasField("daily-counter")); michael@0: do_check_false(m.hasField("does-not-exist")); michael@0: michael@0: yield storage.close(); michael@0: }); michael@0: michael@0: add_task(function test_default_collectors() { michael@0: let provider = new DummyProvider(); michael@0: let storage = yield Metrics.Storage("default_collectors"); michael@0: yield provider.init(storage); michael@0: michael@0: for (let property in Metrics.Provider.prototype) { michael@0: if (!property.startsWith("collect")) { michael@0: continue; michael@0: } michael@0: michael@0: let result = provider[property](); michael@0: do_check_neq(result, null); michael@0: do_check_eq(typeof(result.then), "function"); michael@0: } michael@0: michael@0: yield storage.close(); michael@0: }); michael@0: michael@0: add_task(function test_measurement_storage_basic() { michael@0: let provider = yield getProvider("measurement_storage_basic"); michael@0: let m = provider.getMeasurement("DummyMeasurement", 1); michael@0: michael@0: let now = new Date(); michael@0: let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); michael@0: michael@0: // Daily counter. michael@0: let counterID = m.fieldID("daily-counter"); michael@0: yield m.incrementDailyCounter("daily-counter", now); michael@0: yield m.incrementDailyCounter("daily-counter", now); michael@0: yield m.incrementDailyCounter("daily-counter", yesterday); michael@0: let count = yield provider.storage.getDailyCounterCountFromFieldID(counterID, now); michael@0: do_check_eq(count, 2); michael@0: michael@0: count = yield provider.storage.getDailyCounterCountFromFieldID(counterID, yesterday); michael@0: do_check_eq(count, 1); michael@0: michael@0: yield m.incrementDailyCounter("daily-counter", now, 4); michael@0: count = yield provider.storage.getDailyCounterCountFromFieldID(counterID, now); michael@0: do_check_eq(count, 6); michael@0: michael@0: // Daily discrete numeric. michael@0: let dailyDiscreteNumericID = m.fieldID("daily-discrete-numeric"); michael@0: yield m.addDailyDiscreteNumeric("daily-discrete-numeric", 5, now); michael@0: yield m.addDailyDiscreteNumeric("daily-discrete-numeric", 6, now); michael@0: yield m.addDailyDiscreteNumeric("daily-discrete-numeric", 7, yesterday); michael@0: michael@0: let values = yield provider.storage.getDailyDiscreteNumericFromFieldID( michael@0: dailyDiscreteNumericID, now); michael@0: michael@0: do_check_eq(values.size, 1); michael@0: do_check_true(values.hasDay(now)); michael@0: let actual = values.getDay(now); michael@0: do_check_eq(actual.length, 2); michael@0: do_check_eq(actual[0], 5); michael@0: do_check_eq(actual[1], 6); michael@0: michael@0: values = yield provider.storage.getDailyDiscreteNumericFromFieldID( michael@0: dailyDiscreteNumericID, yesterday); michael@0: michael@0: do_check_eq(values.size, 1); michael@0: do_check_true(values.hasDay(yesterday)); michael@0: do_check_eq(values.getDay(yesterday)[0], 7); michael@0: michael@0: // Daily discrete text. michael@0: let dailyDiscreteTextID = m.fieldID("daily-discrete-text"); michael@0: yield m.addDailyDiscreteText("daily-discrete-text", "foo", now); michael@0: yield m.addDailyDiscreteText("daily-discrete-text", "bar", now); michael@0: yield m.addDailyDiscreteText("daily-discrete-text", "biz", yesterday); michael@0: michael@0: values = yield provider.storage.getDailyDiscreteTextFromFieldID( michael@0: dailyDiscreteTextID, now); michael@0: michael@0: do_check_eq(values.size, 1); michael@0: do_check_true(values.hasDay(now)); michael@0: actual = values.getDay(now); michael@0: do_check_eq(actual.length, 2); michael@0: do_check_eq(actual[0], "foo"); michael@0: do_check_eq(actual[1], "bar"); michael@0: michael@0: values = yield provider.storage.getDailyDiscreteTextFromFieldID( michael@0: dailyDiscreteTextID, yesterday); michael@0: do_check_true(values.hasDay(yesterday)); michael@0: do_check_eq(values.getDay(yesterday)[0], "biz"); michael@0: michael@0: // Daily last numeric. michael@0: let lastDailyNumericID = m.fieldID("daily-last-numeric"); michael@0: yield m.setDailyLastNumeric("daily-last-numeric", 5, now); michael@0: yield m.setDailyLastNumeric("daily-last-numeric", 6, yesterday); michael@0: michael@0: let result = yield provider.storage.getDailyLastNumericFromFieldID( michael@0: lastDailyNumericID, now); michael@0: do_check_eq(result.size, 1); michael@0: do_check_true(result.hasDay(now)); michael@0: do_check_eq(result.getDay(now), 5); michael@0: michael@0: result = yield provider.storage.getDailyLastNumericFromFieldID( michael@0: lastDailyNumericID, yesterday); michael@0: do_check_true(result.hasDay(yesterday)); michael@0: do_check_eq(result.getDay(yesterday), 6); michael@0: michael@0: yield m.setDailyLastNumeric("daily-last-numeric", 7, now); michael@0: result = yield provider.storage.getDailyLastNumericFromFieldID( michael@0: lastDailyNumericID, now); michael@0: do_check_eq(result.getDay(now), 7); michael@0: michael@0: // Daily last text. michael@0: let lastDailyTextID = m.fieldID("daily-last-text"); michael@0: yield m.setDailyLastText("daily-last-text", "foo", now); michael@0: yield m.setDailyLastText("daily-last-text", "bar", yesterday); michael@0: michael@0: result = yield provider.storage.getDailyLastTextFromFieldID( michael@0: lastDailyTextID, now); michael@0: do_check_eq(result.size, 1); michael@0: do_check_true(result.hasDay(now)); michael@0: do_check_eq(result.getDay(now), "foo"); michael@0: michael@0: result = yield provider.storage.getDailyLastTextFromFieldID( michael@0: lastDailyTextID, yesterday); michael@0: do_check_true(result.hasDay(yesterday)); michael@0: do_check_eq(result.getDay(yesterday), "bar"); michael@0: michael@0: yield m.setDailyLastText("daily-last-text", "biz", now); michael@0: result = yield provider.storage.getDailyLastTextFromFieldID( michael@0: lastDailyTextID, now); michael@0: do_check_eq(result.getDay(now), "biz"); michael@0: michael@0: // Last numeric. michael@0: let lastNumericID = m.fieldID("last-numeric"); michael@0: yield m.setLastNumeric("last-numeric", 1, now); michael@0: result = yield provider.storage.getLastNumericFromFieldID(lastNumericID); michael@0: do_check_eq(result[1], 1); michael@0: do_check_true(result[0].getTime() < now.getTime()); michael@0: do_check_true(result[0].getTime() > yesterday.getTime()); michael@0: michael@0: yield m.setLastNumeric("last-numeric", 2, now); michael@0: result = yield provider.storage.getLastNumericFromFieldID(lastNumericID); michael@0: do_check_eq(result[1], 2); michael@0: michael@0: // Last text. michael@0: let lastTextID = m.fieldID("last-text"); michael@0: yield m.setLastText("last-text", "foo", now); michael@0: result = yield provider.storage.getLastTextFromFieldID(lastTextID); michael@0: do_check_eq(result[1], "foo"); michael@0: do_check_true(result[0].getTime() < now.getTime()); michael@0: do_check_true(result[0].getTime() > yesterday.getTime()); michael@0: michael@0: yield m.setLastText("last-text", "bar", now); michael@0: result = yield provider.storage.getLastTextFromFieldID(lastTextID); michael@0: do_check_eq(result[1], "bar"); michael@0: michael@0: yield provider.storage.close(); michael@0: }); michael@0: michael@0: add_task(function test_serialize_json_default() { michael@0: let provider = yield getProvider("serialize_json_default"); michael@0: michael@0: let now = new Date(); michael@0: let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); michael@0: michael@0: let m = provider.getMeasurement("DummyMeasurement", 1); michael@0: michael@0: m.incrementDailyCounter("daily-counter", now); michael@0: m.incrementDailyCounter("daily-counter", now); michael@0: m.incrementDailyCounter("daily-counter", yesterday); michael@0: michael@0: m.addDailyDiscreteNumeric("daily-discrete-numeric", 1, now); michael@0: m.addDailyDiscreteNumeric("daily-discrete-numeric", 2, now); michael@0: m.addDailyDiscreteNumeric("daily-discrete-numeric", 3, yesterday); michael@0: michael@0: m.addDailyDiscreteText("daily-discrete-text", "foo", now); michael@0: m.addDailyDiscreteText("daily-discrete-text", "bar", now); michael@0: m.addDailyDiscreteText("daily-discrete-text", "baz", yesterday); michael@0: michael@0: m.setDailyLastNumeric("daily-last-numeric", 4, now); michael@0: m.setDailyLastNumeric("daily-last-numeric", 5, yesterday); michael@0: michael@0: m.setDailyLastText("daily-last-text", "apple", now); michael@0: m.setDailyLastText("daily-last-text", "orange", yesterday); michael@0: michael@0: m.setLastNumeric("last-numeric", 6, now); michael@0: yield m.setLastText("last-text", "hello", now); michael@0: michael@0: let data = yield provider.storage.getMeasurementValues(m.id); michael@0: michael@0: let serializer = m.serializer(m.SERIALIZE_JSON); michael@0: let formatted = serializer.singular(data.singular); michael@0: michael@0: do_check_eq(Object.keys(formatted).length, 3); // Our keys + _v. michael@0: do_check_true("last-numeric" in formatted); michael@0: do_check_true("last-text" in formatted); michael@0: do_check_eq(formatted["last-numeric"], 6); michael@0: do_check_eq(formatted["last-text"], "hello"); michael@0: do_check_eq(formatted["_v"], 1); michael@0: michael@0: formatted = serializer.daily(data.days.getDay(now)); michael@0: do_check_eq(Object.keys(formatted).length, 6); // Our keys + _v. michael@0: do_check_eq(formatted["daily-counter"], 2); michael@0: do_check_eq(formatted["_v"], 1); michael@0: michael@0: do_check_true(Array.isArray(formatted["daily-discrete-numeric"])); michael@0: do_check_eq(formatted["daily-discrete-numeric"].length, 2); michael@0: do_check_eq(formatted["daily-discrete-numeric"][0], 1); michael@0: do_check_eq(formatted["daily-discrete-numeric"][1], 2); michael@0: michael@0: do_check_true(Array.isArray(formatted["daily-discrete-text"])); michael@0: do_check_eq(formatted["daily-discrete-text"].length, 2); michael@0: do_check_eq(formatted["daily-discrete-text"][0], "foo"); michael@0: do_check_eq(formatted["daily-discrete-text"][1], "bar"); michael@0: michael@0: do_check_eq(formatted["daily-last-numeric"], 4); michael@0: do_check_eq(formatted["daily-last-text"], "apple"); michael@0: michael@0: formatted = serializer.daily(data.days.getDay(yesterday)); michael@0: do_check_eq(formatted["daily-last-numeric"], 5); michael@0: do_check_eq(formatted["daily-last-text"], "orange"); michael@0: michael@0: // Now let's turn off a field so that it's present in the DB michael@0: // but not present in the output. michael@0: let called = false; michael@0: let excluded = "daily-last-numeric"; michael@0: Object.defineProperty(m, "shouldIncludeField", { michael@0: value: function fakeShouldIncludeField(field) { michael@0: called = true; michael@0: return field != excluded; michael@0: }, michael@0: }); michael@0: michael@0: let limited = serializer.daily(data.days.getDay(yesterday)); michael@0: do_check_true(called); michael@0: do_check_false(excluded in limited); michael@0: do_check_eq(formatted["daily-last-text"], "orange"); michael@0: michael@0: yield provider.storage.close(); michael@0: });