Skip to content
Merged
Show file tree
Hide file tree
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
5 changes: 3 additions & 2 deletions src/browser/cdp/selectivity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getCollectedTestplaneDependencies } from "./testplane-selectivity";
import { getHashReader } from "./hash-reader";
import type { Config } from "../../../config";
import { MasterEvents } from "../../../events";
import { selectivityShouldWrite } from "./modes";

type StopSelectivityFn = (test: Test, shouldWrite: boolean) => Promise<void>;

Expand All @@ -24,7 +25,7 @@ export const updateSelectivityHashes = async (config: Config): Promise<void> =>
const browserConfig = config.forBrowser(browserId);
const { enabled, testDependenciesPath, compression, disableSelectivityPatterns } = browserConfig.selectivity;

if (!enabled) {
if (!selectivityShouldWrite(enabled)) {
continue;
}

Expand All @@ -51,7 +52,7 @@ export const startSelectivity = async (browser: ExistingBrowser): Promise<StopSe
const { enabled, compression, sourceRoot, testDependenciesPath, mapDependencyRelativePath } =
browser.config.selectivity;

if (!enabled || !browser.publicAPI.isChromium) {
if (!selectivityShouldWrite(enabled) || !browser.publicAPI.isChromium) {
return () => Promise.resolve();
}

Expand Down
7 changes: 7 additions & 0 deletions src/browser/cdp/selectivity/modes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SelectivityMode, type SelectivityModeValue } from "../../../config/types";

export const selectivityIsDisabled = (mode: SelectivityModeValue): boolean => mode === SelectivityMode.Disabled;
export const selectivityShouldWrite = (mode: SelectivityModeValue): boolean =>
mode === SelectivityMode.Enabled || mode === SelectivityMode.WriteOnly;
export const selectivityShouldRead = (mode: SelectivityModeValue): boolean =>
mode === SelectivityMode.Enabled || mode === SelectivityMode.ReadOnly;
22 changes: 14 additions & 8 deletions src/browser/cdp/selectivity/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import type { Test, TestDepsContext, TestDepsData } from "../../../types";
import { MasterEvents } from "../../../events";
import { getHashWriter } from "./hash-writer";
import { getTestDependenciesReader } from "./test-dependencies-reader";
import { selectivityShouldRead } from "./modes";

/** Called at the start of testplane run per each browser */
const shouldDisableBrowserSelectivity = _.memoize(
async (config: BrowserConfig, browserId: string): Promise<boolean> => {
if (!config.selectivity.enabled) {
if (!selectivityShouldRead(config.selectivity.enabled)) {
return true;
}

Expand Down Expand Up @@ -60,8 +61,9 @@ const shouldDisableBrowserSelectivity = _.memoize(
},
config => {
const { enabled, testDependenciesPath, compression, disableSelectivityPatterns } = config.selectivity;
return enabled
? enabled + "#" + testDependenciesPath + "#" + compression + "#" + disableSelectivityPatterns.join("#")

return selectivityShouldRead(enabled)
? testDependenciesPath + "#" + compression + "#" + disableSelectivityPatterns.join("#")
: "";
},
);
Expand All @@ -70,7 +72,7 @@ const shouldDisableTestBySelectivity = _.memoize(
async (config: BrowserConfig, test: Test): Promise<boolean> => {
const { enabled, testDependenciesPath, compression } = config.selectivity;

if (!enabled) {
if (!selectivityShouldRead(enabled)) {
return false;
}

Expand Down Expand Up @@ -99,7 +101,7 @@ const shouldDisableTestBySelectivity = _.memoize(
(config, test) => {
const { enabled, testDependenciesPath, compression } = config.selectivity;

return enabled ? enabled + "#" + testDependenciesPath + "#" + compression + "#" + test.id : "";
return selectivityShouldRead(enabled) ? testDependenciesPath + "#" + compression + "#" + test.id : "";
},
);

Expand Down Expand Up @@ -157,11 +159,11 @@ export class SelectivityRunner {

startTestCheckToRun(test: Test, browserId: string): void {
const browserConfig = this._config.forBrowser(browserId);
const isSelectivityEnabledForBrowser = browserConfig.selectivity.enabled;
const shouldSelectivelySkipTests = selectivityShouldRead(browserConfig.selectivity.enabled);

// If selectivity is disabled for browser
// If test is disabled on its own (e.g plugin testplane/chunks) we dont waste our time calculating the deps.
if (!isSelectivityEnabledForBrowser || this._opts?.shouldDisableSelectivity || test.disabled) {
if (!shouldSelectivelySkipTests || this._opts?.shouldDisableSelectivity || test.disabled) {
this._testsToRun.push([test, browserId]);
return;
}
Expand Down Expand Up @@ -197,6 +199,10 @@ export class SelectivityRunner {

shouldDisableBrowserSelectivity.cache.clear?.();
shouldDisableTestBySelectivity.cache.clear?.();
getHashReader(this._config.selectivity.testDependenciesPath, this._config.selectivity.compression).clearCache();
this._config.getBrowserIds().forEach(browserId => {
const { selectivity } = this._config.forBrowser(browserId);

getHashReader(selectivity.testDependenciesPath, selectivity.compression).clearCache();
});
}
}
23 changes: 18 additions & 5 deletions src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,16 +268,29 @@ type ReadinessProbeObj = {
type ReadinessProbe = ReadinessProbeFn | ReadinessProbeObj;

export enum TimeTravelMode {
// Record and save all test runs
/** @description Record and save all test runs */
On = "on",
// Do not record any test runs
/** @description Do not record any test runs */
Off = "off",
// Record and save all retries
/** @description Record and save all retries */
RetriesOnly = "retries-only",
// Record all test runs, but save only last failed run
/** @description Record all test runs, but save only last failed run */
LastFailedRun = "last-failed-run",
}

export const SelectivityMode = {
/** @description Completely disables Testplane selectivity */
Disabled: false,
/** @description Skips running unchanged tests, does not update selectivity state after successful run */
ReadOnly: "read-only",
/** @description Runs unchanged tests, updates selectivity state after successful run */
WriteOnly: "write-only",
/** @description Skips running unchanged tests, updates selectivity state after successful run */
Enabled: true,
} as const;

export type SelectivityModeValue = (typeof SelectivityMode)[keyof typeof SelectivityMode];

export interface TimeTravelConfig {
mode: TimeTravelMode;
}
Expand Down Expand Up @@ -392,7 +405,7 @@ export interface CommonConfig {
};

selectivity: {
enabled: boolean;
enabled: SelectivityModeValue;
sourceRoot: string;
testDependenciesPath: string;
compression: SelectivityCompressionType;
Expand Down
21 changes: 13 additions & 8 deletions src/config/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from "lodash";
import { ConfigParsed } from "./types";
import { ConfigParsed, SelectivityMode, SelectivityModeValue } from "./types";

type ValueType = "string" | "number" | "boolean" | "object" | "undefined" | "function";

Expand Down Expand Up @@ -100,16 +100,21 @@ export const addUserAgentToArgs = (config: ConfigParsed): ConfigParsed => {
return config;
};

export const extractSelectivityEnabledEnvVariable = (envPrefixes: string[] = []): { enabled?: boolean } => {
export const extractSelectivityEnabledEnvVariable = (
envPrefixes: string[] = [],
): { enabled?: SelectivityModeValue } => {
for (const envPrefix of envPrefixes) {
const envName = envPrefix + "selectivity_enabled";

if (process.env[envName] === String(true)) {
return { enabled: true };
}

if (process.env[envName] === String(false)) {
return { enabled: false };
switch (process.env[envName]) {
case String(SelectivityMode.Enabled):
return { enabled: SelectivityMode.Enabled };
case String(SelectivityMode.Disabled):
return { enabled: SelectivityMode.Disabled };
case String(SelectivityMode.ReadOnly):
return { enabled: SelectivityMode.ReadOnly };
case String(SelectivityMode.WriteOnly):
return { enabled: SelectivityMode.WriteOnly };
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/worker/runner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const {
} = require("../../browser/cdp/selectivity/testplane-selectivity");
const ipc = require("../../utils/ipc");
const { TEST_ASSIGNED_TO_WORKER } = require("../../constants/process-messages");
const { selectivityShouldWrite } = require("../../browser/cdp/selectivity/modes");

module.exports = class Runner extends AsyncEmitter {
static create(config) {
Expand Down Expand Up @@ -55,13 +56,14 @@ module.exports = class Runner extends AsyncEmitter {
attempt,
});

const selectivityEnabled = config.selectivity && config.selectivity.enabled && isRunInNodeJsEnv(this._config);
const shouldRecordSelectivityDeps =
config.selectivity && selectivityShouldWrite(config.selectivity.enabled) && isRunInNodeJsEnv(this._config);

const prepareParseAndRun = async () => {
runner.prepareBrowser({ sessionId, sessionCaps, sessionOpts, state });

const readTestsFn = () => this._testParser.parse({ file, browserId });
const tests = selectivityEnabled
const tests = shouldRecordSelectivityDeps
? await readTestFileWithTestplaneDependenciesCollecting(file, readTestsFn)
: await readTestsFn();

Expand All @@ -72,6 +74,8 @@ module.exports = class Runner extends AsyncEmitter {
return runner.run();
};

return selectivityEnabled ? runWithTestplaneDependenciesCollecting(prepareParseAndRun) : prepareParseAndRun();
return shouldRecordSelectivityDeps
? runWithTestplaneDependenciesCollecting(prepareParseAndRun)
: prepareParseAndRun();
}
};
1 change: 0 additions & 1 deletion test/src/browser/cdp/selectivity/hash-reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ describe("CDP/Selectivity/HashReader", () => {
const result = reader.patternHasChanged(pattern);

assert.isRejected(result, /Couldn't find files by disableSelectivityPattern/);
assert.calledWith(hashProviderMock.calculateForPattern, pattern);
});
});

Expand Down
Loading
Loading