Skip to content

Commit c94bf09

Browse files
committed
extension/test: restore process.env modified during testing
Some tests mutate process.env, or call updateGoVarsFromConfig that mutates process.env (setting GOROOT, GOPATH, GOMODCACHE, GO111MODULE...) That makes subsequent tests operate in strange state. Fix tests to recover the process env state cached from suite/test start. The ideal solution would be to avoid mutating process.env whenever possible. There were brief attempts to clean up this and replace updateGoVarsFromConfig with a Configuration storage object and dependency injection, but they were not complete yet. Change-Id: Iecd3bb639b50875a3df652f2060c2c836499913e Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/619776 kokoro-CI: kokoro <[email protected]> Commit-Queue: Hyang-Ah Hana Kim <[email protected]> Reviewed-by: Hongxiang Jiang <[email protected]>
1 parent e4a498e commit c94bf09

File tree

7 files changed

+36
-17
lines changed

7 files changed

+36
-17
lines changed

extension/src/goEnv.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,6 @@ export function toolInstallationEnvironment(): NodeJS.Dict<string> {
2626
} else {
2727
toolsGopath = getCurrentGoPath();
2828
}
29-
if (!toolsGopath) {
30-
const msg = 'Cannot install Go tools. Set either go.gopath or go.toolsGopath in settings.';
31-
vscode.window.showInformationMessage(msg, 'Open User Settings', 'Open Workspace Settings').then((selected) => {
32-
switch (selected) {
33-
case 'Open User Settings':
34-
vscode.commands.executeCommand('workbench.action.openGlobalSettings');
35-
break;
36-
case 'Open Workspace Settings':
37-
vscode.commands.executeCommand('workbench.action.openWorkspaceSettings');
38-
break;
39-
}
40-
});
41-
return {};
42-
}
4329
env['GOPATH'] = toolsGopath;
4430

4531
// Explicitly set 'auto' so tools that require

extension/src/goInstallTools.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ export async function promptForUpdatingTool(
480480
}
481481

482482
export function updateGoVarsFromConfig(goCtx: GoExtensionContext): Promise<void> {
483+
// TODO(hyangah): can we avoid modifying process.env? The `go env` output
484+
// can be cached in memory and queried when functions in goEnv.ts are called
485+
// instead of mutating process.env.
483486
const { binPath, why } = getBinPathWithExplanation('go', false);
484487
const goRuntimePath = binPath;
485488

@@ -492,11 +495,14 @@ export function updateGoVarsFromConfig(goCtx: GoExtensionContext): Promise<void>
492495
}
493496

494497
return new Promise<void>((resolve, reject) => {
498+
const env = toolExecutionEnvironment();
499+
const cwd = getWorkspaceFolderPath();
500+
495501
cp.execFile(
496502
goRuntimePath,
497503
// -json is supported since go1.9
498504
['env', '-json', 'GOPATH', 'GOROOT', 'GOPROXY', 'GOBIN', 'GOMODCACHE'],
499-
{ env: toolExecutionEnvironment(), cwd: getWorkspaceFolderPath() },
505+
{ env: env, cwd: cwd },
500506
(err, stdout, stderr) => {
501507
if (err) {
502508
outputChannel.append(

extension/test/gopls/codelens.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ suite('Code lenses for testing and benchmarking', function () {
3737
sinon.restore();
3838
});
3939

40+
// updaetGoVarsFromConfig mutates env vars. Cache the value
41+
// so we can restore it in suiteTeardown.
42+
const prevEnv = Object.assign({}, process.env);
43+
4044
suiteSetup(async () => {
4145
await updateGoVarsFromConfig({});
4246

@@ -47,6 +51,7 @@ suite('Code lenses for testing and benchmarking', function () {
4751

4852
suiteTeardown(async () => {
4953
await env.teardown();
54+
process.env = prevEnv;
5055
});
5156

5257
test('Subtests - runs a test with cursor on t.Run line', async () => {

extension/test/gopls/goTest.run.test.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,20 @@ import { Env } from './goplsTestEnv.utils';
1111
import { updateGoVarsFromConfig } from '../../src/goInstallTools';
1212

1313
suite('Go Test Runner', () => {
14+
// updateGoVarsFromConfig mutates process.env. Restore the cached
15+
// prevEnv when teardown.
16+
// TODO: avoid updateGoVarsFromConfig call.
17+
const prevEnv = Object.assign({}, process.env);
1418
const fixtureDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata');
1519

1620
let testExplorer: GoTestExplorer;
1721

1822
suiteSetup(async () => {
1923
await updateGoVarsFromConfig({});
2024
});
25+
suiteTeardown(() => {
26+
process.env = prevEnv;
27+
});
2128

2229
suite('parseOutput', () => {
2330
const ctx = MockExtensionContext.new();
@@ -170,10 +177,13 @@ suite('Go Test Runner', () => {
170177
});
171178

172179
suite('Subtest', function () {
180+
// This test is slow, especially on Windows.
173181
// WARNING: each call to testExplorer.runner.run triggers one or more
174182
// `go test` command runs (testUtils.goTest is spied, not mocked or replaced).
175183
// Each `go test` command invocation can take seconds on slow machines.
176184
// As we add more cases, the timeout should be increased accordingly.
185+
this.timeout(20000); // I don't know why but timeout chained after `suite` didn't work.
186+
177187
const sandbox = sinon.createSandbox();
178188
const subTestDir = path.join(fixtureDir, 'subTest');
179189
const ctx = MockExtensionContext.new();
@@ -204,7 +214,6 @@ suite('Go Test Runner', () => {
204214
});
205215

206216
test('discover and run', async () => {
207-
console.log('discover and run');
208217
// Locate TestMain and TestOther
209218
const tests = testExplorer.resolver.find(uri).filter((x) => GoTest.parseId(x.id).kind === 'test');
210219
tests.sort((a, b) => a.label.localeCompare(b.label));
@@ -284,6 +293,6 @@ suite('Go Test Runner', () => {
284293
'Failed to execute `go test`'
285294
);
286295
assert.strictEqual(spy.callCount, 0, 'expected no calls to goTest');
287-
}).timeout(10000);
296+
});
288297
});
289298
});

extension/test/integration/coverage.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ suite('Coverage for tests', function () {
2222
let fixtureSourcePath: string;
2323
let coverFilePath: string;
2424

25+
// updateGoVarsFromConfig mutates process.env. Restore to prevEnv in suiteTeardown.
26+
// TODO: avoid updateGoVarsFromConfig.
27+
const prevEnv = Object.assign({}, process.env);
2528
suiteSetup(async () => {
2629
await updateGoVarsFromConfig({});
2730

@@ -30,6 +33,9 @@ suite('Coverage for tests', function () {
3033
coverFilePath = path.join(fixtureSourcePath, 'cover.out');
3134
return;
3235
});
36+
suiteTeardown(() => {
37+
process.env = prevEnv;
38+
});
3339
test('resolve import paths', async () => {
3440
initForTest();
3541
const x = vscode.workspace.openTextDocument(coverFilePath);

extension/test/integration/goDebugConfiguration.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@ suite('Debug Environment Variable Merge Test', () => {
2323
const fixtureSourcePath = path.join(__dirname, '..', '..', '..', 'test', 'testdata');
2424
const filePath = path.join(fixtureSourcePath, 'baseTest', 'test.go');
2525

26+
// updateGoVarsFromConfig mutates process.env.
27+
// Stash the original value and restore it in suiteTeardown.
28+
// TODO: avoid updateGoVarsFromConfig.
29+
const prevEnv = Object.assign({}, process.env);
2630
suiteSetup(async () => {
2731
await goInstallTools.updateGoVarsFromConfig({});
2832
await vscode.workspace.openTextDocument(vscode.Uri.file(filePath));
2933
});
3034

3135
suiteTeardown(() => {
3236
vscode.commands.executeCommand('workbench.action.closeActiveEditor');
37+
process.env = prevEnv;
3338
});
3439

3540
let sandbox: sinon.SinonSandbox;

extension/test/integration/statusbar.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ import ourutil = require('../../src/util');
2929
import { setGOROOTEnvVar } from '../../src/goEnv';
3030

3131
describe('#initGoStatusBar()', function () {
32+
const prevEnv = Object.assign({}, process.env);
3233
this.beforeAll(async () => {
3334
await updateGoVarsFromConfig({}); // should initialize the status bar.
3435
});
3536

3637
this.afterAll(() => {
3738
disposeGoStatusBar();
39+
process.env = prevEnv;
3840
});
3941

4042
it('should create a status bar item', () => {

0 commit comments

Comments
 (0)