Skip to content

Commit

Permalink
Move exec test helper (#500)
Browse files Browse the repository at this point in the history
  • Loading branch information
sorenlouv committed May 7, 2024
1 parent a3f45fa commit 077cf1c
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('cherrypickAndCreateTargetPullRequest', () => {
execSpy = jest
.spyOn(childProcess, 'spawnPromise')

// mock all exec commands to respond without errors
// mock all spawn commands to respond without errors
.mockResolvedValue({ stdout: '', stderr: '', code: 0, cmdArgs: [] });

consoleLogSpy = jest.spyOn(logger, 'consoleLog');
Expand Down
77 changes: 30 additions & 47 deletions src/lib/child-process-promisified.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import childProcess from 'child_process';
import { promisify } from 'util';
import apm from 'elastic-apm-node';
import { logger } from './logger';
const execPromisified = promisify(childProcess.exec);

export async function exec(
cmd: string,
options: childProcess.ExecOptions & { cwd: string },
) {
const res = await execPromisified(cmd, {
maxBuffer: 100 * 1024 * 1024,
...options,
type SpawnErrorContext = {
cmdArgs: ReadonlyArray<string>;
code: number;
stderr: string;
stdout: string;
};

// ensure that git commands return english error messages
env: { ...process.env, LANG: 'en_US' },
});
export class SpawnError extends Error {
context: SpawnErrorContext;
constructor(context: SpawnErrorContext) {
const cmdArgs = context.cmdArgs.join(' ');
const message = `Code: ${
context.code
}, Args: "${cmdArgs}", Message: ${context.stderr.trim()}`;

return res;
super(message);
Error.captureStackTrace(this, SpawnError);
this.name = 'SpawnError';
this.message = message;
this.context = context;
}
}

type SpawnPromiseResponse = {
Expand Down Expand Up @@ -83,17 +89,6 @@ export async function spawnPromise(
});
}

function startSpawnSpan(cmd: string, cmdArgs: ReadonlyArray<string>) {
const span = apm.startSpan(`Spawn: "${cmd}"`);
const fullCmd = getFullCmd(cmd, cmdArgs);
const firstCmdArg = cmdArgs.filter(
(cmdArg) => !cmdArg.startsWith('--') && !cmdArg.startsWith('-'),
)[0];
span?.setType('spawn', cmd, firstCmdArg);
span?.setLabel(`cmd`, fullCmd);
return span;
}

export const spawnStream = (cmd: string, cmdArgs: ReadonlyArray<string>) => {
const spawnSpan = startSpawnSpan(cmd, cmdArgs);

Expand All @@ -111,29 +106,17 @@ export const spawnStream = (cmd: string, cmdArgs: ReadonlyArray<string>) => {
return res;
};

function getFullCmd(cmd: string, cmdArgs: ReadonlyArray<string>) {
return `${cmd} ${cmdArgs.join(' ')}`;
function startSpawnSpan(cmd: string, cmdArgs: ReadonlyArray<string>) {
const span = apm.startSpan(`Spawn: "${cmd}"`);
const fullCmd = getFullCmd(cmd, cmdArgs);
const firstCmdArg = cmdArgs.filter(
(cmdArg) => !cmdArg.startsWith('--') && !cmdArg.startsWith('-'),
)[0];
span?.setType('spawn', cmd, firstCmdArg);
span?.setLabel(`cmd`, fullCmd);
return span;
}

export type SpawnErrorContext = {
cmdArgs: ReadonlyArray<string>;
code: number;
stderr: string;
stdout: string;
};

export class SpawnError extends Error {
context: SpawnErrorContext;
constructor(context: SpawnErrorContext) {
const cmdArgs = context.cmdArgs.join(' ');
const message = `Code: ${
context.code
}, Args: "${cmdArgs}", Message: ${context.stderr.trim()}`;

super(message);
Error.captureStackTrace(this, SpawnError);
this.name = 'SpawnError';
this.message = message;
this.context = context;
}
function getFullCmd(cmd: string, cmdArgs: ReadonlyArray<string>) {
return `${cmd} ${cmdArgs.join(' ')}`;
}
12 changes: 5 additions & 7 deletions src/lib/git.private.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path';
import makeDir from 'make-dir';
import { Commit } from '../entrypoint.api';
import { ValidConfigOptions } from '../options/options';
import { exec } from '../test/childProcessHelper';
import { getDevAccessToken } from '../test/private/getDevAccessToken';
import { getSandboxPath, resetSandbox } from '../test/sandbox';
import * as childProcess from './child-process-promisified';
Expand Down Expand Up @@ -178,7 +179,7 @@ describe('git.private', () => {
targetBranch: '7.x',
backportBranch: 'my-backport-branch',
});
await childProcess.exec(
await exec(
`git remote add sorenlouv https://x-access-token:${accessToken}@github.com/sorenlouv/repo-with-conflicts.git`,
{ cwd },
);
Expand Down Expand Up @@ -380,7 +381,7 @@ describe('git.private', () => {
cwd,
);

await childProcess.exec('git checkout 7.x', { cwd });
await exec('git checkout 7.x', { cwd });

// cherry-pick file
try {
Expand All @@ -394,7 +395,7 @@ describe('git.private', () => {
}

// disregard conflicts and stage all files
await childProcess.exec('git add -A', { cwd });
await exec('git add -A', { cwd });

await commitChanges({ commit, commitAuthor, options });

Expand Down Expand Up @@ -779,10 +780,7 @@ async function getCurrentSha(cwd: string) {
}

async function getCurrentBranchName(cwd: string) {
const { stdout } = await childProcess.exec(
'git rev-parse --abbrev-ref HEAD',
{ cwd },
);
const { stdout } = await exec('git rev-parse --abbrev-ref HEAD', { cwd });
return stdout.trim();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { exec } from '../../../test/childProcessHelper';
import { getDevAccessToken } from '../../../test/private/getDevAccessToken';
import { getSandboxPath, resetSandbox } from '../../../test/sandbox';
import * as childProcess from '../../child-process-promisified';
import { getRepoOwnerAndNameFromGitRemotes } from './getRepoOwnerAndNameFromGitRemotes';

const sandboxPath = getSandboxPath({ filename: __filename });
Expand All @@ -11,8 +11,8 @@ describe('fetchRemoteProjectConfig', () => {
it('retrives the original owner from github', async () => {
await resetSandbox(sandboxPath);
const execOpts = { cwd: sandboxPath };
await childProcess.exec(`git init`, execOpts);
await childProcess.exec(
await exec(`git init`, execOpts);
await exec(
`git remote add sorenlouv git@github.com:sorenlouv/kibana.git`,
execOpts,
);
Expand All @@ -33,16 +33,10 @@ describe('fetchRemoteProjectConfig', () => {
it('swallows the error and returns empty', async () => {
await resetSandbox(sandboxPath);
const execOpts = { cwd: sandboxPath };
await childProcess.exec(`git init`, execOpts);
await childProcess.exec(
`git remote add foo git@github.com:foo/kibana.git`,
execOpts,
);
await exec(`git init`, execOpts);
await exec(`git remote add foo git@github.com:foo/kibana.git`, execOpts);

await childProcess.exec(
`git remote add bar git@github.com:bar/kibana.git`,
execOpts,
);
await exec(`git remote add bar git@github.com:bar/kibana.git`, execOpts);

expect(
await getRepoOwnerAndNameFromGitRemotes({
Expand All @@ -57,7 +51,7 @@ describe('fetchRemoteProjectConfig', () => {
it('returns empty', async () => {
await resetSandbox(sandboxPath);
const execOpts = { cwd: sandboxPath };
await childProcess.exec(`git init`, execOpts);
await exec(`git init`, execOpts);

expect(
await getRepoOwnerAndNameFromGitRemotes({
Expand Down
18 changes: 18 additions & 0 deletions src/test/childProcessHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import childProcess from 'child_process';
import { promisify } from 'util';
const execPromisified = promisify(childProcess.exec);

export async function exec(
cmd: string,
options: childProcess.ExecOptions & { cwd: string },
) {
const res = await execPromisified(cmd, {
maxBuffer: 100 * 1024 * 1024,
...options,

// ensure that git commands return english error messages
env: { ...process.env, LANG: 'en_US' },
});

return res;
}
2 changes: 1 addition & 1 deletion src/test/e2e/cli/commit-author.private.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { exec } from '../../../lib/child-process-promisified';
import { exec } from '../../childProcessHelper';
import { getDevAccessToken } from '../../private/getDevAccessToken';
import { getSandboxPath, resetSandbox } from '../../sandbox';
import { runBackportViaCli } from './runBackportViaCli';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fs from 'fs/promises';
import { exec } from '../../../lib/child-process-promisified';
import { exec } from '../../childProcessHelper';
import { getDevAccessToken } from '../../private/getDevAccessToken';
import { replaceStringAndLinebreaks } from '../../replaceStringAndLinebreaks';
import { getSandboxPath, resetSandbox } from '../../sandbox';
Expand Down
2 changes: 1 addition & 1 deletion src/test/e2e/cli/entrypoint.cli.private.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { exec } from '../../../lib/child-process-promisified';
import * as packageVersion from '../../../utils/packageVersion';
import { exec } from '../../childProcessHelper';
import { getDevAccessToken } from '../../private/getDevAccessToken';
import { getSandboxPath, resetSandbox } from '../../sandbox';
import { runBackportViaCli } from './runBackportViaCli';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { exec } from '../../../lib/child-process-promisified';
import { exec } from '../../childProcessHelper';
import { getDevAccessToken } from '../../private/getDevAccessToken';
import { getSandboxPath, resetSandbox } from '../../sandbox';
import { runBackportViaCli } from './runBackportViaCli';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { exec } from '../../../lib/child-process-promisified';
import { exec } from '../../childProcessHelper';
import { getDevAccessToken } from '../../private/getDevAccessToken';
import { replaceStringAndLinebreaks } from '../../replaceStringAndLinebreaks';
import { getSandboxPath, resetSandbox } from '../../sandbox';
Expand Down

0 comments on commit 077cf1c

Please sign in to comment.