[AB testing PoC] calculate ab test MVTs without manual offset#14286
[AB testing PoC] calculate ab test MVTs without manual offset#14286Jakeii merged 11 commits intocommercial/ab-testing-pocfrom
Conversation
b4ad08f to
46a5cf9
Compare
| "validate": "deno run scripts/validation/index.ts", | ||
| "upload": "deno run --allow-read=dist --allow-env=FASTLY_AB_TESTING_API_TOKEN,FASTLY_AB_TESTING_SERVICE_ID,FASTLY_AB_TESTING_SERVICE_NAME,FASTLY_MVTS_DICTIONARY_ID,FASTLY_MVTS_DICTIONARY_NAME,FASTLY_AB_TESTS_DICTIONARY_ID,FASTLY_AB_TESTS_DICTIONARY_NAME --allow-net=api.fastly.com:443 scripts/deploy/index.ts --mvts=dist/mvts.json --ab-tests=dist/ab-tests.json", | ||
| "build": "deno run --allow-write scripts/build/index.ts --mvts=dist/mvts.json --ab-tests=dist/ab-tests.json" | ||
| "build": "deno run --allow-env=FASTLY_AB_TESTING_API_TOKEN,FASTLY_AB_TESTING_SERVICE_ID,FASTLY_AB_TESTING_SERVICE_NAME,FASTLY_MVTS_DICTIONARY_ID,FASTLY_MVTS_DICTIONARY_NAME,FASTLY_AB_TESTS_DICTIONARY_ID,FASTLY_AB_TESTS_DICTIONARY_NAME --allow-net=api.fastly.com:443 --allow-write scripts/build/index.ts --mvts=dist/mvts.json --ab-tests=dist/ab-tests.json" |
There was a problem hiding this comment.
Build step now needs to read the AB testing state from fastly
|
Hello 👋! When you're ready to run Chromatic, please apply the You will need to reapply the label each time you want to run Chromatic. |
There was a problem hiding this comment.
Pull Request Overview
This PR removes the manual audienceOffset requirement from A/B tests and implements an automatic MVT (multivariate test) allocation system that preserves existing test positions while optimizing space usage.
- Removes
audienceOffsetfield from ABTest type and replaces manual offset management with automatic allocation - Introduces a new TestGroupMVTManager class to handle MVT allocation, resizing, and deallocation
- Refactors the MVT dictionary building process to use existing Fastly dictionary state as the source of truth
Reviewed Changes
Copilot reviewed 25 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ab-testing/types.ts | Removes audienceOffset field from ABTest interface |
| ab-testing/scripts/validation/variantOverlap.ts | Removes entire overlap validation module (no longer needed) |
| ab-testing/scripts/validation/validSizeOffset.ts | Removes size/offset validation module |
| ab-testing/scripts/build/test-group-mvt-manager.ts | New class for managing MVT allocation and test group lifecycle |
| ab-testing/scripts/build/calculate-mvt-updates.ts | New module for calculating MVT updates across audience spaces |
| ab-testing/scripts/lib/ | New shared utilities for constants, types, and Fastly subfield parsing |
| ab-testing/scripts/build/index.ts | Updates build process to fetch existing MVT state and use new allocation system |
| ab-testing/abTest.ts | Removes audienceOffset and highImpact fields from example tests |
| string, | ||
| { name: string; type: string; exp: number } | ||
| > = new Map( | ||
| mvtGroups.entries().map(([key, value]) => [key, value[i]]), |
There was a problem hiding this comment.
Map.entries() returns a MapIterator, not an array. This should be Array.from(mvtGroups.entries()).map(...) to properly convert to an array before calling map().
| mvtGroups.entries().map(([key, value]) => [key, value[i]]), | |
| Array.from(mvtGroups.entries()).map(([key, value]) => [key, value[i]]), |
There was a problem hiding this comment.
The AI is flagging that the result of mvtGroups.entries() cannot be iterated over using a .map, I asked it to generate a TypeScript playground snippet to demonstrate how to iterate over the result of .entries() which we can see here. So this snippet has a compiler error and fails to run, but this isn't an issue we've come across via our tests or with the compiler. 🤔
There was a problem hiding this comment.
Copilot must think we're targeting an older ES version? If you change the target to ESNext the error goes away
There was a problem hiding this comment.
Ok interesting, we should record this and provide feedback, all the issues it's flagged look to be the same kind of issue.
cemms1
left a comment
There was a problem hiding this comment.
I got halfway through reviewing this but then stopped and forgot to continue. I might suggest this PR is slightly too large to give a good PR review here and in an ideal world, this would have been split into a couple of PRs to make it a bit easier for reviewing.
I'll finish my review soon but leaving the comments before I forget!
Co-authored-by: Charlotte Emms <43961396+cemms1@users.noreply.github.com>
If you have a suggestion of how I could break it up, happy to do so! There were a couple of small things like removing the |
| const stringifyMVTValue = (array: FastlyTestParams[]): string => { | ||
| const subfield: Record<string, string> = {}; | ||
| array.forEach((item, index) => { | ||
| subfield[`group:${index}`] = item.name; | ||
| subfield[`group:${index}:type`] = item.type; | ||
| subfield[`group:${index}:exp`] = String(item.exp); | ||
| }); | ||
| return stringifyFastlySubfield(subfield); | ||
| }; |
There was a problem hiding this comment.
A test would help to better illustrate what is happening here
What does this change?
This does away with manual test offset, and now looks at the existing state of the tests in the mvt dictionary when building the key values for the current
ab-tests.ts, ensuring any existing tests "stay where they are" within the test space.It does the following
This does means that tests will not use contiguous ranges of MVT IDs anymore, but MVTs are random so this doesn't affect the behaviour of test allocation.
Why?
At the moment tests need to specify their
audienceOffset, which is where in the mvt space to position the test, this meant that developers wanting to add tests have to check all existing tests and work out what value they need to use for any new tests.The reason for it's existence was to avoid tests "moving around" to different mvts, changing the users who are in the test while it's in progress.