diff --git a/ab-testing/config/abTests.ts b/ab-testing/config/abTests.ts index fdd4d4d0a77..6f33a56b7a4 100644 --- a/ab-testing/config/abTests.ts +++ b/ab-testing/config/abTests.ts @@ -209,7 +209,6 @@ const ABTests: ABTest[] = [ groups: ["a", "b"], shouldForceMetricsCollection: false, }, - { name: "commercial-prebid-failsafe-timeout", description: @@ -223,6 +222,30 @@ const ABTests: ABTest[] = [ groups: ["control", "variant"], shouldForceMetricsCollection: true, }, + { + name: "webx-test-test", + description: "Test for webx test", + owners: ["dotcom.platform@theguardian.com"], + status: "ON", + expirationDate: "2026-08-31", + type: "client", + audienceSize: 10 / 100, + audienceSpace: "D", + groups: ["control", "variant"], + shouldForceMetricsCollection: false, + }, + { + name: "webx-test-test-2", + description: "Test for webx test", + owners: ["dotcom.platform@theguardian.com"], + status: "ON", + expirationDate: "2026-08-31", + type: "client", + audienceSize: 50 / 100, + audienceSpace: "E", + groups: ["control", "variant"], + shouldForceMetricsCollection: false, + }, ]; const activeABtests = ABTests.filter((test) => test.status === "ON"); diff --git a/ab-testing/config/lib/types.ts b/ab-testing/config/lib/types.ts index 88eadb1e8a5..558a9b950ab 100644 --- a/ab-testing/config/lib/types.ts +++ b/ab-testing/config/lib/types.ts @@ -1,6 +1,6 @@ type FastlyTestParams = { name: string; type: string; exp: number }; type AudienceSpace = Map; -type AllSpace = Map; +type AllSpaces = Map; -export type { FastlyTestParams, AudienceSpace, AllSpace }; +export type { FastlyTestParams, AudienceSpace, AllSpaces as AllSpace }; diff --git a/ab-testing/config/scripts/build/calculate-mvt-updates.ts b/ab-testing/config/scripts/build/calculate-mvt-updates.ts index c99fcd1497f..bb5b3ccba9a 100644 --- a/ab-testing/config/scripts/build/calculate-mvt-updates.ts +++ b/ab-testing/config/scripts/build/calculate-mvt-updates.ts @@ -104,7 +104,7 @@ const calculateAllSpaceUpdates = ( mvtGroups: AllSpace, tests: ABTest[], ): AllSpace => { - const updatedTestSpace: AudienceSpace[] = AudienceSpaces.map((space, i) => { + const updatedTestSpaces: AudienceSpace[] = AudienceSpaces.map((space) => { console.log(`Calculating updates for space: ${space}`); const spaceTests = tests.filter( (test) => (test.audienceSpace ?? "A") === space, // 'A' is the default space @@ -116,15 +116,24 @@ const calculateAllSpaceUpdates = ( } const spaceMVTGroups = new Map( - mvtGroups - .entries() - .map(([key, value]) => [key, value[i] as FastlyTestParams]), + Array.from(mvtGroups.entries()) + .map(([mvtId, tests]) => [ + mvtId, + spaceTests.find((test) => + tests.find( + (t) => t.name === test.name && t.type === test.type, + ), + ), + ]) + .filter(([, test]) => test !== undefined) as Array< + [string, FastlyTestParams] + >, ); return calculateSpaceUpdates(spaceMVTGroups, spaceTests); }); - return updatedTestSpace.reduce((acc, curr) => { + return updatedTestSpaces.reduce((acc, curr) => { curr.forEach((value, key) => { if (!acc.has(key)) { acc.set(key, []); diff --git a/ab-testing/config/scripts/build/test-group-mvt-manager.ts b/ab-testing/config/scripts/build/test-group-mvt-manager.ts index 0a5c7e461ec..8109fcedb86 100644 --- a/ab-testing/config/scripts/build/test-group-mvt-manager.ts +++ b/ab-testing/config/scripts/build/test-group-mvt-manager.ts @@ -47,9 +47,13 @@ class TestGroupMVTManager { Array.from(this.testGroups.values()).flat(), ); + /** + * collect all available MVTs that are not currently occupied in a random order + * so that new test mvts are assigned randomly. + */ this.availableMVTs = Array.from({ length: MVT_COUNT }, (_, i) => i) .filter((i) => !this.occupiedMVTs.has(i)) - .sort((a, b) => a - b); + .sort(() => Math.random() - 0.5); console.log( `Initialized TestGroupMVTs with ${this.availableMVTs.length} available MVTs`, @@ -109,11 +113,14 @@ class TestGroupMVTManager { throw new Error(`Not enough available MVTs for test ${name}`); } for (let i = 0; i < additionalMVTsNeeded; i++) { - const mvtIndex = this.availableMVTs.shift(); - if (mvtIndex !== undefined) { - currentMVTs.push(mvtIndex); - this.occupiedMVTs.add(mvtIndex); + const mvtId = this.availableMVTs.shift(); + if (mvtId === undefined) { + throw new Error( + `No available MVTs left to expand test ${name}`, + ); } + currentMVTs.push(mvtId); + this.occupiedMVTs.add(mvtId); } } else if (newSize < currentSize) { const removedMVTs = currentMVTs.slice(newSize); @@ -122,8 +129,6 @@ class TestGroupMVTManager { this.availableMVTs.push(mvt); }); currentMVTs.length = newSize; - // Keep available MVTs sorted in ascending order - this.availableMVTs.sort((a, b) => a - b); } this.testGroups.set(name, currentMVTs); } @@ -140,8 +145,6 @@ class TestGroupMVTManager { this.availableMVTs.push(mvt); }); this.testGroups.delete(name); - // Keep available MVTs sorted in ascending order - this.availableMVTs.sort((a, b) => a - b); } } }