tree: Add integration-style tests for loading old summary versions#27105
tree: Add integration-style tests for loading old summary versions#27105jzaffiro wants to merge 8 commits intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an integration-style regression test to ensure current SharedTree code can load summaries written using older minVersionForCollab settings, across compressed/uncompressed tree encoding strategies.
Changes:
- Introduces
summaryLoad.integration.tsto generate per-version summaries and attempt loading them with the current version configuration. - Covers multiple
FluidClientVersionkeys and bothTreeCompressionStrategy.CompressedandTreeCompressionStrategy.Uncompressed.
| describe("Summary load regression tests", () => { | ||
| before(async () => { | ||
| await generateOldSummaries(); | ||
| }); |
There was a problem hiding this comment.
These tests generate the “old” summary files at runtime (in the before hook) using the same code under test. This can mask real regressions because both the writer and reader evolve together, so you’re not actually validating compatibility with summaries produced by prior releases. Consider loading from checked-in fixtures (or snapshots generated once under a --snapshot/regen mode) so the test exercises genuinely historical serialized data.
There was a problem hiding this comment.
Addressed by committing snapshot files and adding a regenerate mode separate from the normal test flow
| async function generateOldSummaries(): Promise<void> { | ||
| // Clean and recreate the output directory each run | ||
| rmSync(outputDir, { recursive: true, force: true }); | ||
|
|
There was a problem hiding this comment.
This test unconditionally deletes and rewrites a directory under src/test (rmSync(outputDir, ...) + writeFileSync(...)). That means a normal test run mutates the working tree (and could delete any checked-in files placed under that directory). Prefer either writing to a per-run temp directory and cleaning it up, or using the existing snapshot infrastructure which only updates files when explicitly regenerating snapshots.
There was a problem hiding this comment.
Addressed by committing snapshot files and adding a regenerate mode separate from the normal test flow
| MockSharedObjectServices.createFromSummary(JSON.parse(summaryJson)), | ||
| stFactory.attributes, | ||
| ); | ||
| assert(tree !== undefined, "Loaded tree should not be undefined"); |
There was a problem hiding this comment.
The only assertion is tree !== undefined, but stFactory.load(...) returns a non-optional value, so this doesn’t meaningfully validate that the summary was interpreted correctly. To make this a stronger regression test, assert on the loaded content (e.g., read a view and verify label and the child array values) so semantic decode issues are caught.
| assert(tree !== undefined, "Loaded tree should not be undefined"); | |
| const view = tree.viewWith(new TreeViewConfiguration({ schema: TestSchema })); | |
| assert.equal(view.root.label, "foo"); | |
| assert.deepEqual( | |
| Array.from(view.root.child, (child) => child.count), | |
| [1, 2], | |
| ); |
There was a problem hiding this comment.
Updated and added a comment to fix assertions if summary content generation is updated.
| console.log(`removing snapshot directory: ${outputDir}`); | ||
| rmSync(outputDir, { recursive: true, force: true }); | ||
| } | ||
| mkdirSync(outputDir, { recursive: true }); |
There was a problem hiding this comment.
I don't think we ever want to remove or update these files. We should only ever add additional variants, since we need to support loading old summaries, even if we don't generate them like that anymore.
So instead of "regenerateOldSummaries" I think we want something like "checkForMissingSummaries(addIfMissing: boolean)"
Rather than deleting all the summaries, it can load all of them (the string contents of the files) into a Set<string>.
Then when we loop through all the summaries we could generate, generate the string we would save to a file.
Then check if that string is in the set: if its not, push it into an array of missing summaries.
Then after the loop, if the array of missing summaries is not empty:
If addIfMissing is false: report an error listing all the ones which are missing.
If addIfMissing is true: write them all to disk with non-colliding names.
To help with the non-colliding names we can include a -1 at the end of each file name, and increment that number if the file already exists.
There was a problem hiding this comment.
Note that once we do this, it should run as a test, and not the before hook.
There was a problem hiding this comment.
Committed summary files and runs a "checkForMissingSummaries" test in addition to the load tests for each summary file in the directory.
|
🔗 No broken links found! ✅ Your attention to detail is admirable. linkcheck output |
Prevent any future bugs for loading old summaries in newer versions of the code by adding tests for that case.
AB#59669