Skip to content

Commit

Permalink
feat(repo): spin up .ts daemon when running tests that use daemon
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder committed May 30, 2024
1 parent dea8e7d commit 696c588
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 24 deletions.
2 changes: 2 additions & 0 deletions jest.preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ module.exports = {
coverageReporters: ['html'],
maxWorkers: 1,
testEnvironment: 'node',
globalSetup: '../../scripts/unit-test-setup.js',
globalTeardown: '../../scripts/unit-test-teardown.js',
};
1 change: 1 addition & 0 deletions packages/cypress/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ async function buildCypressTargets(
? cypressConfig.e2e.excludeSpecPattern.map((p) => join(projectRoot, p))
: [join(projectRoot, cypressConfig.e2e.excludeSpecPattern)];
const specFiles = await globWithWorkspaceContext(
context.workspaceRoot,
specPatterns,
excludeSpecPatterns
);
Expand Down
43 changes: 30 additions & 13 deletions packages/nx/src/daemon/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { readFileSync, statSync } from 'fs';
import { FileHandle, open } from 'fs/promises';
import { ensureDirSync, ensureFileSync } from 'fs-extra';
import { connect } from 'net';
import { join } from 'path';
import { extname, join } from 'path';
import { performance } from 'perf_hooks';
import { output } from '../../utils/output';
import { getFullOsSocketPath, killSocketOrPath } from '../socket-utils';
Expand Down Expand Up @@ -478,18 +478,35 @@ export class DaemonClient {
this._out = await open(DAEMON_OUTPUT_LOG_FILE, 'a');
this._err = await open(DAEMON_OUTPUT_LOG_FILE, 'a');

const backgroundProcess = spawn(
process.execPath,
[join(__dirname, '../server/start.js')],
{
cwd: workspaceRoot,
stdio: ['ignore', this._out.fd, this._err.fd],
detached: true,
windowsHide: true,
shell: false,
env: { ...process.env, ...DAEMON_ENV_SETTINGS },
}
);
// This stuff is only hit during our unit tests,
// as the daemon server is typescript during their execution.
const isTypescript = extname(__filename) === '.ts';
const workerExt = isTypescript ? 'ts' : 'js';

const args = [join(__dirname, `../server/start.${workerExt}`)];

// If the daemon is typescript, we need to add the ts-node/register to support it.
if (isTypescript) {
args.unshift('-r', 'ts-node/register');
}

const backgroundProcess = spawn(process.execPath, args, {
cwd: workspaceRoot,
stdio: ['ignore', this._out.fd, this._err.fd],
detached: true,
windowsHide: true,
shell: false,
env: {
...process.env,
...DAEMON_ENV_SETTINGS,
...(isTypescript
? {
// Ensures that the worker uses the same tsconfig as the main process
TS_NODE_PROJECT: join(__dirname, '../../../tsconfig.lib.json'),
}
: {}),
},
});
backgroundProcess.unref();

/**
Expand Down
24 changes: 17 additions & 7 deletions packages/nx/src/daemon/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,12 @@ async function handleMessage(socket, data: string) {
);
}

if (daemonIsOutdated()) {
const outdated = daemonIsOutdated();
if (outdated) {
await respondWithErrorAndExit(
socket,
`Lock files changed`,
new Error('LOCK-FILES-CHANGED')
`Daemon outdated`,
new Error(outdated)
);
}

Expand Down Expand Up @@ -274,11 +275,19 @@ function registerProcessTerminationListeners() {

let existingLockHash: string | undefined;

function daemonIsOutdated(): boolean {
return nxVersionChanged() || lockFileHashChanged();
function daemonIsOutdated(): string | null {
if (nxVersionChanged()) {
return 'NX_VERSION_CHANGED';
} else if (lockFileHashChanged()) {
return 'LOCK_FILES_CHANGED';
}
return null;
}

function nxVersionChanged(): boolean {
if (process.env.NX_SKIP_NX_VERSION_CHECK === 'true') {
return false;
}
return nxVersion !== getInstalledNxVersion();
}

Expand Down Expand Up @@ -332,10 +341,11 @@ const handleWorkspaceChanges: FileWatcherCallback = async (
try {
resetInactivityTimeout(handleInactivityTimeout);

if (daemonIsOutdated()) {
const outdatedReason = daemonIsOutdated();
if (outdatedReason) {
await handleServerProcessTermination({
server,
reason: 'Lock file changed',
reason: outdatedReason,
});
return;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/nx/src/utils/workspace-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function getAllFileDataInContext(workspaceRoot: string) {
return daemonClient.getAllFileData();
}

export function getFilesInDirectoryUsingContext(
export async function getFilesInDirectoryUsingContext(
workspaceRoot: string,
dir: string
) {
Expand Down
6 changes: 3 additions & 3 deletions packages/playwright/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ async function buildPlaywrightTargets(
playwrightConfig.testMatch ??= '**/*.@(spec|test).?(c|m)[jt]s?(x)';

const dependsOn: TargetConfiguration['dependsOn'] = [];
forEachTestFile(
await forEachTestFile(
(testFile) => {
const relativeSpecFilePath = normalizePath(
relative(projectRoot, testFile)
Expand Down Expand Up @@ -210,15 +210,15 @@ async function buildPlaywrightTargets(
return { targets, metadata };
}

function forEachTestFile(
async function forEachTestFile(
cb: (path: string) => void,
opts: {
context: CreateNodesContext;
path: string;
config: PlaywrightTestConfig;
}
) {
const files = getFilesInDirectoryUsingContext(
const files = await getFilesInDirectoryUsingContext(
opts.context.workspaceRoot,
opts.path
);
Expand Down
9 changes: 9 additions & 0 deletions scripts/unit-test-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Shuts down daemon before running any tests. This ensures that if a
// test needs the daemon, it will start up fresh and use the `.ts` daemon.
module.exports = () => {
process.env.NX_SKIP_NX_VERSION_CHECK = 'true';
require('child_process').execSync('pnpm exec nx daemon --stop', {
shell: true,
stdio: 'inherit',
});
};
6 changes: 6 additions & 0 deletions scripts/unit-test-teardown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Shuts down daemon after running any tests. This ensures that subsequent
// commands use the installed Nx version's daemon.
module.exports = () =>
require('child_process').execSync('pnpm exec nx daemon --stop', {
shell: true,
});
2 changes: 2 additions & 0 deletions typedoc-theme/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ export default {
resolver: '../scripts/patched-jest-resolver.js',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../coverage/typedoc-theme',
globalSetup: null,
globalTeardown: null,
preset: '../jest.preset.js',
};

0 comments on commit 696c588

Please sign in to comment.