Skip to content
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

Fix flaky scanner test #781

Closed
wants to merge 18 commits into from
Closed
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -419,13 +419,13 @@
"scripts": {
"vscode:prepublish": "yarn run compile",
"lint": "eslint . --ext .ts",
"pretest": "yarn run lint && tsc --strict --skipLibCheck",
"pretest": "tsc --strict --skipLibCheck",
"test:integration": "ts-node ./test/integrationTest.ts",
"test:web-client": "mocha web/test/*.test.mjs",
"test:system": "ts-node test/systemTest.ts",
"test:unit": "mocha test/unit/**/*.test.[tj]s",
"test:unit:some": "mocha",
"test": "yarn test:unit && yarn test:web-client && yarn test:integration && yarn test:system",
"test": "yarn test:integration scanner/performAsAppMapsAreModified.test.js",
"compile": "NODE_ENV=production tsup --config tsup.config.ts",
"watch": "tsup --config tsup.config.ts --watch",
"package": "vsce package",
Expand Down
9 changes: 9 additions & 0 deletions src/services/nodeDependencyProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ export class ProcessLog extends Array<ProcessLogItem> {
}

export async function getModulePath(options: ProgramOptions): Promise<string> {
const workspaceFolders = vscode.workspace.workspaceFolders;
if (
options.dependency === ProgramName.Scanner &&
workspaceFolders &&
workspaceFolders.length > 0
) {
const root = path.resolve(workspaceFolders[0].uri.fsPath, '..', '..', '..', '..');
return path.join(root, 'appmap-js', 'packages', 'scanner', 'built', 'cli.js');
}
const localToolsPath = ExtensionSettings.appMapCommandLineToolsPath;
if (localToolsPath) {
let packageName: string;
Expand Down
2 changes: 1 addition & 1 deletion src/services/nodeProcessService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export class NodeProcessService implements WorkspaceService<NodeProcessServiceIn

const installProcess = spawn({
modulePath: this.yarnPath,
args: ['up', '-R', '@appland/appmap', '@appland/scanner'],
args: ['add', '@appland/appmap@latest', '@appland/scanner@1.81.1'],
cwd: this.globalStorageDir,
log: NodeProcessService.outputChannel,
// Fix "The remote archive doesn't match the expected checksum" issue by
Expand Down
1 change: 1 addition & 0 deletions src/services/processWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export class ProcessWatcher implements vscode.Disposable {

this.shouldRun = true;
this.process = spawn(options);
this.process = spawn({ ...options, args: ['--version'] });
this.process.log.append(
`spawned ${this.process.spawnargs.join(' ')} with options ${JSON.stringify(options)}`
);
Expand Down
68 changes: 44 additions & 24 deletions test/integration/scanner/performAsAppMapsAreModified.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as vscode from 'vscode';
import assert from 'assert';
import { exists, stat } from 'fs';
import { existsSync, mkdirSync, rmSync } from 'fs';
import { join, relative } from 'path';
import { promisify } from 'util';
import {
initializeWorkspace,
waitFor,
Expand All @@ -15,53 +14,74 @@ import {
waitForAppMapServices,
restoreFile,
withAuthenticatedUser,
executeWorkspaceOSCommand,
} from '../util';
import AppMapService from '../../../src/appMapService';

// async function logWatches(): Promise<void> {
// const watches = await executeWorkspaceOSCommand('ps -ef | grep -e --watch', ProjectA);
// console.log('Watches: ', watches);
// }

async function logIndexDir(): Promise<void> {
const indexDir = await executeWorkspaceOSCommand(`ls -al ${ExampleAppMapIndexDir}`, ProjectA);
console.log(`\nIndex Dir: ${indexDir}`);
}

describe('Scanner', () => {
let services: AppMapService;
withAuthenticatedUser();

beforeEach(async () => {
await initializeWorkspace();
await waitForAppMapServices(
services = await waitForAppMapServices(
'tmp/appmap/minitest/Microposts_controller_can_get_microposts_as_JSON.appmap.json'
);
await waitFor('Index directory exists', async () => {
return Boolean(await promisify(stat)(ExampleAppMapIndexDir));
});
await waitFor('Index directory exists', () => existsSync(ExampleAppMapIndexDir));
});

afterEach(initializeWorkspace);

it('is performed as AppMaps are modified', async () => {
await vscode.commands.executeCommand('appmap.deleteAllAppMaps');
async function removeAndReindex() {
await logIndexDir();
await vscode.commands.executeCommand('appmap.deleteAllAppMaps');
rmSync(ExampleAppMapIndexDir, { force: true, recursive: true });
mkdirSync(ExampleAppMapIndexDir);
await logIndexDir();

await waitFor('AppMaps to be deleted', () => services.localAppMaps.appMaps.length === 0);
await waitFor('Diagnostics to be cleared', hasNoDiagnostics);

const appMapPath = relative(ProjectA, ExampleAppMap);
await restoreFile(appMapPath);

assert(existsSync(ExampleAppMap));

await waitFor('Diagnostics were not cleared', hasNoDiagnostics);
await waitFor('AppMap to be re-indexed', () =>
existsSync(join(ExampleAppMapIndexDir, 'mtime'))
);
await logIndexDir();
}

// KEG: Remove this, as it's failing due to an issue either with IndexJanitor or with the test itself.
// await waitFor(
// `AppMap index dir should be removed`,
// async () => !(await promisify(exists)(ExampleAppMapIndexDir))
// );
await removeAndReindex();

const appMapPath = relative(ProjectA, ExampleAppMap);
await repeatUntil(
async () => await restoreFile(appMapPath),
`AppMap should be reindexed`,
async () => promisify(exists)(join(ExampleAppMapIndexDir, 'mtime'))
await logIndexDir();
await repeatUntil(removeAndReindex, 'Findings to be generated', () =>
existsSync(join(ExampleAppMapIndexDir, 'appmap-findings.json'))
);
await logIndexDir();

await repeatUntil(
async () => await restoreFile(appMapPath),
'No Diagnostics were created for Microposts_controller_can_get_microposts_as_JSON',
async () => {
return getDiagnosticsForAppMap(ExampleAppMap).length > 0;
}
await waitFor(
'diagnostics to be created',
() => getDiagnosticsForAppMap(ExampleAppMap).length > 0
);

const diagnostic = getDiagnosticsForAppMap(ExampleAppMap)[0];
assert.strictEqual(
diagnostic.uri.fsPath,
join(ProjectA, 'app/controllers/microposts_controller.rb')
);
assert(false);
});
});
9 changes: 6 additions & 3 deletions test/integration/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,18 @@ async function closeAllEditors(): Promise<void> {
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
}

export async function executeWorkspaceOSCommand(cmd: string, workspaceName: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
export async function executeWorkspaceOSCommand(
cmd: string,
workspaceName: string
): Promise<string> {
return new Promise<string>((resolve, reject) => {
exec(cmd, { cwd: workspaceName }, (err, stdout, stderr) => {
if (err) {
console.log(stdout);
console.warn(stderr);
return reject(err);
}
resolve();
resolve(stdout);
});
});
}
Expand Down
2 changes: 2 additions & 0 deletions test/integrationTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ async function integrationTest() {
userDataDir,
// '--disable-extensions',
'--disable-gpu',
'--disable-keytar',
'--password-store=basic',
workspaceDir,
],
});
Expand Down