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 d2a98c2 commit 6a38e6b
Show file tree
Hide file tree
Showing 22 changed files with 85 additions and 58 deletions.
1 change: 1 addition & 0 deletions jest.preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ module.exports = {
coverageReporters: ['html'],
maxWorkers: 1,
testEnvironment: 'node',
setupFiles: ['../../scripts/unit-test-setup.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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
import { WORKSPACE_PLUGIN_DIR } from '../../constants';
import update from './rename-workspace-rules';

import 'nx/src/internal-testing-utils/mock-project-graph';

const rule1Name = 'test-rule';
const rule2Name = 'my-rule';

Expand Down
2 changes: 2 additions & 0 deletions packages/eslint/src/generators/init/init.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import 'nx/src/internal-testing-utils/mock-project-graph';
import { NxJsonConfiguration, readJson, Tree, updateJson } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { LinterInitOptions, lintInitGenerator } from './init';
import { setWorkspaceRoot } from 'nx/src/utils/workspace-root';

describe('@nx/eslint:init', () => {
let tree: Tree;
let options: LinterInitOptions;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
setWorkspaceRoot(tree.root);
options = {
addPlugin: true,
};
Expand Down
4 changes: 2 additions & 2 deletions packages/gradle/src/plugin/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const createNodesV2: CreateNodesV2<GradlePluginOptions> = [
);
const targetsCache = readTargetsCache(cachePath);

populateGradleReport(context.workspaceRoot);
await populateGradleReport(context.workspaceRoot);
const gradleReport = getCurrentGradleReport();

try {
Expand Down Expand Up @@ -131,7 +131,7 @@ export const createNodes: CreateNodes<GradlePluginOptions> = [
logger.warn(
'`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will error.'
);
populateGradleReport(context.workspaceRoot);
await populateGradleReport(context.workspaceRoot);
const gradleReport = getCurrentGradleReport();
const internalCreateNodes = makeCreateNodes(gradleReport, {});
return await internalCreateNodes(configFile, options, context);
Expand Down
6 changes: 4 additions & 2 deletions packages/gradle/src/utils/get-gradle-report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ export function getCurrentGradleReport() {
return gradleReportCache;
}

export function populateGradleReport(workspaceRoot: string): void {
const gradleConfigHash = hashWithWorkspaceContext(workspaceRoot, [
export async function populateGradleReport(
workspaceRoot: string
): Promise<void> {
const gradleConfigHash = await hashWithWorkspaceContext(workspaceRoot, [
gradleConfigGlob,
]);
if (gradleReportCache && gradleConfigHash === gradleCurrentConfigHash) {
Expand Down
3 changes: 3 additions & 0 deletions packages/jest/src/plugins/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { join } from 'path';

import { createNodes } from './plugin';
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
import { setWorkspaceRoot } from 'nx/src/utils/workspace-root';

describe('@nx/jest/plugin', () => {
let createNodesFunction = createNodes[1];
Expand All @@ -25,6 +26,8 @@ describe('@nx/jest/plugin', () => {
configFiles: [],
};

setWorkspaceRoot(tempFs.tempDir);

await tempFs.createFiles({
'proj/jest.config.js': `module.exports = {}`,
'proj/src/unit.spec.ts': '',
Expand Down
8 changes: 8 additions & 0 deletions packages/nx/src/adapter/ngcli-adapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import {
import { createTreeWithEmptyWorkspace } from '../generators/testing-utils/create-tree-with-empty-workspace';
import { addProjectConfiguration } from '../generators/utils/project-configuration';

jest.mock('../project-graph/project-graph', () => ({
...jest.requireActual('../project-graph/project-graph'),
createProjectGraphAsync: () => ({
nodes: {},
externalNodes: {},
}),
}));

describe('ngcli-adapter', () => {
it('arrayBufferToString should support large buffers', () => {
const largeString = 'a'.repeat(1000000);
Expand Down
19 changes: 7 additions & 12 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 @@ -49,9 +49,6 @@ import { NxWorkspaceFiles } from '../../native';
const DAEMON_ENV_SETTINGS = {
NX_PROJECT_GLOB_CACHE: 'false',
NX_CACHE_PROJECTS_CONFIG: 'false',

// Used to identify that the code is running in the daemon process.
NX_ON_DAEMON_PROCESS: 'true',
};

export type UnregisterCallback = () => void;
Expand Down Expand Up @@ -283,14 +280,9 @@ export class DaemonClient {
return this.sendToDaemonViaQueue(message);
}

getWorkspaceContextFileData(
globs: string[],
exclude?: string[]
): Promise<FileData[]> {
getWorkspaceContextFileData(): Promise<FileData[]> {
const message: HandleContextFileDataMessage = {
type: GET_CONTEXT_FILE_DATA,
globs,
exclude,
};
return this.sendToDaemonViaQueue(message);
}
Expand Down Expand Up @@ -480,14 +472,17 @@ export class DaemonClient {

const backgroundProcess = spawn(
process.execPath,
[join(__dirname, '../server/start.js')],
[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 },
env: {
...process.env,
...DAEMON_ENV_SETTINGS,
},
}
);
backgroundProcess.unref();
Expand Down
2 changes: 0 additions & 2 deletions packages/nx/src/daemon/message-types/get-context-file-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ export const GET_CONTEXT_FILE_DATA = 'GET_CONTEXT_FILE_DATA' as const;

export type HandleContextFileDataMessage = {
type: typeof GET_CONTEXT_FILE_DATA;
globs: string[];
exclude?: string[];
};

export function isHandleContextFileDataMessage(
Expand Down
2 changes: 1 addition & 1 deletion packages/nx/src/daemon/server/handle-context-file-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { workspaceRoot } from '../../utils/workspace-root';
import { HandlerResult } from './server';

export async function handleContextFileData(): Promise<HandlerResult> {
const files = getAllFileDataInContext(workspaceRoot);
const files = await getAllFileDataInContext(workspaceRoot);
return {
response: JSON.stringify(files),
description: 'handleContextFileData',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { HandlerResult } from './server';
export async function handleGetFilesInDirectory(
dir: string
): Promise<HandlerResult> {
const files = getFilesInDirectoryUsingContext(workspaceRoot, dir);
const files = await getFilesInDirectoryUsingContext(workspaceRoot, dir);
return {
response: JSON.stringify(files),
description: 'handleNxWorkspaceFiles',
Expand Down
10 changes: 0 additions & 10 deletions packages/nx/src/daemon/server/handle-request-file-data.ts

This file was deleted.

26 changes: 14 additions & 12 deletions packages/nx/src/daemon/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
handleRecordOutputsHash,
} from './handle-outputs-tracking';
import { handleProcessInBackground } from './handle-process-in-background';
import { handleRequestFileData } from './handle-request-file-data';
import { handleRequestProjectGraph } from './handle-request-project-graph';
import { handleRequestShutdown } from './handle-request-shutdown';
import { serverLogger } from './logger';
Expand Down Expand Up @@ -132,11 +131,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 @@ -164,10 +164,6 @@ async function handleMessage(socket, data: string) {
);
} else if (payload.type === 'HASH_TASKS') {
await handleResult(socket, 'HASH_TASKS', () => handleHashTasks(payload));
} else if (payload.type === 'REQUEST_FILE_DATA') {
await handleResult(socket, 'REQUEST_FILE_DATA', () =>
handleRequestFileData()
);
} else if (payload.type === 'PROCESS_IN_BACKGROUND') {
await handleResult(socket, 'PROCESS_IN_BACKGROUND', () =>
handleProcessInBackground(payload)
Expand Down Expand Up @@ -274,8 +270,13 @@ 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 {
Expand Down Expand Up @@ -332,10 +333,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
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('explicit package json dependencies', () => {

const fileMap = createFileMap(
projectsConfigurations as any,
getAllFileDataInContext(tempFs.tempDir)
await getAllFileDataInContext(tempFs.tempDir)
).fileMap;

const builder = new ProjectGraphBuilder(undefined, fileMap.projectFileMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ export function loadRemoteNxPlugin(
: {}),
};

delete env.NX_ON_DAEMON_PROCESS;

const worker = fork(workerPath, [], {
stdio: ['ignore', 'inherit', 'inherit', 'ipc'],
env,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('retrieveProjectConfigurationPaths', () => {
})
);

const configPaths = retrieveProjectConfigurationPaths(fs.tempDir, [
const configPaths = await retrieveProjectConfigurationPaths(fs.tempDir, [
{
createNodes: [
'{project.json,**/project.json}',
Expand Down
7 changes: 1 addition & 6 deletions packages/nx/src/utils/all-file-data.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { FileData } from '../config/project-graph';
import { daemonClient } from '../daemon/client/client';
import { getAllFileDataInContext } from './workspace-context';
import { workspaceRoot } from './workspace-root';

export function allFileData(): Promise<FileData[]> {
if (daemonClient.enabled()) {
return daemonClient.getAllFileData();
} else {
return Promise.resolve(getAllFileDataInContext(workspaceRoot));
}
return getAllFileDataInContext(workspaceRoot);
}
4 changes: 2 additions & 2 deletions packages/nx/src/utils/workspace-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ export function updateFilesInContext(
return workspaceContext?.incrementalUpdate(updatedFiles, deletedFiles);
}

export function getAllFileDataInContext(workspaceRoot: string) {
export async function getAllFileDataInContext(workspaceRoot: string) {
if (isOnDaemon() || !daemonClient.enabled()) {
ensureContextAvailable(workspaceRoot);
return workspaceContext.allFileData();
}
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
13 changes: 13 additions & 0 deletions scripts/unit-test-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = () => {
process.env.NX_DAEMON = 'false';

jest.doMock('@nx/devkit', () => ({
...jest.requireActual('@nx/devkit'),
createProjectGraphAsync: jest.fn().mockImplementation(async () => {
return {
nodes: {},
dependencies: {},
};
}),
}));
};
19 changes: 18 additions & 1 deletion typedoc-theme/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
const nxPreset = require('@nx/jest/preset').default;

const preset = {
...nxPreset,
testTimeout: 35000,
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
transform: {
'^.+\\.(ts|js|html)$': 'ts-jest',
},
resolver: '../scripts/patched-jest-resolver.js',
moduleFileExtensions: ['ts', 'js', 'html'],
coverageReporters: ['html'],
maxWorkers: 1,
testEnvironment: 'node',
};

/* eslint-disable */
export default {
...preset,
displayName: 'typedoc-theme',

globals: {},
Expand All @@ -14,5 +31,5 @@ export default {
resolver: '../scripts/patched-jest-resolver.js',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../coverage/typedoc-theme',
preset: '../jest.preset.js',
setupFiles: [],
};

0 comments on commit 6a38e6b

Please sign in to comment.