commit 867009dc644627bcfc520004fc5436e181f898b7
parent faaa95ad17de048438a166d0411026b6c45f96f1
Author: Florian Quèze <florian@queze.net>
Date: Fri, 19 Dec 2025 22:06:25 +0000
Bug 2006845 - Include commit hashes in the xpcshell-<date>.json files, r=ahal.
Differential Revision: https://phabricator.services.mozilla.com/D276972
Diffstat:
3 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/testing/timings/JSON_FORMAT.md b/testing/timings/JSON_FORMAT.md
@@ -101,18 +101,24 @@ String tables for efficient storage. All strings are deduplicated and stored onc
"Testing :: XPCShell Harness",
"Firefox :: General",
...
+ ],
+ "commitIds": [ // Commit IDs from repository (extracted from profile.meta.sourceURL)
+ "f37a6863f87aeeb870b16223045ea7614b1ba0a7",
+ "abc123def456789012345678901234567890abcd",
+ ...
]
}
```
### taskInfo
-Maps task IDs to their associated job names and repositories. These are parallel arrays indexed by `taskIdId`:
+Maps task IDs to their associated job names, repositories, and commit IDs. These are parallel arrays indexed by `taskIdId`:
```json
{
"repositoryIds": [0, 1, 0, 2, ...], // Index into tables.repositories
- "jobNameIds": [0, 0, 1, 1, ...] // Index into tables.jobNames
+ "jobNameIds": [0, 0, 1, 1, ...], // Index into tables.jobNames
+ "commitIds": [0, 1, 0, null, ...] // Index into tables.commitIds (null if not available)
}
```
@@ -122,6 +128,8 @@ const taskIdId = 5;
const taskId = tables.taskIds[taskIdId]; // "YJJe4a0CRIqbAmcCo8n63w.0"
const repository = tables.repositories[taskInfo.repositoryIds[taskIdId]]; // "mozilla-central"
const jobName = tables.jobNames[taskInfo.jobNameIds[taskIdId]]; // "test-linux1804-64/opt-xpcshell"
+const commitIdIdx = taskInfo.commitIds[taskIdId];
+const commitId = commitIdIdx !== null ? tables.commitIds[commitIdIdx] : null; // "f37a6863f87a..." or null
```
### testInfo
diff --git a/testing/timings/fetch-xpcshell-data.js b/testing/timings/fetch-xpcshell-data.js
@@ -345,6 +345,7 @@ function createDataTables(jobResults) {
messages: [],
crashSignatures: [],
components: [],
+ commitIds: [],
};
// Maps for O(1) string lookups
@@ -358,12 +359,14 @@ function createDataTables(jobResults) {
messages: new Map(),
crashSignatures: new Map(),
components: new Map(),
+ commitIds: new Map(),
};
// Task info maps task ID index to repository and job name indexes
const taskInfo = {
repositoryIds: [],
jobNameIds: [],
+ commitIds: [],
};
// Test info maps test ID index to test path and name indexes
@@ -400,6 +403,9 @@ function createDataTables(jobResults) {
const jobNameId = findStringIndex("jobNames", result.jobName);
const repositoryId = findStringIndex("repositories", result.repository);
+ const commitId = result.commitId
+ ? findStringIndex("commitIds", result.commitId)
+ : null;
for (const timing of result.timings) {
const fullPath = timing.path;
@@ -445,6 +451,7 @@ function createDataTables(jobResults) {
if (taskInfo.repositoryIds[taskIdId] === undefined) {
taskInfo.repositoryIds[taskIdId] = repositoryId;
taskInfo.jobNameIds[taskIdId] = jobNameId;
+ taskInfo.commitIds[taskIdId] = commitId;
}
// Initialize test group if it doesn't exist
@@ -519,6 +526,7 @@ function sortStringTablesByFrequency(dataStructure) {
messages: new Array(tables.messages.length).fill(0),
crashSignatures: new Array(tables.crashSignatures.length).fill(0),
components: new Array(tables.components.length).fill(0),
+ commitIds: new Array(tables.commitIds.length).fill(0),
};
// Count taskInfo references
@@ -532,6 +540,11 @@ function sortStringTablesByFrequency(dataStructure) {
frequencyCounts.repositories[repositoryId]++;
}
}
+ for (const commitId of taskInfo.commitIds) {
+ if (commitId !== null) {
+ frequencyCounts.commitIds[commitId]++;
+ }
+ }
// Count testInfo references
for (const testPathId of testInfo.testPathIds) {
@@ -644,6 +657,7 @@ function sortStringTablesByFrequency(dataStructure) {
const sortedTaskInfo = {
repositoryIds: [],
jobNameIds: [],
+ commitIds: [],
};
for (
@@ -658,6 +672,10 @@ function sortStringTablesByFrequency(dataStructure) {
sortedTaskInfo.jobNameIds[newTaskIdId] = indexMaps.jobNames.get(
taskInfo.jobNameIds[oldTaskIdId]
);
+ sortedTaskInfo.commitIds[newTaskIdId] =
+ taskInfo.commitIds[oldTaskIdId] === null
+ ? null
+ : indexMaps.commitIds.get(taskInfo.commitIds[oldTaskIdId]);
}
// Remap testInfo indices
@@ -1286,6 +1304,7 @@ async function createAggregatedFailuresFile(dates) {
messages: [],
crashSignatures: [],
components: [],
+ commitIds: [],
};
const stringMaps = {
@@ -1298,6 +1317,7 @@ async function createAggregatedFailuresFile(dates) {
messages: new Map(),
crashSignatures: new Map(),
components: new Map(),
+ commitIds: new Map(),
};
function addToMergedTable(tableName, value) {
@@ -1317,6 +1337,7 @@ async function createAggregatedFailuresFile(dates) {
const mergedTaskInfo = {
repositoryIds: [],
jobNameIds: [],
+ commitIds: [],
};
const mergedTestInfo = {
@@ -1403,15 +1424,19 @@ async function createAggregatedFailuresFile(dates) {
const taskIdString = data.tables.taskIds[taskIdId];
const repositoryId = data.taskInfo.repositoryIds[taskIdId];
const jobNameId = data.taskInfo.jobNameIds[taskIdId];
+ const commitId = data.taskInfo.commitIds[taskIdId];
const repository = data.tables.repositories[repositoryId];
const jobName = data.tables.jobNames[jobNameId];
+ const commitIdString =
+ commitId !== null ? data.tables.commitIds[commitId] : null;
const mergedRepositoryId = addToMergedTable(
"repositories",
repository
);
const mergedJobNameId = addToMergedTable("jobNames", jobName);
+ const mergedCommitId = addToMergedTable("commitIds", commitIdString);
const run = {
repositoryId: mergedRepositoryId,
@@ -1431,6 +1456,7 @@ async function createAggregatedFailuresFile(dates) {
if (mergedTaskInfo.repositoryIds[mergedTaskIdId] === undefined) {
mergedTaskInfo.repositoryIds[mergedTaskIdId] = mergedRepositoryId;
mergedTaskInfo.jobNameIds[mergedTaskIdId] = mergedJobNameId;
+ mergedTaskInfo.commitIds[mergedTaskIdId] = mergedCommitId;
}
run.taskIdId = mergedTaskIdId;
diff --git a/testing/timings/profile-worker.js b/testing/timings/profile-worker.js
@@ -374,6 +374,16 @@ async function processJob(job) {
const resourceUsage = extractResourceUsage(profile);
+ // Extract commit ID from profile.meta.sourceURL
+ // Format: "https://hg.mozilla.org/integration/autoland/rev/f37a6863f87aeeb870b16223045ea7614b1ba0a7"
+ let commitId = null;
+ if (profile.meta.sourceURL) {
+ const match = profile.meta.sourceURL.match(/\/rev\/([a-f0-9]+)$/i);
+ if (match) {
+ commitId = match[1];
+ }
+ }
+
// Convert start_time to timestamp in seconds if it's a string
const startTime =
typeof job.start_time === "string"
@@ -388,6 +398,7 @@ async function processJob(job) {
startTime,
timings,
resourceUsage,
+ commitId,
};
}