diff --git a/packages/test/test-end-to-end-tests/src/test/deRehydrateContainerTests.spec.ts b/packages/test/test-end-to-end-tests/src/test/deRehydrateContainerTests.spec.ts index 3481a474e7dc..dcb3954a11c4 100644 --- a/packages/test/test-end-to-end-tests/src/test/deRehydrateContainerTests.spec.ts +++ b/packages/test/test-end-to-end-tests/src/test/deRehydrateContainerTests.spec.ts @@ -30,10 +30,13 @@ import { LoaderContainerTracker, LocalCodeLoader, TestFluidObject, - TestFluidObjectFactory, createDocumentId, + getContainerEntryPointBackCompat, + getDataStoreEntryPointBackCompat, } from "@fluidframework/test-utils/internal"; +import { createDataStoreFactory } from "@fluidframework/runtime-utils/internal"; import * as semver from "semver"; +import { pkgVersion } from "../packageVersion.js"; // eslint-disable-next-line import/no-internal-modules import type { SnapshotWithBlobs } from "../../../../loader/container-loader/lib/serializedStateManager.js"; @@ -197,7 +200,8 @@ describeCompat( async function createDetachedContainerAndGetEntryPoint() { const container: IContainer = await loader.createDetachedContainer(codeDetails); // Get the root dataStore from the detached container. - const defaultDataStore = (await container.getEntryPoint()) as TestFluidObject; + const defaultDataStore = + await getContainerEntryPointBackCompat(container); return { container, defaultDataStore, @@ -205,7 +209,8 @@ describeCompat( } function createTestLoader(): Loader { - const factory: TestFluidObjectFactory = new TestFluidObjectFactory([ + // It's important to use data store runtime of the same version as DDSs! + const factory = new apis.dataRuntime.TestFluidObjectFactory([ [sharedStringId, SharedString.getFactory()], [sharedMapId, SharedMap.getFactory()], [crcId, ConsensusRegisterCollection.getFactory()], @@ -216,8 +221,22 @@ describeCompat( [sparseMatrixId, SparseMatrix.getFactory()], [sharedCounterId, SharedCounter.getFactory()], ]); - const codeLoader = new LocalCodeLoader([[codeDetails, factory]], {}); - const testLoader = new Loader({ + + // This dance is to ensure that we get reasonable version of ContainerRuntime. + // If we do not set IRuntimeFactory property, LocalCodeLoader will use ContainerRuntime from current version + // We only support limited (N/N-1) compatibility for container runtime and data stores, so that will not work. + // Use version supplied by test framework + const defaultFactory = createDataStoreFactory("default", factory); + (defaultFactory as any).IRuntimeFactory = + new apis.containerRuntime.ContainerRuntimeFactoryWithDefaultDataStore({ + defaultFactory, + registryEntries: [[defaultFactory.type, Promise.resolve(defaultFactory)]], + runtimeOptions: {}, + }); + const codeLoader = new LocalCodeLoader([[codeDetails, defaultFactory]], {}); + + // Use Loader supplied by test framework. + const testLoader = new apis.loader.Loader({ urlResolver: provider.urlResolver, documentServiceFactory: provider.documentServiceFactory, codeLoader, @@ -229,7 +248,8 @@ describeCompat( const createPeerDataStore = async (containerRuntime: IContainerRuntimeBase) => { const dataStore = await containerRuntime.createDataStore(["default"]); - const peerDataStore = (await dataStore.entryPoint.get()) as ITestFluidObject; + const peerDataStore = + await getDataStoreEntryPointBackCompat(dataStore); return { peerDataStore, peerDataStoreRuntimeChannel: peerDataStore.channel, @@ -237,7 +257,7 @@ describeCompat( }; async function getDataObjectFromContainer(container: IContainer, key: string) { - const entryPoint = (await container.getEntryPoint()) as TestFluidObject; + const entryPoint = await getContainerEntryPointBackCompat(container); const handle: IFluidHandle | undefined = entryPoint.root.get(key); assert(handle !== undefined, `handle for [${key}] must exist`); return handle.get(); @@ -255,8 +275,16 @@ describeCompat( beforeEach("createLoader", async function () { provider = getTestObjectProvider(); if ( - semver.compare(provider.driver.version, "0.46.0") === -1 && - (provider.driver.type === "routerlicious" || provider.driver.type === "tinylicious") + // These tests use dedicated (same) version loader, container runtime, DDSs. + // Thus there is no value in running more pairs that are essentially exactly the same as other tests. + provider.type === "TestObjectProviderWithVersionedLoad" || + // These tests only work with the latest version of loader - + // they do make certain assumptions that are not valid for older loaders. This check could be relaxed in + // the future. + apis.loader.version !== pkgVersion || + (semver.compare(provider.driver.version, "0.46.0") === -1 && + (provider.driver.type === "routerlicious" || + provider.driver.type === "tinylicious")) ) { this.skip(); } @@ -399,9 +427,9 @@ describeCompat( await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); // Check for default data store - const entryPoint = await container2.getEntryPoint(); - assert.notStrictEqual(entryPoint, undefined, "Component should exist!!"); - const defaultDataStore = entryPoint as TestFluidObject; + const defaultDataStore = + await getContainerEntryPointBackCompat(container2); + assert.notStrictEqual(defaultDataStore, undefined, "Component should exist!!"); // Check for dds const sharedMap = await defaultDataStore.getSharedObject(sharedMapId); @@ -451,9 +479,9 @@ describeCompat( await container2.attach(request); // Check for default data store - const entryPoint = await container2.getEntryPoint(); - assert.notStrictEqual(entryPoint, undefined, "Component should exist!!"); - const defaultDataStore = entryPoint as TestFluidObject; + const defaultDataStore = + await getContainerEntryPointBackCompat(container2); + assert.notStrictEqual(defaultDataStore, undefined, "Component should exist!!"); // Check for dds const sharedMap = await defaultDataStore.getSharedObject(sharedMapId); @@ -502,9 +530,9 @@ describeCompat( } // Check for default data store - const entryPoint = await container1.getEntryPoint(); - assert.notStrictEqual(entryPoint, undefined, "Component should exist!!"); - const defaultDataStore = entryPoint as TestFluidObject; + const defaultDataStore = + await getContainerEntryPointBackCompat(container1); + assert.notStrictEqual(defaultDataStore, undefined, "Component should exist!!"); // Check for dds const sharedMap = await defaultDataStore.getSharedObject(sharedMapId); @@ -548,7 +576,8 @@ describeCompat( const { container } = await createDetachedContainerAndGetEntryPoint(); const snapshotTree = container.serialize(); - const defaultDataStore = (await container.getEntryPoint()) as TestFluidObject; + const defaultDataStore = + await getContainerEntryPointBackCompat(container); assert( defaultDataStore.context.storage !== undefined, "Storage should be present in detached data store", @@ -564,7 +593,8 @@ describeCompat( const container2: IContainer = await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); - const defaultDataStore2 = (await container2.getEntryPoint()) as TestFluidObject; + const defaultDataStore2 = + await getContainerEntryPointBackCompat(container2); assert( defaultDataStore2.context.storage !== undefined, "Storage should be present in rehydrated data store", @@ -582,7 +612,8 @@ describeCompat( it("Change contents of dds, then rehydrate and then check summary", async () => { const { container } = await createDetachedContainerAndGetEntryPoint(); - const defaultDataStoreBefore = (await container.getEntryPoint()) as TestFluidObject; + const defaultDataStoreBefore = + await getContainerEntryPointBackCompat(container); const sharedStringBefore = await defaultDataStoreBefore.getSharedObject(sharedStringId); const intervalsBefore = sharedStringBefore.getIntervalCollection("intervals"); @@ -651,7 +682,8 @@ describeCompat( const container2 = await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); - const defaultComponentAfter = (await container2.getEntryPoint()) as TestFluidObject; + const defaultComponentAfter = + await getContainerEntryPointBackCompat(container2); const sharedStringAfter = await defaultComponentAfter.getSharedObject(sharedStringId); const intervalsAfter = sharedStringAfter.getIntervalCollection("intervals"); @@ -703,7 +735,8 @@ describeCompat( it("Rehydrate container from summary, change contents of dds and then check summary", async () => { const { container } = await createDetachedContainerAndGetEntryPoint(); let str = "AA"; - const defaultComponent1 = (await container.getEntryPoint()) as TestFluidObject; + const defaultComponent1 = + await getContainerEntryPointBackCompat(container); const sharedString1 = await defaultComponent1.getSharedObject(sharedStringId); sharedString1.insertText(0, str); @@ -712,7 +745,7 @@ describeCompat( const container2 = await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); const defaultDataStoreBefore = - (await container2.getEntryPoint()) as TestFluidObject; + await getContainerEntryPointBackCompat(container2); const sharedStringBefore = await defaultDataStoreBefore.getSharedObject(sharedStringId); const sharedMapBefore = @@ -722,7 +755,8 @@ describeCompat( sharedMapBefore.set("0", str); await container2.attach(request); - const defaultComponentAfter = (await container.getEntryPoint()) as TestFluidObject; + const defaultComponentAfter = + await getContainerEntryPointBackCompat(container); const sharedStringAfter = await defaultComponentAfter.getSharedObject(sharedStringId); const sharedMapAfter = @@ -879,7 +913,7 @@ describeCompat( await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); const rehydratedEntryPoint = - (await rehydratedContainer.getEntryPoint()) as TestFluidObject; + await getContainerEntryPointBackCompat(rehydratedContainer); const rehydratedRootOfDataStore = await rehydratedEntryPoint.getSharedObject(sharedMapId); const dataStore2Handle: IFluidHandle | undefined = @@ -915,7 +949,7 @@ describeCompat( await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); const rehydratedEntryPoint = - (await rehydratedContainer.getEntryPoint()) as TestFluidObject; + await getContainerEntryPointBackCompat(rehydratedContainer); const rootOfDds2 = await rehydratedEntryPoint.getSharedObject(sharedMapId); const dds2Handle: IFluidHandle | undefined = rootOfDds2.get(dds2Key); @@ -958,7 +992,9 @@ describeCompat( await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); const rehydratedEntryPoint = - (await rehydratedContainer.getEntryPoint()) as TestFluidObject; + await getContainerEntryPointBackCompat( + rehydratedContainer, + ); const rootOfDds2 = await rehydratedEntryPoint.getSharedObject(sharedMapId); const dds2Handle: IFluidHandle | undefined = @@ -1020,7 +1056,9 @@ describeCompat( await loader.rehydrateDetachedContainerFromSnapshot(snapshotTree); const rehydratedEntryPoint = - (await rehydratedContainer.getEntryPoint()) as TestFluidObject; + await getContainerEntryPointBackCompat( + rehydratedContainer, + ); const rehydratedRootOfDataStore2 = await rehydratedEntryPoint.getSharedObject(sharedMapId); const dataStore2Handle: IFluidHandle | undefined =