forked from mirrors/gecko-dev
		
	We can't add the provenance data to the `installation.first_seen` extra data because it is already at its maximum number of keys. So instead we will add the `installation.first_seen_prov_ext` event which will be sent at the same time as `installation.first_seen` and will contain provenance attribution data in its extras object. Differential Revision: https://phabricator.services.mozilla.com/D172520
		
			
				
	
	
		
			538 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			538 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
 * http://creativecommons.org/publicdomain/zero/1.0/
 | 
						|
 */
 | 
						|
"use strict";
 | 
						|
 | 
						|
/**
 | 
						|
 * Test that we can properly parse and validate `zoneIdProvenanceData`.
 | 
						|
 */
 | 
						|
 | 
						|
const { AttributionIOUtils } = ChromeUtils.importESModule(
 | 
						|
  "resource:///modules/AttributionCode.sys.mjs"
 | 
						|
);
 | 
						|
const { ProvenanceData } = ChromeUtils.importESModule(
 | 
						|
  "resource:///modules/ProvenanceData.sys.mjs"
 | 
						|
);
 | 
						|
const { TelemetryTestUtils } = ChromeUtils.importESModule(
 | 
						|
  "resource://testing-common/TelemetryTestUtils.sys.mjs"
 | 
						|
);
 | 
						|
 | 
						|
add_setup(function setup() {
 | 
						|
  let origReadUTF8 = AttributionIOUtils.readUTF8;
 | 
						|
  registerCleanupFunction(() => {
 | 
						|
    AttributionIOUtils.readUTF8 = origReadUTF8;
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
// If `iniFileContents` is passed as `null`, we will simulate an error reading
 | 
						|
// the INI.
 | 
						|
async function testProvenance(iniFileContents, testFn, telemetryTestFn) {
 | 
						|
  // The extra data returned by `ProvenanceData.submitProvenanceTelemetry` uses
 | 
						|
  // names that don't actually match the scalar names due to name length
 | 
						|
  // restrictions.
 | 
						|
  let scalarToExtraKeyMap = {
 | 
						|
    "attribution.provenance.data_exists": "data_exists",
 | 
						|
    "attribution.provenance.file_system": "file_system",
 | 
						|
    "attribution.provenance.ads_exists": "ads_exists",
 | 
						|
    "attribution.provenance.security_zone": "security_zone",
 | 
						|
    "attribution.provenance.referrer_url_exists": "refer_url_exist",
 | 
						|
    "attribution.provenance.referrer_url_is_mozilla": "refer_url_moz",
 | 
						|
    "attribution.provenance.host_url_exists": "host_url_exist",
 | 
						|
    "attribution.provenance.host_url_is_mozilla": "host_url_moz",
 | 
						|
  };
 | 
						|
 | 
						|
  if (iniFileContents == null) {
 | 
						|
    AttributionIOUtils.readUTF8 = async path => {
 | 
						|
      throw new Error("test error: simulating provenance file read error");
 | 
						|
    };
 | 
						|
  } else {
 | 
						|
    AttributionIOUtils.readUTF8 = async path => iniFileContents;
 | 
						|
  }
 | 
						|
  let provenance = await ProvenanceData.readZoneIdProvenanceFile();
 | 
						|
  if (testFn) {
 | 
						|
    await testFn(provenance);
 | 
						|
  }
 | 
						|
  if (telemetryTestFn) {
 | 
						|
    Services.telemetry.clearScalars();
 | 
						|
    let extras = await ProvenanceData.submitProvenanceTelemetry();
 | 
						|
    let scalars = Services.telemetry.getSnapshotForScalars(
 | 
						|
      "new-profile",
 | 
						|
      false /* aClear */
 | 
						|
    ).parent;
 | 
						|
    let checkScalar = (scalarName, expectedValue) => {
 | 
						|
      TelemetryTestUtils.assertScalar(scalars, scalarName, expectedValue);
 | 
						|
      let extraKey = scalarToExtraKeyMap[scalarName];
 | 
						|
      Assert.equal(extras[extraKey], expectedValue.toString());
 | 
						|
    };
 | 
						|
    telemetryTestFn(checkScalar);
 | 
						|
  }
 | 
						|
  ProvenanceData._clearCache();
 | 
						|
}
 | 
						|
 | 
						|
add_task(async function unableToReadFile() {
 | 
						|
  await testProvenance(
 | 
						|
    null,
 | 
						|
    provenance => {
 | 
						|
      Assert.ok("readProvenanceError" in provenance);
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.data_exists", false);
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function expectedMozilla() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
fileSystem=NTFS
 | 
						|
zoneIdFileSize=194
 | 
						|
zoneIdBufferLargeEnough=true
 | 
						|
zoneIdTruncated=false
 | 
						|
 | 
						|
[MozillaZoneIdentifierStartSentinel]
 | 
						|
[ZoneTransfer]
 | 
						|
ZoneId=3
 | 
						|
ReferrerUrl=https://mozilla.org/
 | 
						|
HostUrl=https://download-installer.cdn.mozilla.net/pub/firefox/nightly/latest-mozilla-central-l10n/Firefox%20Installer.en-US.exe
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.deepEqual(provenance, {
 | 
						|
        fileSystem: "NTFS",
 | 
						|
        zoneIdFileSize: 194,
 | 
						|
        zoneIdBufferLargeEnough: true,
 | 
						|
        zoneIdTruncated: false,
 | 
						|
        zoneId: 3,
 | 
						|
        referrerUrl: "https://mozilla.org/",
 | 
						|
        hostUrl:
 | 
						|
          "https://download-installer.cdn.mozilla.net/pub/firefox/nightly/latest-mozilla-central-l10n/Firefox%20Installer.en-US.exe",
 | 
						|
        referrerUrlIsMozilla: true,
 | 
						|
        hostUrlIsMozilla: true,
 | 
						|
      });
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.data_exists", true);
 | 
						|
      checkScalar("attribution.provenance.file_system", "NTFS");
 | 
						|
      checkScalar("attribution.provenance.ads_exists", true);
 | 
						|
      checkScalar("attribution.provenance.security_zone", "3");
 | 
						|
      checkScalar("attribution.provenance.referrer_url_exists", true);
 | 
						|
      checkScalar("attribution.provenance.referrer_url_is_mozilla", true);
 | 
						|
      checkScalar("attribution.provenance.host_url_exists", true);
 | 
						|
      checkScalar("attribution.provenance.host_url_is_mozilla", true);
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function expectedNonMozilla() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[ZoneTransfer]
 | 
						|
ReferrerUrl=https://mozilla.foobar.org/
 | 
						|
HostUrl=https://download-installer.cdn.mozilla.foobar.net/pub/firefox/nightly/latest-mozilla-central-l10n/Firefox%20Installer.en-US.exe
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.referrerUrlIsMozilla, false);
 | 
						|
      Assert.equal(provenance.hostUrlIsMozilla, false);
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.referrer_url_exists", true);
 | 
						|
      checkScalar("attribution.provenance.referrer_url_is_mozilla", false);
 | 
						|
      checkScalar("attribution.provenance.host_url_exists", true);
 | 
						|
      checkScalar("attribution.provenance.host_url_is_mozilla", false);
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function readFsError() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
readFsError=openFile
 | 
						|
readFsErrorCode=1234
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.readFsError, "openFile");
 | 
						|
      Assert.equal(provenance.readFsErrorCode, 1234);
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.file_system", "error");
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedReadFsError() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
readFsError=openFile
 | 
						|
readFsErrorCode=bazqux
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.readFsError, "openFile");
 | 
						|
      Assert.ok(!("readFsErrorCode" in provenance));
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.file_system", "error");
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedReadFsError() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
readFsError=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.readFsError, "unexpected");
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.file_system", "error");
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function missingFileSystem() {
 | 
						|
  await testProvenance(
 | 
						|
    ``,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.fileSystem, "missing");
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.file_system", "missing");
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function fileSystem() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
fileSystem=ntfs
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.fileSystem, "NTFS");
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.file_system", "NTFS");
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedFileSystem() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
fileSystem=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.fileSystem, "other");
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.file_system", "other");
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function zoneIdFileSize() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdFileSize=1234
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdFileSize, 1234);
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unknownZoneIdFileSize() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdFileSize=unknown
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdFileSize, "unknown");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedZoneIdFileSize() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdFileSize=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdFileSize, "unexpected");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function missingZoneIdFileSize() {
 | 
						|
  await testProvenance(
 | 
						|
    ``,
 | 
						|
    provenance => {
 | 
						|
      Assert.ok(!("zoneIdFileSize" in provenance));
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function zoneIdBufferLargeEnoughTrue() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdBufferLargeEnough=TrUe
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdBufferLargeEnough, true);
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function zoneIdBufferLargeEnoughFalse() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdBufferLargeEnough=FaLsE
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdBufferLargeEnough, false);
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unknownZoneIdBufferLargeEnough() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdBufferLargeEnough=unknown
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdBufferLargeEnough, "unknown");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unknownZoneIdBufferLargeEnough() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdBufferLargeEnough=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdBufferLargeEnough, "unexpected");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function missingZoneIdBufferLargeEnough() {
 | 
						|
  await testProvenance(``, provenance => {
 | 
						|
    Assert.ok(!("zoneIdBufferLargeEnough" in provenance));
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function zoneIdTruncatedTrue() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdTruncated=TrUe
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdTruncated, true);
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function zoneIdTruncatedFalse() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdTruncated=FaLsE
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdTruncated, false);
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unknownZoneIdTruncated() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdTruncated=unknown
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdTruncated, "unknown");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedZoneIdTruncated() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
zoneIdTruncated=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneIdTruncated, "unexpected");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function missingZoneIdTruncated() {
 | 
						|
  await testProvenance(``, provenance => {
 | 
						|
    Assert.ok(!("zoneIdTruncated" in provenance));
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function readZoneIdError() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
readZoneIdError=openFile
 | 
						|
readZoneIdErrorCode=1234
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.readZoneIdError, "openFile");
 | 
						|
      Assert.equal(provenance.readZoneIdErrorCode, 1234);
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedReadZoneIdErrorCode() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
readZoneIdError=openFile
 | 
						|
readZoneIdErrorCode=bazqux
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.readZoneIdError, "openFile");
 | 
						|
      Assert.ok(!("readZoneIdErrorCode" in provenance));
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function noAdsOnInstaller() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
readZoneIdError=openFile
 | 
						|
readZoneIdErrorCode=2
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.readZoneIdError, "openFile");
 | 
						|
      Assert.equal(provenance.readZoneIdErrorCode, 2);
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.ads_exists", false);
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedReadZoneIdError() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[Mozilla]
 | 
						|
readZoneIdError=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.readZoneIdError, "unexpected");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function missingZoneId() {
 | 
						|
  await testProvenance(
 | 
						|
    ``,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneId, "missing");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedZoneId() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[ZoneTransfer]
 | 
						|
ZoneId=9999999999
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.zoneId, "unexpected");
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.ads_exists", true);
 | 
						|
      checkScalar("attribution.provenance.security_zone", "unexpected");
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function missingReferrerUrl() {
 | 
						|
  await testProvenance(
 | 
						|
    ``,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.referrerUrl, "missing");
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.ads_exists", true);
 | 
						|
      checkScalar("attribution.provenance.referrer_url_exists", false);
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedReferrerUrl() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[ZoneTransfer]
 | 
						|
ReferrerUrl=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.referrerUrl, "unexpected");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function missingHostUrl() {
 | 
						|
  await testProvenance(
 | 
						|
    ``,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.hostUrl, "missing");
 | 
						|
    },
 | 
						|
    checkScalar => {
 | 
						|
      checkScalar("attribution.provenance.ads_exists", true);
 | 
						|
      checkScalar("attribution.provenance.referrer_url_exists", false);
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function unexpectedHostUrl() {
 | 
						|
  await testProvenance(
 | 
						|
    `
 | 
						|
[ZoneTransfer]
 | 
						|
HostUrl=foobar
 | 
						|
`,
 | 
						|
    provenance => {
 | 
						|
      Assert.equal(provenance.hostUrl, "unexpected");
 | 
						|
    },
 | 
						|
    null
 | 
						|
  );
 | 
						|
});
 |