diff -r 000000000000 -r 6474c204b198 services/metrics/tests/xpcshell/test_metrics_provider_manager.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/metrics/tests/xpcshell/test_metrics_provider_manager.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,357 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://gre/modules/Promise.jsm"); +Cu.import("resource://gre/modules/Metrics.jsm"); +Cu.import("resource://testing-common/services/metrics/mocks.jsm"); + +const PULL_ONLY_TESTING_CATEGORY = "testing-only-pull-only-providers"; + +function run_test() { + let cm = Cc["@mozilla.org/categorymanager;1"] + .getService(Ci.nsICategoryManager); + cm.addCategoryEntry(PULL_ONLY_TESTING_CATEGORY, "DummyProvider", + "resource://testing-common/services/metrics/mocks.jsm", + false, true); + cm.addCategoryEntry(PULL_ONLY_TESTING_CATEGORY, "DummyConstantProvider", + "resource://testing-common/services/metrics/mocks.jsm", + false, true); + + run_next_test(); +}; + +add_task(function test_constructor() { + let storage = yield Metrics.Storage("constructor"); + let manager = new Metrics.ProviderManager(storage); + + yield storage.close(); +}); + +add_task(function test_register_provider() { + let storage = yield Metrics.Storage("register_provider"); + + let manager = new Metrics.ProviderManager(storage); + let dummy = new DummyProvider(); + + yield manager.registerProvider(dummy); + do_check_eq(manager._providers.size, 1); + yield manager.registerProvider(dummy); + do_check_eq(manager._providers.size, 1); + do_check_eq(manager.getProvider(dummy.name), dummy); + + let failed = false; + try { + manager.registerProvider({}); + } catch (ex) { + do_check_true(ex.message.startsWith("Provider is not valid")); + failed = true; + } finally { + do_check_true(failed); + failed = false; + } + + manager.unregisterProvider(dummy.name); + do_check_eq(manager._providers.size, 0); + do_check_null(manager.getProvider(dummy.name)); + + yield storage.close(); +}); + +add_task(function test_register_providers_from_category_manager() { + const category = "metrics-providers-js-modules"; + + let cm = Cc["@mozilla.org/categorymanager;1"] + .getService(Ci.nsICategoryManager); + cm.addCategoryEntry(category, "DummyProvider", + "resource://testing-common/services/metrics/mocks.jsm", + false, true); + + let storage = yield Metrics.Storage("register_providers_from_category_manager"); + let manager = new Metrics.ProviderManager(storage); + try { + do_check_eq(manager._providers.size, 0); + yield manager.registerProvidersFromCategoryManager(category); + do_check_eq(manager._providers.size, 1); + } finally { + yield storage.close(); + } +}); + +add_task(function test_collect_constant_data() { + let storage = yield Metrics.Storage("collect_constant_data"); + let errorCount = 0; + let manager= new Metrics.ProviderManager(storage); + manager.onProviderError = function () { errorCount++; } + let provider = new DummyProvider(); + yield manager.registerProvider(provider); + + do_check_eq(provider.collectConstantCount, 0); + + yield manager.collectConstantData(); + do_check_eq(provider.collectConstantCount, 1); + + do_check_true(manager._providers.get("DummyProvider").constantsCollected); + + yield storage.close(); + do_check_eq(errorCount, 0); +}); + +add_task(function test_collect_constant_throws() { + let storage = yield Metrics.Storage("collect_constant_throws"); + let manager = new Metrics.ProviderManager(storage); + let errors = []; + manager.onProviderError = function (error) { errors.push(error); }; + + let provider = new DummyProvider(); + provider.throwDuringCollectConstantData = "Fake error during collect"; + yield manager.registerProvider(provider); + + yield manager.collectConstantData(); + do_check_eq(errors.length, 1); + do_check_true(errors[0].contains(provider.throwDuringCollectConstantData)); + + yield storage.close(); +}); + +add_task(function test_collect_constant_populate_throws() { + let storage = yield Metrics.Storage("collect_constant_populate_throws"); + let manager = new Metrics.ProviderManager(storage); + let errors = []; + manager.onProviderError = function (error) { errors.push(error); }; + + let provider = new DummyProvider(); + provider.throwDuringConstantPopulate = "Fake error during constant populate"; + yield manager.registerProvider(provider); + + yield manager.collectConstantData(); + + do_check_eq(errors.length, 1); + do_check_true(errors[0].contains(provider.throwDuringConstantPopulate)); + do_check_false(manager._providers.get(provider.name).constantsCollected); + + yield storage.close(); +}); + +add_task(function test_collect_constant_onetime() { + let storage = yield Metrics.Storage("collect_constant_onetime"); + let manager = new Metrics.ProviderManager(storage); + let provider = new DummyProvider(); + yield manager.registerProvider(provider); + + yield manager.collectConstantData(); + do_check_eq(provider.collectConstantCount, 1); + + yield manager.collectConstantData(); + do_check_eq(provider.collectConstantCount, 1); + + yield storage.close(); +}); + +add_task(function test_collect_multiple() { + let storage = yield Metrics.Storage("collect_multiple"); + let manager = new Metrics.ProviderManager(storage); + + for (let i = 0; i < 10; i++) { + yield manager.registerProvider(new DummyProvider("provider" + i)); + } + + do_check_eq(manager._providers.size, 10); + + yield manager.collectConstantData(); + + yield storage.close(); +}); + +add_task(function test_collect_daily() { + let storage = yield Metrics.Storage("collect_daily"); + let manager = new Metrics.ProviderManager(storage); + + let provider1 = new DummyProvider("DP1"); + let provider2 = new DummyProvider("DP2"); + + yield manager.registerProvider(provider1); + yield manager.registerProvider(provider2); + + yield manager.collectDailyData(); + do_check_eq(provider1.collectDailyCount, 1); + do_check_eq(provider2.collectDailyCount, 1); + + yield manager.collectDailyData(); + do_check_eq(provider1.collectDailyCount, 2); + do_check_eq(provider2.collectDailyCount, 2); + + yield storage.close(); +}); + +add_task(function test_pull_only_not_initialized() { + let storage = yield Metrics.Storage("pull_only_not_initialized"); + let manager = new Metrics.ProviderManager(storage); + yield manager.registerProvidersFromCategoryManager(PULL_ONLY_TESTING_CATEGORY); + do_check_eq(manager.providers.length, 1); + do_check_eq(manager.providers[0].name, "DummyProvider"); + yield storage.close(); +}); + +add_task(function test_pull_only_registration() { + let storage = yield Metrics.Storage("pull_only_registration"); + let manager = new Metrics.ProviderManager(storage); + yield manager.registerProvidersFromCategoryManager(PULL_ONLY_TESTING_CATEGORY); + do_check_eq(manager.providers.length, 1); + + // Simple registration and unregistration. + yield manager.ensurePullOnlyProvidersRegistered(); + do_check_eq(manager.providers.length, 2); + do_check_neq(manager.getProvider("DummyConstantProvider"), null); + yield manager.ensurePullOnlyProvidersUnregistered(); + do_check_eq(manager.providers.length, 1); + do_check_null(manager.getProvider("DummyConstantProvider")); + + // Multiple calls to register work. + yield manager.ensurePullOnlyProvidersRegistered(); + do_check_eq(manager.providers.length, 2); + yield manager.ensurePullOnlyProvidersRegistered(); + do_check_eq(manager.providers.length, 2); + + // Unregister with 2 requests for registration should not unregister. + yield manager.ensurePullOnlyProvidersUnregistered(); + do_check_eq(manager.providers.length, 2); + + // But the 2nd one will. + yield manager.ensurePullOnlyProvidersUnregistered(); + do_check_eq(manager.providers.length, 1); + + yield storage.close(); +}); + +add_task(function test_pull_only_register_while_registering() { + let storage = yield Metrics.Storage("pull_only_register_will_registering"); + let manager = new Metrics.ProviderManager(storage); + yield manager.registerProvidersFromCategoryManager(PULL_ONLY_TESTING_CATEGORY); + + manager.ensurePullOnlyProvidersRegistered(); + manager.ensurePullOnlyProvidersRegistered(); + yield manager.ensurePullOnlyProvidersRegistered(); + do_check_eq(manager.providers.length, 2); + + manager.ensurePullOnlyProvidersUnregistered(); + manager.ensurePullOnlyProvidersUnregistered(); + yield manager.ensurePullOnlyProvidersUnregistered(); + do_check_eq(manager.providers.length, 1); + + yield storage.close(); +}); + +add_task(function test_pull_only_unregister_while_registering() { + let storage = yield Metrics.Storage("pull_only_unregister_while_registering"); + let manager = new Metrics.ProviderManager(storage); + yield manager.registerProvidersFromCategoryManager(PULL_ONLY_TESTING_CATEGORY); + + manager.ensurePullOnlyProvidersRegistered(); + yield manager.ensurePullOnlyProvidersUnregistered(); + do_check_eq(manager.providers.length, 1); + + yield storage.close(); +}); + +add_task(function test_pull_only_register_while_unregistering() { + let storage = yield Metrics.Storage("pull_only_register_while_unregistering"); + let manager = new Metrics.ProviderManager(storage); + yield manager.registerProvidersFromCategoryManager(PULL_ONLY_TESTING_CATEGORY); + + yield manager.ensurePullOnlyProvidersRegistered(); + manager.ensurePullOnlyProvidersUnregistered(); + yield manager.ensurePullOnlyProvidersRegistered(); + do_check_eq(manager.providers.length, 2); + + yield storage.close(); +}); + +// Re-use database for perf reasons. +const REGISTRATION_ERRORS_DB = "registration_errors"; + +add_task(function test_category_manager_registration_error() { + let storage = yield Metrics.Storage(REGISTRATION_ERRORS_DB); + let manager = new Metrics.ProviderManager(storage); + + let cm = Cc["@mozilla.org/categorymanager;1"] + .getService(Ci.nsICategoryManager); + cm.addCategoryEntry("registration-errors", "DummyThrowOnInitProvider", + "resource://testing-common/services/metrics/mocks.jsm", + false, true); + + let deferred = Promise.defer(); + let errorCount = 0; + + manager.onProviderError = function (msg) { + errorCount++; + deferred.resolve(msg); + }; + + yield manager.registerProvidersFromCategoryManager("registration-errors"); + do_check_eq(manager.providers.length, 0); + do_check_eq(errorCount, 1); + + let msg = yield deferred.promise; + do_check_true(msg.contains("Provider error: DummyThrowOnInitProvider: " + + "Error registering provider from category manager: " + + "Error: Dummy Error")); + + yield storage.close(); +}); + +add_task(function test_pull_only_registration_error() { + let storage = yield Metrics.Storage(REGISTRATION_ERRORS_DB); + let manager = new Metrics.ProviderManager(storage); + + let deferred = Promise.defer(); + let errorCount = 0; + + manager.onProviderError = function (msg) { + errorCount++; + deferred.resolve(msg); + }; + + yield manager.registerProviderFromType(DummyPullOnlyThrowsOnInitProvider); + do_check_eq(errorCount, 0); + + yield manager.ensurePullOnlyProvidersRegistered(); + do_check_eq(errorCount, 1); + + let msg = yield deferred.promise; + do_check_true(msg.contains("Provider error: DummyPullOnlyThrowsOnInitProvider: " + + "Error registering pull-only provider: Error: Dummy Error")); + + yield storage.close(); +}); + +add_task(function test_error_during_shutdown() { + let storage = yield Metrics.Storage(REGISTRATION_ERRORS_DB); + let manager = new Metrics.ProviderManager(storage); + + let deferred = Promise.defer(); + let errorCount = 0; + + manager.onProviderError = function (msg) { + errorCount++; + deferred.resolve(msg); + }; + + yield manager.registerProviderFromType(DummyThrowOnShutdownProvider); + yield manager.registerProviderFromType(DummyProvider); + do_check_eq(errorCount, 0); + do_check_eq(manager.providers.length, 1); + + yield manager.ensurePullOnlyProvidersRegistered(); + do_check_eq(errorCount, 0); + yield manager.ensurePullOnlyProvidersUnregistered(); + do_check_eq(errorCount, 1); + let msg = yield deferred.promise; + do_check_true(msg.contains("Provider error: DummyThrowOnShutdownProvider: " + + "Error when shutting down provider: Error: Dummy shutdown error")); + + yield storage.close(); +});