Skip to content

improvement(test-version-utils): Automatically set minVersionForCollab in e2e test generation #24809

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 59 additions & 113 deletions packages/test/test-version-utils/src/compatUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,7 @@ import {
type RouterliciousEndpoint,
} from "@fluid-internal/test-driver-definitions";
import { FluidTestDriverConfig, createFluidTestDriver } from "@fluid-private/test-drivers";
import {
DefaultSummaryConfiguration,
CompressionAlgorithms,
disabledCompressionConfig,
ICompressionRuntimeOptions,
type IContainerRuntimeOptionsInternal,
} from "@fluidframework/container-runtime/internal";
import type { MinimumVersionForCollab } from "@fluidframework/container-runtime/internal";
import { FluidObject, IFluidLoadable, IRequest } from "@fluidframework/core-interfaces";
import { IFluidHandleContext } from "@fluidframework/core-interfaces/internal";
import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
Expand Down Expand Up @@ -56,98 +50,50 @@ import { getRequestedVersion } from "./versionUtils.js";
export const TestDataObjectType = "@fluid-example/test-dataStore";

/**
* This function modifies container runtime options according to a version of runtime used.
* If a version of runtime does not support some options, they are removed.
* If a version runtime supports some options, such options are enabled to increase a chance of
* hitting feature set controlled by such options, and thus increase chances of finding product bugs.
* Determines the MinimumVersionForCollab that should be used for cross-client compatibility tests.
*
* @param version - a version of container runtime to be used in test
* @param optionsArg - input runtime options (optional)
* @returns - runtime options that should be used with a given version of container runtime
* @internal
* In cross-client compat tests, a different version of the runtime is being used to create and load
* containers. The MinimumVersionForCollab returned will be the lesser of the two versions:
* - runtimeVersion: The version of the runtime that is being used to create the container.
* - runtimeVersionForLoading: The version of the runtime that is being used to load the container.
* Additionally, runtimeVersionForLoading is only defined in cross-client compat tests, so if it's undefined
* we will just use runtimeVersion.
*
* Note: The MinimumVersionForCollab returned will only be used if a minVersionForCollab was not provided
* in the ITestContainerConfig object.
*
* For example, if we are running a cross-client compat test with the following versions:
* - runtimeVersion: "2.42.0"
* - runtimeVersionForLoading: "1.4.0"
* We will return "1.4.0" since it's the lower of the two versions.
*/
function filterRuntimeOptionsForVersion(
version: string,
optionsArg: IContainerRuntimeOptionsInternal = {
summaryOptions: {
summaryConfigOverrides: {
...DefaultSummaryConfiguration,
...{
initialSummarizerDelayMs: 0,
},
},
},
},
driverType: TestDriverTypes,
) {
let options = { ...optionsArg };

// No test fails with this option, it allows us to validate properly expectations and
// implementation of services
options.loadSequenceNumberVerification = "close";

const compressorDisabled: ICompressionRuntimeOptions = {
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
compressionAlgorithm: CompressionAlgorithms.lz4,
};

// These is the "maximum" config.
const {
compressionOptions = options.enableGroupedBatching === false
? disabledCompressionConfig
: {
minimumBatchSizeInBytes: 200,
compressionAlgorithm: CompressionAlgorithms.lz4,
},
enableGroupedBatching = true,
enableRuntimeIdCompressor = "on",
// Some t9s tests timeout with small settings. This is likely due to too many ops going through.
// Reduce chunking cut-off for such tests.
chunkSizeInBytes = driverType === "local" ? 200 : 1000,
} = options;

if (version.startsWith("1.")) {
options = {
// None of these features are supported by 1.3
compressionOptions: disabledCompressionConfig,
enableGroupedBatching: false,
enableRuntimeIdCompressor: undefined,
// Enable chunking.
// We need to ensure that 1.x documents (that use chunking) can still be opened by 2.x.
// This options does nothing for 2.x builds as chunking is only enabled if compression is enabled.
chunkSizeInBytes,
...options,
};
} else if (version.startsWith("2.0.0-rc.1.")) {
options = {
compressionOptions: compressorDisabled, // Can't use compression, need https://github.com/microsoft/FluidFramework/pull/20111 fix
enableGroupedBatching,
enableRuntimeIdCompressor: undefined, // it was boolean in RC1, switched to enum in RC2
chunkSizeInBytes: Number.POSITIVE_INFINITY, // disabled, need https://github.com/microsoft/FluidFramework/pull/20115 fix
...options,
};
} else if (version.startsWith("2.0.0-rc.2.")) {
options = {
compressionOptions: compressorDisabled, // Can't use compression, need https://github.com/microsoft/FluidFramework/pull/20111 fix
enableGroupedBatching,
// control over schema was generalized in RC3 - see https://github.com/microsoft/FluidFramework/pull/20174
// IdCompressor settings moved around - can't enable them across versions without tripping on asserts
enableRuntimeIdCompressor: undefined,
chunkSizeInBytes: Number.POSITIVE_INFINITY, // disabled, need https://github.com/microsoft/FluidFramework/pull/20115 fix
...options,
};
} else {
// "2.0.0-rc.3." ++
options = {
compressionOptions,
enableGroupedBatching,
chunkSizeInBytes,
enableRuntimeIdCompressor,
...options,
};
function getMinVersionForCollab(
runtimeVersion: string,
runtimeVersionForLoading: string | undefined,
): MinimumVersionForCollab {
assertValidMinVersionForCollab(runtimeVersion);
if (runtimeVersionForLoading === undefined) {
// If `containerRuntimeForLoading` is not defined, then this is not a cross-client compat scenario.
// In this case, we can use the `runtimeVersion` as the default minVersionForCollab.
return runtimeVersion;
}
assertValidMinVersionForCollab(runtimeVersionForLoading);
// If `containerRuntimeForLoading` is defined, we will use the lower of the two versions to ensure
// compatibility between the two runtimes.
return semver.compare(runtimeVersion, runtimeVersionForLoading) <= 0
? runtimeVersion
: runtimeVersionForLoading;
}

return options;
/**
* Asserts the given version is valid semver and is type MinimumVersionForCollab.
*/
function assertValidMinVersionForCollab(
version: string,
): asserts version is MinimumVersionForCollab {
if (semver.valid(version) === null) {
throw new Error(`Runtime version must be valid semver: ${version}`);
}
}

/**
Expand Down Expand Up @@ -250,12 +196,12 @@ export async function getVersionedTestObjectProviderFromApis(
return new factoryCtor(
TestDataObjectType,
dataStoreFactory,
filterRuntimeOptionsForVersion(
apis.containerRuntime.version,
containerOptions?.runtimeOptions,
type,
),
containerOptions?.minVersionForCollab,
containerOptions?.runtimeOptions,
containerOptions?.minVersionForCollab ??
getMinVersionForCollab(
apis.containerRuntime.version,
apis.containerRuntimeForLoading?.version,
),
);
};

Expand Down Expand Up @@ -363,12 +309,12 @@ export async function getCompatVersionedTestObjectProviderFromApis(
return new factoryCtor(
TestDataObjectType,
dataStoreFactory,
filterRuntimeOptionsForVersion(
minVersion,
containerOptions?.runtimeOptions,
driverConfig.type,
),
containerOptions?.minVersionForCollab,
containerOptions?.runtimeOptions,
containerOptions?.minVersionForCollab ??
getMinVersionForCollab(
apis.containerRuntime.version,
apis.containerRuntimeForLoading?.version,
),
[innerRequestHandler],
);
};
Expand All @@ -388,12 +334,12 @@ export async function getCompatVersionedTestObjectProviderFromApis(
return new factoryCtor(
TestDataObjectType,
dataStoreFactory,
filterRuntimeOptionsForVersion(
minVersion,
containerOptions?.runtimeOptions,
driverConfig.type,
),
containerOptions?.minVersionForCollab,
containerOptions?.runtimeOptions,
containerOptions?.minVersionForCollab ??
getMinVersionForCollab(
apis.containerRuntime.version,
apis.containerRuntimeForLoading.version,
),
[innerRequestHandler],
);
};
Expand Down
Loading