summaryrefslogtreecommitdiffstats
path: root/browser/components/attribution/test/browser/browser_AttributionCode_telemetry.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/attribution/test/browser/browser_AttributionCode_telemetry.js')
-rw-r--r--browser/components/attribution/test/browser/browser_AttributionCode_telemetry.js101
1 files changed, 101 insertions, 0 deletions
diff --git a/browser/components/attribution/test/browser/browser_AttributionCode_telemetry.js b/browser/components/attribution/test/browser/browser_AttributionCode_telemetry.js
new file mode 100644
index 0000000000..43888a1e74
--- /dev/null
+++ b/browser/components/attribution/test/browser/browser_AttributionCode_telemetry.js
@@ -0,0 +1,101 @@
+ChromeUtils.defineESModuleGetters(this, {
+ TelemetryTestUtils: "resource://testing-common/TelemetryTestUtils.sys.mjs",
+});
+const { AttributionIOUtils } = ChromeUtils.importESModule(
+ "resource:///modules/AttributionCode.sys.mjs"
+);
+
+add_task(async function test_parse_error() {
+ if (AppConstants.platform == "macosx") {
+ // On macOS, the underlying data is the OS-level quarantine
+ // database. We need to start from nothing to isolate the cache.
+ const { MacAttribution } = ChromeUtils.importESModule(
+ "resource:///modules/MacAttribution.sys.mjs"
+ );
+ let attributionSvc = Cc["@mozilla.org/mac-attribution;1"].getService(
+ Ci.nsIMacAttributionService
+ );
+ attributionSvc.setReferrerUrl(MacAttribution.applicationPath, "", true);
+ }
+
+ registerCleanupFunction(async () => {
+ await AttributionCode.deleteFileAsync();
+ AttributionCode._clearCache();
+ });
+ const histogram = Services.telemetry.getHistogramById(
+ "BROWSER_ATTRIBUTION_ERRORS"
+ );
+ // Delete the file to trigger a read error
+ await AttributionCode.deleteFileAsync();
+ AttributionCode._clearCache();
+ // Clear any existing telemetry
+ histogram.clear();
+ let result = await AttributionCode.getAttrDataAsync();
+ Assert.deepEqual(
+ result,
+ {},
+ "Shouldn't be able to get a result if the file doesn't exist"
+ );
+
+ // Write an invalid file to trigger a decode error
+ // Skip this for MSIX packages though - we can't write or delete
+ // the attribution file there, everything happens in memory instead.
+ if (
+ AppConstants.platform === "win" &&
+ !Services.sysinfo.getProperty("hasWinPackageId")
+ ) {
+ await AttributionCode.deleteFileAsync();
+ AttributionCode._clearCache();
+ // Empty string is valid on macOS.
+ await AttributionCode.writeAttributionFile(
+ AppConstants.platform == "macosx" ? "invalid" : ""
+ );
+ result = await AttributionCode.getAttrDataAsync();
+ Assert.deepEqual(result, {}, "Should have failed to parse");
+
+ // `assertHistogram` also ensures that `read_error` index 0 is 0
+ // as we should not have recorded telemetry from the previous `getAttrDataAsync` call
+ TelemetryTestUtils.assertHistogram(histogram, INDEX_DECODE_ERROR, 1);
+ // Reset
+ histogram.clear();
+ }
+});
+
+add_task(async function test_read_error() {
+ registerCleanupFunction(async () => {
+ await AttributionCode.deleteFileAsync();
+ AttributionCode._clearCache();
+ });
+ const histogram = Services.telemetry.getHistogramById(
+ "BROWSER_ATTRIBUTION_ERRORS"
+ );
+
+ // Delete the file to trigger a read error
+ await AttributionCode.deleteFileAsync();
+ AttributionCode._clearCache();
+ // Clear any existing telemetry
+ histogram.clear();
+
+ // Force the file to exist but then cause a read error
+ let oldExists = AttributionIOUtils.exists;
+ AttributionIOUtils.exists = () => true;
+
+ let oldRead = AttributionIOUtils.read;
+ AttributionIOUtils.read = () => {
+ throw new Error("read_error");
+ };
+
+ registerCleanupFunction(() => {
+ AttributionIOUtils.exists = oldExists;
+ AttributionIOUtils.read = oldRead;
+ });
+
+ // Try to read the file
+ await AttributionCode.getAttrDataAsync();
+
+ // It should record the read error
+ TelemetryTestUtils.assertHistogram(histogram, INDEX_READ_ERROR, 1);
+
+ // Clear any existing telemetry
+ histogram.clear();
+});