From 54f03f7c0be88bf49b3e4e61bcb7196d3b04b9ed Mon Sep 17 00:00:00 2001 From: eladcon Date: Sun, 22 Oct 2023 14:00:04 +0300 Subject: [PATCH] fix(cli): cant run tests with external packages in non-entry files (#4545) Tests output directories are now under the target directory. This closes #4394. Although there is still an issue where `require` doesn't respect the vm context, i think this makes sense since the current OS directories are temporary which increases the chances of lost terraform data and dangling cloud resources ## Checklist - [X] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [X] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- apps/wing/src/commands/test/test.ts | 5 +- libs/wingcompiler/src/compile.test.ts | 71 +++++++++++++++++++++++++++ libs/wingcompiler/src/compile.ts | 5 +- 3 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 libs/wingcompiler/src/compile.test.ts diff --git a/apps/wing/src/commands/test/test.ts b/apps/wing/src/commands/test/test.ts index 400d6ef34dd..360307aafc2 100644 --- a/apps/wing/src/commands/test/test.ts +++ b/apps/wing/src/commands/test/test.ts @@ -10,7 +10,7 @@ import debug from "debug"; import { glob } from "glob"; import { nanoid } from "nanoid"; import { printResults, validateOutputFilePath, writeResultsToFile } from "./results"; -import { generateTmpDir, withSpinner } from "../../util"; +import { withSpinner } from "../../util"; import { compile, CompileOptions } from "../compile"; const log = debug("wing:test"); @@ -98,9 +98,6 @@ async function testOne(entrypoint: string, options: TestOptions) { ...options, rootId: options.rootId ?? `Test.${nanoid(10)}`, testing: true, - // since the test cleans up after each run, it's essential to create a temporary output directory- - // at least one that is different then the usual compilation output dir, otherwise we might end up cleaning up the user's actual resources. - ...(options.target !== Target.SIM && { targetDir: `${await generateTmpDir()}/target` }), }) ); diff --git a/libs/wingcompiler/src/compile.test.ts b/libs/wingcompiler/src/compile.test.ts new file mode 100644 index 00000000000..7521f91d2cf --- /dev/null +++ b/libs/wingcompiler/src/compile.test.ts @@ -0,0 +1,71 @@ +import { describe, test, expect } from "vitest"; +import { join, resolve, basename } from "path"; +import { stat, mkdtemp } from "fs/promises"; +import { tmpdir } from "os"; +import { Target } from "./constants"; +import { compile } from "./compile"; + +const exampleDir = resolve("../../examples/tests/valid"); +const exampleFilePath = join(exampleDir, "enums.test.w"); + +export async function generateTmpDir() { + return mkdtemp(join(tmpdir(), "-wing-compile-test")); +} + +describe( + "compile tests", + () => { + test("should produce stable artifacts for tf-aws", async () => { + const targetDir = `${await generateTmpDir()}/target`; + const artifactDir = await compile(exampleFilePath, { + target: Target.TF_AWS, + targetDir, + }); + + const stats = await stat(artifactDir); + expect(stats.isDirectory()).toBeTruthy(); + expect(artifactDir).toContain(targetDir); + expect(basename(artifactDir)).toEqual("enums.test.tfaws") + }); + + test("should produce temp artifacts for tf-aws testing", async () => { + const targetDir = `${await generateTmpDir()}/target`; + const artifactDir = await compile(exampleFilePath, { + target: Target.TF_AWS, + targetDir, + testing: true, + }); + + const stats = await stat(artifactDir); + expect(stats.isDirectory()).toBeTruthy(); + expect(artifactDir).toContain(targetDir); + expect(basename(artifactDir).match(/enums\.test\.tfaws\.\d+$/)).toBeTruthy(); + }); + + test("should produce stable artifacts for sim", async () => { + const targetDir = `${await generateTmpDir()}/target`; + const artifactDir = await compile(exampleFilePath, { + target: Target.SIM, + targetDir, + }); + + const stats = await stat(artifactDir); + expect(stats.isDirectory()).toBeTruthy(); + expect(artifactDir).toContain(targetDir); + expect(basename(artifactDir)).toEqual("enums.test.wsim") + }); + + test("should produce stable artifacts for sim testing", async () => { + const targetDir = `${await generateTmpDir()}/target`; + const artifactDir = await compile(exampleFilePath, { + target: Target.SIM, + targetDir, + testing: true, + }); + + const stats = await stat(artifactDir); + expect(stats.isDirectory()).toBeTruthy(); + expect(artifactDir).toContain(targetDir); + expect(basename(artifactDir)).toEqual("enums.test.wsim") + }); +}); diff --git a/libs/wingcompiler/src/compile.ts b/libs/wingcompiler/src/compile.ts index 0a8f02dc277..b1c9b991c89 100644 --- a/libs/wingcompiler/src/compile.ts +++ b/libs/wingcompiler/src/compile.ts @@ -80,8 +80,9 @@ function resolveSynthDir( log?.(err); throw new Error("Source file cannot be found"); } - const tmpSuffix = tmp ? `.${Date.now().toString().slice(-6)}.tmp` : ""; - const lastPart = `${entrypointName}.${targetDirSuffix}${tmpSuffix}`; + const randomPart = tmp || (testing && target !== Target.SIM) ? `.${Date.now().toString().slice(-6)}` : ""; + const tmpSuffix = tmp ? ".tmp" : ""; + const lastPart = `${entrypointName}.${targetDirSuffix}${randomPart}${tmpSuffix}`; if (testing) { return join(outDir, "test", lastPart); } else {