/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; ChromeUtils.defineESModuleGetters(this, { ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs", TelemetryTestUtils: "resource://testing-common/TelemetryTestUtils.sys.mjs", }); AddonTestUtils.init(this); AddonTestUtils.overrideCertDB(); AddonTestUtils.createAppInfo( "xpcshell@tests.mozilla.org", "XPCShell", "42", "42" ); const ADDON_ID = "test-startup-cache-telemetry@xpcshell.mozilla.org"; add_setup(async () => { // FOG needs a profile directory to put its data in. do_get_profile(); // FOG needs to be initialized in order for data to flow. Services.fog.initializeFOG(); await AddonTestUtils.promiseStartupManager(); }); add_task(async function test_startupCache_write_byteLength() { Services.fog.testResetFOG(); const extension = ExtensionTestUtils.loadExtension({ useAddonManager: "permanent", manifest: { browser_specific_settings: { gecko: { id: ADDON_ID } }, }, }); await extension.startup(); const { StartupCache } = ExtensionParent; const aomStartup = Cc[ "@mozilla.org/addons/addon-manager-startup;1" ].getService(Ci.amIAddonManagerStartup); let expectedByteLength = new Uint8Array( aomStartup.encodeBlob(StartupCache._data) ).byteLength; equal( typeof expectedByteLength, "number", "Got a numeric byteLength for the expected startupCache data" ); Assert.greater( expectedByteLength, 0, "Got a non-zero byteLength as expected" ); await StartupCache._saveNow(); let scalars = TelemetryTestUtils.getProcessScalars("parent"); equal( scalars["extensions.startupCache.write_byteLength"], expectedByteLength, "Got the expected value set in the 'extensions.startupCache.write_byteLength' scalar" ); equal( Glean.extensions.startupCacheWriteBytelength.testGetValue(), expectedByteLength, "Expected 'extensions.startupCache.write_byteLength' Glean metric." ); await extension.unload(); }); add_task(async function test_startupCache_read_errors() { const { StartupCache } = ExtensionParent; // Clear any pre-existing keyed scalar. TelemetryTestUtils.getProcessScalars("parent", /* keyed */ true, true); Services.fog.testResetFOG(); // Temporarily point StartupCache._file to a path that is // not going to exist for sure. Assert.notEqual( StartupCache.file, null, "Got a StartupCache._file non-null property as expected" ); const oldFile = StartupCache.file; const restoreStartupCacheFile = () => (StartupCache.file = oldFile); StartupCache.file = `${StartupCache.file}.non_existing_file.${Math.random()}`; registerCleanupFunction(restoreStartupCacheFile); // Make sure the _readData has been called and we can expect // the extensions.startupCache.read_errors scalar to have // been recorded. await StartupCache._readData(); let scalars = TelemetryTestUtils.getProcessScalars( "parent", /* keyed */ true ); Assert.deepEqual( scalars["extensions.startupCache.read_errors"], { NotFoundError: 1, }, "Got the expected value set in the 'extensions.startupCache.read_errors' keyed scalar" ); Assert.deepEqual( Glean.extensions.startupCacheReadErrors.NotFoundError.testGetValue(), 1, "Expected value for 'extensions.startupCache.read_errors' Glean metric." ); restoreStartupCacheFile(); }); add_task(async function test_startupCache_load_timestamps() { const { StartupCache } = ExtensionParent; // Clear any pre-existing keyed scalar and Glean metrics data. Services.telemetry.getSnapshotForScalars("main", true); Services.fog.testResetFOG(); let gleanMetric = Glean.extensions.startupCacheLoadTime.testGetValue(); equal( gleanMetric, null, "Expect extensions.startup_cache_load_time Glean metric to be initially null" ); // Make sure the _readData has been called and we can expect // the startupCache load telemetry timestamps to have been // recorded. await StartupCache._readData(); info( "Verify telemetry recorded for the 'extensions.startup_cache_load_time' Glean metric" ); gleanMetric = Glean.extensions.startupCacheLoadTime.testGetValue(); equal( typeof gleanMetric, "number", "Expect extensions.startup_cache_load_time Glean metric to be set to a number" ); info( "Verify telemetry mirrored into the 'extensions.startupCache.load_time' scalar" ); const scalars = TelemetryTestUtils.getProcessScalars("parent", false, true); const mirror = scalars["extensions.startupCache.load_time"]; equal( typeof mirror, "number", "Expect extensions.startupCache.load_time mirrored scalar to be set to a number" ); // See https://bugzilla.mozilla.org/show_bug.cgi?id=1865850. Assert.lessOrEqual( Math.abs(gleanMetric - mirror), 1, `Expect Glean metric ${gleanMetric} and mirrored scalar ${mirror} to be within 1ms of each other.` ); });