diff options
Diffstat (limited to 'toolkit/components/telemetry/tests/unit/test_client_id.js')
-rw-r--r-- | toolkit/components/telemetry/tests/unit/test_client_id.js | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/toolkit/components/telemetry/tests/unit/test_client_id.js b/toolkit/components/telemetry/tests/unit/test_client_id.js new file mode 100644 index 0000000000..c20f70e2b2 --- /dev/null +++ b/toolkit/components/telemetry/tests/unit/test_client_id.js @@ -0,0 +1,163 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { ClientID } = ChromeUtils.importESModule( + "resource://gre/modules/ClientID.sys.mjs" +); + +const PREF_CACHED_CLIENTID = "toolkit.telemetry.cachedClientID"; + +var drsPath; + +const uuidRegex = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + +function run_test() { + do_get_profile(); + drsPath = PathUtils.join(PathUtils.profileDir, "datareporting", "state.json"); + + Services.prefs.setBoolPref( + "toolkit.telemetry.testing.overrideProductsCheck", + true + ); + run_next_test(); +} + +add_task(function test_setup() { + // FOG needs a profile and to be init. + do_get_profile(); + Services.fog.initializeFOG(); +}); + +add_task(async function test_client_id() { + const invalidIDs = [ + [-1, "setIntPref"], + [0.5, "setIntPref"], + ["INVALID-UUID", "setStringPref"], + [true, "setBoolPref"], + ["", "setStringPref"], + ["3d1e1560-682a-4043-8cf2-aaaaaaaaaaaZ", "setStringPref"], + ]; + + // If there is no DRS file, and no cached id, we should get a new client ID. + await ClientID._reset(); + Services.prefs.clearUserPref(PREF_CACHED_CLIENTID); + await IOUtils.remove(drsPath, { ignoreAbsent: true }); + let clientID = await ClientID.getClientID(); + Assert.equal(typeof clientID, "string"); + Assert.ok(uuidRegex.test(clientID)); + if (AppConstants.platform != "android") { + Assert.equal(clientID, Glean.legacyTelemetry.clientId.testGetValue()); + } + + // We should be guarded against invalid DRS json. + await ClientID._reset(); + Services.prefs.clearUserPref(PREF_CACHED_CLIENTID); + await IOUtils.writeUTF8(drsPath, "abcd", { + tmpPath: drsPath + ".tmp", + }); + clientID = await ClientID.getClientID(); + Assert.equal(typeof clientID, "string"); + Assert.ok(uuidRegex.test(clientID)); + if (AppConstants.platform != "android") { + Assert.equal(clientID, Glean.legacyTelemetry.clientId.testGetValue()); + } + + // If the DRS data is broken, we should end up with the cached ID. + let oldClientID = clientID; + for (let [invalidID] of invalidIDs) { + await ClientID._reset(); + await IOUtils.writeJSON(drsPath, { clientID: invalidID }); + clientID = await ClientID.getClientID(); + Assert.equal(clientID, oldClientID); + if (AppConstants.platform != "android") { + Assert.equal(clientID, Glean.legacyTelemetry.clientId.testGetValue()); + } + } + + // Test that valid DRS actually works. + const validClientID = "5afebd62-a33c-416c-b519-5c60fb988e8e"; + await ClientID._reset(); + await IOUtils.writeJSON(drsPath, { clientID: validClientID }); + clientID = await ClientID.getClientID(); + Assert.equal(clientID, validClientID); + if (AppConstants.platform != "android") { + Assert.equal(clientID, Glean.legacyTelemetry.clientId.testGetValue()); + } + + // Test that reloading a valid DRS works. + await ClientID._reset(); + Services.prefs.clearUserPref(PREF_CACHED_CLIENTID); + clientID = await ClientID.getClientID(); + Assert.equal(clientID, validClientID); + if (AppConstants.platform != "android") { + Assert.equal(clientID, Glean.legacyTelemetry.clientId.testGetValue()); + } + + // Assure that cached IDs are being checked for validity. + for (let [invalidID, prefFunc] of invalidIDs) { + await ClientID._reset(); + Services.prefs[prefFunc](PREF_CACHED_CLIENTID, invalidID); + let cachedID = ClientID.getCachedClientID(); + Assert.strictEqual( + cachedID, + null, + "ClientID should ignore invalid cached IDs" + ); + Assert.ok( + !Services.prefs.prefHasUserValue(PREF_CACHED_CLIENTID), + "ClientID should reset invalid cached IDs" + ); + Assert.ok( + Services.prefs.getPrefType(PREF_CACHED_CLIENTID) == + Ci.nsIPrefBranch.PREF_INVALID, + "ClientID should reset invalid cached IDs" + ); + } +}); + +add_task(async function test_setCanaryClientID() { + const KNOWN_UUID = "c0ffeec0-ffee-c0ff-eec0-ffeec0ffeec0"; + + await ClientID._reset(); + + // We should be able to set a valid UUID + await ClientID.setCanaryClientID(); + let clientID = await ClientID.getClientID(); + Assert.equal(KNOWN_UUID, clientID); + if (AppConstants.platform != "android") { + Assert.equal(clientID, Glean.legacyTelemetry.clientId.testGetValue()); + } +}); + +add_task(async function test_removeParallelGet() { + // We should get a valid UUID after reset + await ClientID.removeClientID(); + let firstClientID = await ClientID.getClientID(); + if (AppConstants.platform != "android") { + Assert.equal(firstClientID, Glean.legacyTelemetry.clientId.testGetValue()); + } + + // We should get the same ID twice when requesting it in parallel to a reset. + let promiseRemoveClientID = ClientID.removeClientID(); + let p = ClientID.getClientID(); + let newClientID = await ClientID.getClientID(); + await promiseRemoveClientID; + let otherClientID = await p; + + Assert.notEqual( + firstClientID, + newClientID, + "After reset client ID should be different." + ); + Assert.equal( + newClientID, + otherClientID, + "Getting the client ID in parallel to a reset should give the same id." + ); + if (AppConstants.platform != "android") { + Assert.equal(newClientID, Glean.legacyTelemetry.clientId.testGetValue()); + } +}); |