From 1461d47298a7f0b55e6ec1d5774a0b1297aeb719 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 24 May 2024 10:23:13 -0700 Subject: [PATCH 01/54] Refactor ingress tests to use test workspace --- gulpfile.ts | 7 ----- package.json | 4 +-- test/ingress/IngressPromptStep.test.ts | 9 ++++--- .../tryGetDockerfileExposePorts.test.ts | 9 ++++--- test/test.code-workspace | 2 +- .../dockerfiles}/sample1.Dockerfile | 0 .../dockerfiles}/sample2.Dockerfile | 0 .../dockerfiles}/sample3.Dockerfile | 0 .../dockerfiles}/sample4.Dockerfile | 0 .../dockerfiles}/sample5.Dockerfile | 0 .../dockerfiles}/sample6.Dockerfile | 0 .../dockerfiles}/sample7.Dockerfile | 0 test/testUtils.ts | 27 +++++++++++++++++++ 13 files changed, 40 insertions(+), 18 deletions(-) rename test/{ingress/dockerfileSamples => testProject/dockerfiles}/sample1.Dockerfile (100%) rename test/{ingress/dockerfileSamples => testProject/dockerfiles}/sample2.Dockerfile (100%) rename test/{ingress/dockerfileSamples => testProject/dockerfiles}/sample3.Dockerfile (100%) rename test/{ingress/dockerfileSamples => testProject/dockerfiles}/sample4.Dockerfile (100%) rename test/{ingress/dockerfileSamples => testProject/dockerfiles}/sample5.Dockerfile (100%) rename test/{ingress/dockerfileSamples => testProject/dockerfiles}/sample6.Dockerfile (100%) rename test/{ingress/dockerfileSamples => testProject/dockerfiles}/sample7.Dockerfile (100%) create mode 100644 test/testUtils.ts diff --git a/gulpfile.ts b/gulpfile.ts index 60b03dabe..3e69c1ffd 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -26,13 +26,6 @@ async function cleanReadme(): Promise { await fse.writeFile(readmePath, data); } -async function preTest(): Promise { - const fromPath: string = path.join(__dirname, 'test', 'ingress', 'dockerfileSamples'); - const toPath: string = path.join(__dirname, 'dist', 'test', 'ingress', 'dockerfileSamples'); - fse.copySync(fromPath, toPath); -} - exports['webpack-dev'] = gulp.series(prepareForWebpack, () => gulp_webpack('development')); exports['webpack-prod'] = gulp.series(prepareForWebpack, () => gulp_webpack('production')); exports.cleanReadme = cleanReadme; -exports.preTest = preTest; diff --git a/package.json b/package.json index 25149a55f..73f780033 100644 --- a/package.json +++ b/package.json @@ -735,13 +735,13 @@ }, "scripts": { "vscode:prepublish": "npm run cleanReadme", - "build": "tsc && gulp webpack-prod", + "build": "tsc", "cleanReadme": "gulp cleanReadme", "compile": "tsc -watch", "package": "vsce package --githubBranch main --no-dependencies", "lint": "eslint --ext .ts .", "lint-fix": "eslint --ext .ts . --fix", - "pretest": "gulp preTest", + "pretest": "npm run webpack-prod", "test": "node ./dist/test/runTest.js", "webpack": "tsc && gulp webpack-dev", "webpack-profile": "webpack --profile --json --mode production > webpack-stats.json && echo Use http://webpack.github.io/analyse to analyze the stats", diff --git a/test/ingress/IngressPromptStep.test.ts b/test/ingress/IngressPromptStep.test.ts index 4b754fd07..2846fc324 100644 --- a/test/ingress/IngressPromptStep.test.ts +++ b/test/ingress/IngressPromptStep.test.ts @@ -5,16 +5,17 @@ import { AzExtFsExtra } from "@microsoft/vscode-azext-utils"; import * as assert from "assert"; -import * as path from "path"; +import { type Uri } from "vscode"; import { tryConfigureIngressUsingDockerfile, type IngressContext } from "../../extension.bundle"; +import { getWorkspaceFolderUri } from "../testUtils"; import { wrapWithMockTelemetry } from "../wrapWithMockTelemetry"; import { type MockIngressContext } from "./MockIngressContext"; import { expectedSamplePorts } from "./tryGetDockerfileExposePorts.test"; suite('IngressPromptStep', async () => { test('tryConfigureIngressUsingDockerfile', async () => { - const dockerfileSamplesPath: string = path.join(__dirname, 'dockerfileSamples'); - const dockerfileSamples = await AzExtFsExtra.readDirectory(dockerfileSamplesPath); + const dockerfilesPath: Uri = getWorkspaceFolderUri('dockerfiles'); + const dockerfiles = await AzExtFsExtra.readDirectory(dockerfilesPath); const expectedResult: MockIngressContext[] = [ { enableIngress: true, enableExternal: true, dockerfileExposePorts: expectedSamplePorts[0], targetPort: 443 }, @@ -26,7 +27,7 @@ suite('IngressPromptStep', async () => { { enableIngress: false, enableExternal: false, dockerfileExposePorts: undefined, targetPort: undefined }, // no expose ]; - for (const [i, ds] of dockerfileSamples.entries()) { + for (const [i, ds] of dockerfiles.entries()) { const context: MockIngressContext = { dockerfilePath: i === 1 ? undefined : ds.fsPath, alwaysPromptIngress: i === 3 diff --git a/test/ingress/tryGetDockerfileExposePorts.test.ts b/test/ingress/tryGetDockerfileExposePorts.test.ts index 347f3a261..2d0d2b83d 100644 --- a/test/ingress/tryGetDockerfileExposePorts.test.ts +++ b/test/ingress/tryGetDockerfileExposePorts.test.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from "assert"; -import * as path from "path"; +import { type Uri } from "vscode"; import { AzExtFsExtra, PortRange, tryGetDockerfileExposePorts } from "../../extension.bundle"; +import { getWorkspaceFolderUri } from "../testUtils"; /** * Expected port values for the ingress Dockerfile test samples @@ -22,10 +23,10 @@ export const expectedSamplePorts: PortRange[][] = [ suite('tryGetDockerfileExposePorts', async () => { test('Correctly detects all Dockerfile sample expose ports', async () => { - const dockerfileSamplesPath: string = path.join(__dirname, 'dockerfileSamples'); - const dockerfileSamples = await AzExtFsExtra.readDirectory(dockerfileSamplesPath); + const dockerfilesPath: Uri = getWorkspaceFolderUri('dockerfiles'); + const dockerfiles = await AzExtFsExtra.readDirectory(dockerfilesPath); - for (const [i, ds] of dockerfileSamples.entries()) { + for (const [i, ds] of dockerfiles.entries()) { const portRange: PortRange[] = await tryGetDockerfileExposePorts(ds.fsPath) ?? []; for (const [j, pr] of portRange.entries()) { diff --git a/test/test.code-workspace b/test/test.code-workspace index 44949d696..dbdec9725 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -1,7 +1,7 @@ { "folders": [ { - "path": "./testWorkspace" + "path": "./testProject/dockerfiles" } ] } diff --git a/test/ingress/dockerfileSamples/sample1.Dockerfile b/test/testProject/dockerfiles/sample1.Dockerfile similarity index 100% rename from test/ingress/dockerfileSamples/sample1.Dockerfile rename to test/testProject/dockerfiles/sample1.Dockerfile diff --git a/test/ingress/dockerfileSamples/sample2.Dockerfile b/test/testProject/dockerfiles/sample2.Dockerfile similarity index 100% rename from test/ingress/dockerfileSamples/sample2.Dockerfile rename to test/testProject/dockerfiles/sample2.Dockerfile diff --git a/test/ingress/dockerfileSamples/sample3.Dockerfile b/test/testProject/dockerfiles/sample3.Dockerfile similarity index 100% rename from test/ingress/dockerfileSamples/sample3.Dockerfile rename to test/testProject/dockerfiles/sample3.Dockerfile diff --git a/test/ingress/dockerfileSamples/sample4.Dockerfile b/test/testProject/dockerfiles/sample4.Dockerfile similarity index 100% rename from test/ingress/dockerfileSamples/sample4.Dockerfile rename to test/testProject/dockerfiles/sample4.Dockerfile diff --git a/test/ingress/dockerfileSamples/sample5.Dockerfile b/test/testProject/dockerfiles/sample5.Dockerfile similarity index 100% rename from test/ingress/dockerfileSamples/sample5.Dockerfile rename to test/testProject/dockerfiles/sample5.Dockerfile diff --git a/test/ingress/dockerfileSamples/sample6.Dockerfile b/test/testProject/dockerfiles/sample6.Dockerfile similarity index 100% rename from test/ingress/dockerfileSamples/sample6.Dockerfile rename to test/testProject/dockerfiles/sample6.Dockerfile diff --git a/test/ingress/dockerfileSamples/sample7.Dockerfile b/test/testProject/dockerfiles/sample7.Dockerfile similarity index 100% rename from test/ingress/dockerfileSamples/sample7.Dockerfile rename to test/testProject/dockerfiles/sample7.Dockerfile diff --git a/test/testUtils.ts b/test/testUtils.ts new file mode 100644 index 000000000..6704f2b7f --- /dev/null +++ b/test/testUtils.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as path from 'path'; +import { workspace, type Uri, type WorkspaceFolder } from "vscode"; + +export function getWorkspaceFolderUri(folderName: string): Uri { + let workspaceFolderUri: Uri | undefined; + + const workspaceFolders: readonly WorkspaceFolder[] | undefined = workspace.workspaceFolders; + if (!workspaceFolders || workspaceFolders.length === 0) { + throw new Error('No workspace is open'); + } else { + for (const workspaceFolder of workspaceFolders) { + if (workspaceFolder.name === folderName) { + workspaceFolderUri = workspaceFolder.uri; + assert.strictEqual(path.basename(workspaceFolderUri.fsPath), folderName, 'Opened against an unexpected workspace.'); + return workspaceFolderUri; + } + } + } + + throw new Error(`Unable to find workspace folder "${folderName}"`); +} From 50cc37f2e1f5249671be786ce405fc1cee9ffd42 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 24 May 2024 10:31:03 -0700 Subject: [PATCH 02/54] Update package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 73f780033..06bef6e5f 100644 --- a/package.json +++ b/package.json @@ -743,7 +743,8 @@ "lint-fix": "eslint --ext .ts . --fix", "pretest": "npm run webpack-prod", "test": "node ./dist/test/runTest.js", - "webpack": "tsc && gulp webpack-dev", + "webpack": "npm run build && gulp webpack-dev", + "webpack-prod": "npm run build && gulp webpack-prod", "webpack-profile": "webpack --profile --json --mode production > webpack-stats.json && echo Use http://webpack.github.io/analyse to analyze the stats", "prepare": "husky install" }, From dc539326b5e0262643427ed9b38f528e85b0882f Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 24 May 2024 10:47:27 -0700 Subject: [PATCH 03/54] Fix prepublish --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06bef6e5f..cf087931f 100644 --- a/package.json +++ b/package.json @@ -734,7 +734,7 @@ } }, "scripts": { - "vscode:prepublish": "npm run cleanReadme", + "vscode:prepublish": "npm run webpack-prod", "build": "tsc", "cleanReadme": "gulp cleanReadme", "compile": "tsc -watch", From f235e50d68a8f8166e2c3c10936d72056e2860bb Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 24 May 2024 10:59:24 -0700 Subject: [PATCH 04/54] Update testProjects folder name --- test/test.code-workspace | 3 ++- .../dockerfiles/sample1.Dockerfile | 0 .../dockerfiles/sample2.Dockerfile | 0 .../dockerfiles/sample3.Dockerfile | 0 .../dockerfiles/sample4.Dockerfile | 0 .../dockerfiles/sample5.Dockerfile | 0 .../dockerfiles/sample6.Dockerfile | 0 .../dockerfiles/sample7.Dockerfile | 0 8 files changed, 2 insertions(+), 1 deletion(-) rename test/{testProject => testProjects}/dockerfiles/sample1.Dockerfile (100%) rename test/{testProject => testProjects}/dockerfiles/sample2.Dockerfile (100%) rename test/{testProject => testProjects}/dockerfiles/sample3.Dockerfile (100%) rename test/{testProject => testProjects}/dockerfiles/sample4.Dockerfile (100%) rename test/{testProject => testProjects}/dockerfiles/sample5.Dockerfile (100%) rename test/{testProject => testProjects}/dockerfiles/sample6.Dockerfile (100%) rename test/{testProject => testProjects}/dockerfiles/sample7.Dockerfile (100%) diff --git a/test/test.code-workspace b/test/test.code-workspace index dbdec9725..4411dceb3 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -1,7 +1,8 @@ { "folders": [ { - "path": "./testProject/dockerfiles" + "name": "dockerfiles", + "path": "./testProjects/dockerfiles" } ] } diff --git a/test/testProject/dockerfiles/sample1.Dockerfile b/test/testProjects/dockerfiles/sample1.Dockerfile similarity index 100% rename from test/testProject/dockerfiles/sample1.Dockerfile rename to test/testProjects/dockerfiles/sample1.Dockerfile diff --git a/test/testProject/dockerfiles/sample2.Dockerfile b/test/testProjects/dockerfiles/sample2.Dockerfile similarity index 100% rename from test/testProject/dockerfiles/sample2.Dockerfile rename to test/testProjects/dockerfiles/sample2.Dockerfile diff --git a/test/testProject/dockerfiles/sample3.Dockerfile b/test/testProjects/dockerfiles/sample3.Dockerfile similarity index 100% rename from test/testProject/dockerfiles/sample3.Dockerfile rename to test/testProjects/dockerfiles/sample3.Dockerfile diff --git a/test/testProject/dockerfiles/sample4.Dockerfile b/test/testProjects/dockerfiles/sample4.Dockerfile similarity index 100% rename from test/testProject/dockerfiles/sample4.Dockerfile rename to test/testProjects/dockerfiles/sample4.Dockerfile diff --git a/test/testProject/dockerfiles/sample5.Dockerfile b/test/testProjects/dockerfiles/sample5.Dockerfile similarity index 100% rename from test/testProject/dockerfiles/sample5.Dockerfile rename to test/testProjects/dockerfiles/sample5.Dockerfile diff --git a/test/testProject/dockerfiles/sample6.Dockerfile b/test/testProjects/dockerfiles/sample6.Dockerfile similarity index 100% rename from test/testProject/dockerfiles/sample6.Dockerfile rename to test/testProjects/dockerfiles/sample6.Dockerfile diff --git a/test/testProject/dockerfiles/sample7.Dockerfile b/test/testProjects/dockerfiles/sample7.Dockerfile similarity index 100% rename from test/testProject/dockerfiles/sample7.Dockerfile rename to test/testProjects/dockerfiles/sample7.Dockerfile From 7aa9d80c464e993f52755c9b4c2a9bf40495c3ad Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:47:36 -0700 Subject: [PATCH 05/54] Use blank pretest script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cf087931f..382de82b9 100644 --- a/package.json +++ b/package.json @@ -741,7 +741,7 @@ "package": "vsce package --githubBranch main --no-dependencies", "lint": "eslint --ext .ts .", "lint-fix": "eslint --ext .ts . --fix", - "pretest": "npm run webpack-prod", + "pretest": "", "test": "node ./dist/test/runTest.js", "webpack": "npm run build && gulp webpack-dev", "webpack-prod": "npm run build && gulp webpack-prod", From c93618e64b791133b582b3a641f17904ef65e036 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:50:39 -0700 Subject: [PATCH 06/54] Update tools deps --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5a958553..6cf65b54d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@azure/storage-blob": "^12.4.1", "@microsoft/vscode-azext-azureutils": "^2.0.3", "@microsoft/vscode-azext-github": "^1.0.0", - "@microsoft/vscode-azext-utils": "^2.1.5", + "@microsoft/vscode-azext-utils": "^2.5.1", "@microsoft/vscode-azureresources-api": "^2.0.2", "buffer": "^6.0.3", "dayjs": "^1.11.3", @@ -34,7 +34,7 @@ "devDependencies": { "@azure/ms-rest-azure-env": "^2.0.0", "@microsoft/eslint-config-azuretools": "^0.2.2", - "@microsoft/vscode-azext-dev": "^2.0.1", + "@microsoft/vscode-azext-dev": "^2.0.4", "@types/deep-eql": "^4.0.0", "@types/fs-extra": "^8.1.1", "@types/gulp": "^4.0.6", @@ -859,9 +859,9 @@ } }, "node_modules/@microsoft/vscode-azext-dev": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-dev/-/vscode-azext-dev-2.0.1.tgz", - "integrity": "sha512-kZSNzytI0rIvEiLvkthmOABfC+I6ePvuPCepwCwIBRy3Z27AvfilHEbbT86l1F0vE/ng7r7vQ7QEVP2qypW7fQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-dev/-/vscode-azext-dev-2.0.4.tgz", + "integrity": "sha512-+XZenjPrfsEc3OPMOdPBVCgPsTvx6h1BVItf5mUoRC3lfN3Gv8OZF80VIETnC9Gj5nB+9nDpQWDzj9V/+2ZS/g==", "dev": true, "dependencies": { "assert": "^2.0.0", @@ -952,9 +952,9 @@ } }, "node_modules/@microsoft/vscode-azext-utils": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.1.5.tgz", - "integrity": "sha512-QmSEWeWh19MIj65Xl+lOb4Sa9CnNBA1nAeclWpHXPH9okm8Tp75a0YJmhWF67vFL86PYe83hikiObumYvJzhzg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.1.tgz", + "integrity": "sha512-K9S25xSZ5jEy5ofsLGdgzdXkyqzYhdJuBNkSRMa/7Qt6S+YtspQ4qwX6gNGvlMHE3gPAXDHqxvn+yPmm4s5uYg==", "dependencies": { "@microsoft/vscode-azureresources-api": "^2.0.4", "@vscode/extension-telemetry": "^0.9.0", @@ -12526,9 +12526,9 @@ } }, "@microsoft/vscode-azext-dev": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-dev/-/vscode-azext-dev-2.0.1.tgz", - "integrity": "sha512-kZSNzytI0rIvEiLvkthmOABfC+I6ePvuPCepwCwIBRy3Z27AvfilHEbbT86l1F0vE/ng7r7vQ7QEVP2qypW7fQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-dev/-/vscode-azext-dev-2.0.4.tgz", + "integrity": "sha512-+XZenjPrfsEc3OPMOdPBVCgPsTvx6h1BVItf5mUoRC3lfN3Gv8OZF80VIETnC9Gj5nB+9nDpQWDzj9V/+2ZS/g==", "dev": true, "requires": { "assert": "^2.0.0", @@ -12609,9 +12609,9 @@ } }, "@microsoft/vscode-azext-utils": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.1.5.tgz", - "integrity": "sha512-QmSEWeWh19MIj65Xl+lOb4Sa9CnNBA1nAeclWpHXPH9okm8Tp75a0YJmhWF67vFL86PYe83hikiObumYvJzhzg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.1.tgz", + "integrity": "sha512-K9S25xSZ5jEy5ofsLGdgzdXkyqzYhdJuBNkSRMa/7Qt6S+YtspQ4qwX6gNGvlMHE3gPAXDHqxvn+yPmm4s5uYg==", "requires": { "@microsoft/vscode-azureresources-api": "^2.0.4", "@vscode/extension-telemetry": "^0.9.0", diff --git a/package.json b/package.json index 382de82b9..ec60549a2 100644 --- a/package.json +++ b/package.json @@ -751,7 +751,7 @@ "devDependencies": { "@azure/ms-rest-azure-env": "^2.0.0", "@microsoft/eslint-config-azuretools": "^0.2.2", - "@microsoft/vscode-azext-dev": "^2.0.1", + "@microsoft/vscode-azext-dev": "^2.0.4", "@types/deep-eql": "^4.0.0", "@types/fs-extra": "^8.1.1", "@types/gulp": "^4.0.6", @@ -787,7 +787,7 @@ "@azure/storage-blob": "^12.4.1", "@microsoft/vscode-azext-azureutils": "^2.0.3", "@microsoft/vscode-azext-github": "^1.0.0", - "@microsoft/vscode-azext-utils": "^2.1.5", + "@microsoft/vscode-azext-utils": "^2.5.1", "@microsoft/vscode-azureresources-api": "^2.0.2", "buffer": "^6.0.3", "dayjs": "^1.11.3", From da2544b3956a2365e6e389711230cd2080f5a115 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:53:58 -0700 Subject: [PATCH 07/54] SharedResourcesNameStep --- .../internal/SharedResourcesNameStep.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts index 7fc5e85bf..2ea69443e 100644 --- a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts +++ b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts @@ -39,6 +39,10 @@ export class SharedResourcesNameStep extends AzureWizardPromptStep Date: Thu, 13 Jun 2024 10:54:20 -0700 Subject: [PATCH 08/54] EnvironmentVariablesListStep --- .../getStartingConfiguration.ts | 2 +- .../imageSource/EnvironmentVariablesListStep.ts | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/commands/deployWorkspaceProject/internal/startingConfiguration/getStartingConfiguration.ts b/src/commands/deployWorkspaceProject/internal/startingConfiguration/getStartingConfiguration.ts index 79472cf5b..f05d26e31 100644 --- a/src/commands/deployWorkspaceProject/internal/startingConfiguration/getStartingConfiguration.ts +++ b/src/commands/deployWorkspaceProject/internal/startingConfiguration/getStartingConfiguration.ts @@ -46,7 +46,7 @@ export async function getStartingConfiguration(context: DeployWorkspaceProjectIn environmentVariables: context.envPath ? undefined /** No need to set anything if there's an envPath, the step will handle parsing the data for us */ : - await EnvironmentVariablesListStep.workspaceHasEnvFile() ? undefined : [] /** The equivalent of "skipForNow" */, + await EnvironmentVariablesListStep.workspaceHasEnvFile(context.rootFolder) ? undefined : [] /** The equivalent of "skipForNow" */, }; } diff --git a/src/commands/image/imageSource/EnvironmentVariablesListStep.ts b/src/commands/image/imageSource/EnvironmentVariablesListStep.ts index 04b916902..ff4e14952 100644 --- a/src/commands/image/imageSource/EnvironmentVariablesListStep.ts +++ b/src/commands/image/imageSource/EnvironmentVariablesListStep.ts @@ -6,7 +6,7 @@ import { type EnvironmentVar } from "@azure/arm-appcontainers"; import { AzExtFsExtra, AzureWizardPromptStep, GenericTreeItem, activitySuccessContext, activitySuccessIcon } from "@microsoft/vscode-azext-utils"; import { parse, type DotenvParseOutput } from "dotenv"; -import { workspace, type Uri } from "vscode"; +import { RelativePattern, workspace, type Uri, type WorkspaceFolder } from "vscode"; import { ImageSource, envFileGlobPattern } from "../../../constants"; import { ext } from "../../../extensionVariables"; import { type EnvironmentVariableTelemetryProps as TelemetryProps } from "../../../telemetry/ImageSourceTelemetryProps"; @@ -84,8 +84,14 @@ export class EnvironmentVariablesListStep extends AzureWizardPromptStep { return { name, value: envData[name] } }); } - public static async workspaceHasEnvFile(): Promise { - const envFileUris: Uri[] = await workspace.findFiles(allEnvFilesGlobPattern); + public static async workspaceHasEnvFile(rootFolder?: WorkspaceFolder): Promise { + let envFileUris: Uri[]; + if (rootFolder) { + const relativePattern: RelativePattern = new RelativePattern(rootFolder, allEnvFilesGlobPattern); + envFileUris = await workspace.findFiles(relativePattern); + } else { + envFileUris = await workspace.findFiles(allEnvFilesGlobPattern); + } return !!envFileUris.length; } From b6a1ebbe5760952acfafce441dc6b05f9582e98d Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:55:13 -0700 Subject: [PATCH 09/54] settingUtils --- .../deployWorkspaceProject/settings/dwpSettingUtilsV2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/deployWorkspaceProject/settings/dwpSettingUtilsV2.ts b/src/commands/deployWorkspaceProject/settings/dwpSettingUtilsV2.ts index 32d00e081..6c6787569 100644 --- a/src/commands/deployWorkspaceProject/settings/dwpSettingUtilsV2.ts +++ b/src/commands/deployWorkspaceProject/settings/dwpSettingUtilsV2.ts @@ -8,7 +8,7 @@ import { settingUtils } from "../../../utils/settingUtils"; import { type DeploymentConfigurationSettings } from "./DeployWorkspaceProjectSettingsV2"; export namespace dwpSettingUtilsV2 { - const deploymentConfigurationsSetting: string = 'deploymentConfigurations'; + export const deploymentConfigurationsSetting: string = 'deploymentConfigurations'; export async function getWorkspaceDeploymentConfigurations(rootFolder: WorkspaceFolder): Promise { const settingsPath: string = settingUtils.getDefaultRootWorkspaceSettingsPath(rootFolder); From d86efde30e198d5b76e29e8d71e5fbd4d6d90f65 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:56:10 -0700 Subject: [PATCH 10/54] Use path lib for TarFileStep --- .../image/imageSource/buildImageInAzure/TarFileStep.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/image/imageSource/buildImageInAzure/TarFileStep.ts b/src/commands/image/imageSource/buildImageInAzure/TarFileStep.ts index 6423cb402..b907ba376 100644 --- a/src/commands/image/imageSource/buildImageInAzure/TarFileStep.ts +++ b/src/commands/image/imageSource/buildImageInAzure/TarFileStep.ts @@ -5,7 +5,7 @@ import { AzureWizardExecuteStep } from "@microsoft/vscode-azext-utils"; import * as os from 'os'; -import { URI, Utils } from "vscode-uri"; +import * as path from "path"; import { type BuildImageInAzureImageSourceContext } from "./BuildImageInAzureImageSourceContext"; const idPrecision = 6; @@ -16,7 +16,7 @@ export class TarFileStep extends AzureWizardExecuteStep { const id: number = Math.floor(Math.random() * Math.pow(10, idPrecision)); const archive = `sourceArchive${id}.tar.gz`; - context.tarFilePath = Utils.joinPath(URI.parse(os.tmpdir()), archive).fsPath; + context.tarFilePath = path.join(os.tmpdir(), archive); } public shouldExecute(context: BuildImageInAzureImageSourceContext): boolean { From 2a5a692070d561a0d217efd73e9d8ee83d533762 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:00:40 -0700 Subject: [PATCH 11/54] Update getRootWorkspaceFolder --- .../imageSource/buildImageInAzure/RootFolderStep.ts | 2 +- src/utils/workspaceUtils.ts | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/commands/image/imageSource/buildImageInAzure/RootFolderStep.ts b/src/commands/image/imageSource/buildImageInAzure/RootFolderStep.ts index 601f76b53..91c0c5928 100644 --- a/src/commands/image/imageSource/buildImageInAzure/RootFolderStep.ts +++ b/src/commands/image/imageSource/buildImageInAzure/RootFolderStep.ts @@ -14,7 +14,7 @@ import { type BuildImageInAzureImageSourceContext } from './BuildImageInAzureIma export class RootFolderStep extends AzureWizardPromptStep { public async prompt(context: BuildImageInAzureImageSourceContext): Promise { const prompt: string = localize('selectRootWorkspace', 'Select a project with a Dockerfile'); - const rootFolder: WorkspaceFolder | undefined = await getRootWorkspaceFolder(prompt); + const rootFolder: WorkspaceFolder | undefined = await getRootWorkspaceFolder(context, prompt); if (!rootFolder) { context.telemetry.properties.hasWorkspaceProjectOpen = 'false'; diff --git a/src/utils/workspaceUtils.ts b/src/utils/workspaceUtils.ts index 690bf4480..61e71b45d 100644 --- a/src/utils/workspaceUtils.ts +++ b/src/utils/workspaceUtils.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { UserCancelledError, type IActionContext, type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils"; +import { type IActionContext, type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils"; import { basename } from "path"; -import { Uri, window, workspace, type OpenDialogOptions, type WorkspaceFolder } from "vscode"; +import { Uri, workspace, type OpenDialogOptions, type WorkspaceFolder } from "vscode"; import { browseItem, dockerfileGlobPattern, envFileGlobPattern } from "../constants"; import { type SetTelemetryProps } from "../telemetry/SetTelemetryProps"; import { type WorkspaceFileTelemetryProps as TelemetryProps } from "../telemetry/WorkspaceFileTelemetryProps"; @@ -91,17 +91,13 @@ export async function selectWorkspaceFile( } } -export async function getRootWorkspaceFolder(placeHolder?: string): Promise { +export async function getRootWorkspaceFolder(context: IActionContext, placeHolder?: string): Promise { if (!workspace.workspaceFolders?.length) { return undefined; } else if (workspace.workspaceFolders?.length === 1) { return workspace.workspaceFolders[0]; } else { - const folder = await window.showWorkspaceFolderPick({ placeHolder: placeHolder ?? localize('selectRootWorkspace', 'Select a folder for your workspace') }); - if (!folder) { - throw new UserCancelledError('selectRootWorkspace'); - } - return folder; + return await context.ui.showWorkspaceFolderPick({ placeHolder }); } } From 0f21b64498c5e1808e4ce40a5d6928ebfbda3db2 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:03:26 -0700 Subject: [PATCH 12/54] Revert --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec60549a2..86fd14720 100644 --- a/package.json +++ b/package.json @@ -741,7 +741,7 @@ "package": "vsce package --githubBranch main --no-dependencies", "lint": "eslint --ext .ts .", "lint-fix": "eslint --ext .ts . --fix", - "pretest": "", + "pretest": "npm run webpack-prod", "test": "node ./dist/test/runTest.js", "webpack": "npm run build && gulp webpack-dev", "webpack-prod": "npm run build && gulp webpack-prod", From 51592b3b72023828ba5c59a7c8e0c61cd246bc57 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:39:08 -0700 Subject: [PATCH 13/54] Update comment --- .../deployWorkspaceProject/internal/SharedResourcesNameStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts index 2ea69443e..ecb295dbd 100644 --- a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts +++ b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts @@ -41,7 +41,7 @@ export class SharedResourcesNameStep extends AzureWizardPromptStep Date: Thu, 13 Jun 2024 11:43:27 -0700 Subject: [PATCH 14/54] Update SharedResourcesNameStep --- .../internal/SharedResourcesNameStep.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts index ecb295dbd..96bd9c6be 100644 --- a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts +++ b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts @@ -41,8 +41,8 @@ export class SharedResourcesNameStep extends AzureWizardPromptStep Date: Thu, 13 Jun 2024 11:55:58 -0700 Subject: [PATCH 15/54] Monorepo test scaffold --- extension.bundle.ts | 11 +- package.json | 9 +- .../deployWorkspaceProject.test.ts | 54 ++++++++ .../deployWorkspaceProject/dwpTestUtils.ts | 47 +++++++ .../DeployWorkspaceProjectTestCase.ts | 36 ++++++ .../testCases/monoRepoBasicTestCases.ts | 116 ++++++++++++++++++ .../deployWorkspaceProject/testScenarios.ts | 26 ++++ test/nightly/global.nightly.test.ts | 18 +++ test/testUtils.ts | 15 +++ test/typeUtils.ts | 11 ++ 10 files changed, 337 insertions(+), 6 deletions(-) create mode 100644 test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts create mode 100644 test/nightly/deployWorkspaceProject/dwpTestUtils.ts create mode 100644 test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts create mode 100644 test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts create mode 100644 test/nightly/deployWorkspaceProject/testScenarios.ts create mode 100644 test/nightly/global.nightly.test.ts create mode 100644 test/typeUtils.ts diff --git a/extension.bundle.ts b/extension.bundle.ts index 5416da456..f27dde214 100644 --- a/extension.bundle.ts +++ b/extension.bundle.ts @@ -16,13 +16,22 @@ // At runtime the tests live in dist/tests and will therefore pick up the main webpack bundle at dist/extension.bundle.js. export * from '@microsoft/vscode-azext-utils'; // Export activate/deactivate for main.js +export * from './src/commands/deployWorkspaceProject/deployWorkspaceProject'; +export * from './src/commands/deployWorkspaceProject/getDeployWorkspaceProjectResults'; export * from './src/commands/deployWorkspaceProject/internal/DeployWorkspaceProjectInternalContext'; +export * from './src/commands/deployWorkspaceProject/settings/DeployWorkspaceProjectSettingsV1'; +export * from './src/commands/deployWorkspaceProject/settings/DeployWorkspaceProjectSettingsV2'; +export * from './src/commands/deployWorkspaceProject/settings/dwpSettingUtilsV1'; +export * from './src/commands/deployWorkspaceProject/settings/dwpSettingUtilsV2'; +export * from './src/commands/IContainerAppContext'; +export * from './src/commands/ingress/editTargetPort/getDefaultPort'; export * from './src/commands/ingress/IngressContext'; export * from './src/commands/ingress/IngressPromptStep'; -export * from './src/commands/ingress/editTargetPort/getDefaultPort'; export * from './src/commands/ingress/tryGetDockerfileExposePorts'; export { activate, deactivate } from './src/extension'; export * from './src/extensionVariables'; +export * from './src/utils/azureClients'; +export * from './src/utils/settingUtils'; export * from './src/utils/validateUtils'; // NOTE: The auto-fix action "source.organizeImports" does weird things with this file, but there doesn't seem to be a way to disable it on a per-file basis so we'll just let it happen diff --git a/package.json b/package.json index 86fd14720..2470a0ce0 100644 --- a/package.json +++ b/package.json @@ -734,17 +734,16 @@ } }, "scripts": { - "vscode:prepublish": "npm run webpack-prod", - "build": "tsc", + "vscode:prepublish": "npm run cleanReadme", + "build": "tsc && gulp webpack-prod", "cleanReadme": "gulp cleanReadme", "compile": "tsc -watch", "package": "vsce package --githubBranch main --no-dependencies", "lint": "eslint --ext .ts .", "lint-fix": "eslint --ext .ts . --fix", - "pretest": "npm run webpack-prod", + "pretest": "", "test": "node ./dist/test/runTest.js", - "webpack": "npm run build && gulp webpack-dev", - "webpack-prod": "npm run build && gulp webpack-prod", + "webpack": "tsc && gulp webpack-dev", "webpack-profile": "webpack --profile --json --mode production > webpack-stats.json && echo Use http://webpack.github.io/analyse to analyze the stats", "prepare": "husky install" }, diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts new file mode 100644 index 000000000..ec6017e38 --- /dev/null +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -0,0 +1,54 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { runWithTestActionContext } from '@microsoft/vscode-azext-dev'; +import * as assert from 'assert'; +import * as path from 'path'; +import { workspace, type Uri, type WorkspaceFolder } from 'vscode'; +import { AzExtFsExtra, deployWorkspaceProject, dwpSettingUtilsV2, settingUtils, type DeploymentConfigurationSettings, type DeployWorkspaceProjectResults } from '../../../extension.bundle'; +import { assertStringPropsMatch, getWorkspaceFolderUri } from '../../testUtils'; +import { testScenarios } from './testScenarios'; + +suite('deployWorkspaceProject', function (this: Mocha.Suite) { + for (const scenario of testScenarios) { + suite(scenario.label, function () { + const workspaceFolderUri: Uri = getWorkspaceFolderUri(scenario.folderName); + const rootFolder: WorkspaceFolder | undefined = workspace.getWorkspaceFolder(workspaceFolderUri); + assert.ok(rootFolder, 'Could not retrieve root workspace folder.'); + + suiteSetup(async function () { + console.log('running suite setup for: ', workspaceFolderUri.fsPath) + const settingsPath: string = settingUtils.getDefaultRootWorkspaceSettingsPath(rootFolder); + const vscodeFolderPath: string = path.dirname(settingsPath); + if (await AzExtFsExtra.pathExists(vscodeFolderPath)) { + AzExtFsExtra.deleteResource(vscodeFolderPath, { recursive: true }); + } + }); + + // add same reset logic for suiteTeardown + + for (const testCase of scenario.testCases) { + test(testCase.label, async function () { + await runWithTestActionContext('deployWorkspaceProject', async context => { + await context.ui.runWithInputs(testCase.inputs, async () => { + console.log("starting test for: ", testCase.label) + const results: DeployWorkspaceProjectResults = await deployWorkspaceProject(context); + console.log("finished running: ", testCase.label) + assertStringPropsMatch(results as Partial>, testCase.expectedResults as Record, 'DeployWorkspaceProject results mismatch.'); + + const deploymentConfigurationsV2: DeploymentConfigurationSettings[] = await dwpSettingUtilsV2.getWorkspaceDeploymentConfigurations(rootFolder) ?? []; + for (const [i, expectedDeploymentConfiguration] of (testCase.expectedVSCodeSettings?.deploymentConfigurations ?? []).entries()) { + const deploymentConfiguration: DeploymentConfigurationSettings = deploymentConfigurationsV2[i] ?? {}; + assertStringPropsMatch(deploymentConfiguration as Partial>, expectedDeploymentConfiguration, 'DeployWorkspaceProject ".vscode" saved settings mismatch.'); + } + + await testCase.postTestAssertion?.(context, results, 'DeployWorkspaceProject resource settings mismatch.'); + }); + }); + }); + } + }); + } +}); diff --git a/test/nightly/deployWorkspaceProject/dwpTestUtils.ts b/test/nightly/deployWorkspaceProject/dwpTestUtils.ts new file mode 100644 index 000000000..e7eb2c003 --- /dev/null +++ b/test/nightly/deployWorkspaceProject/dwpTestUtils.ts @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { type ContainerApp, type EnvironmentVar } from "@azure/arm-appcontainers"; +import { parseAzureResourceId } from "@microsoft/vscode-azext-azureutils"; +import { createSubscriptionContext, nonNullProp, subscriptionExperience, type IActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils"; +import { type AzureSubscription } from "@microsoft/vscode-azureresources-api"; +import * as assert from "assert"; +import { createContainerAppsAPIClient, ext, type DeployWorkspaceProjectResults } from "../../../extension.bundle"; +import { type StringOrRegExpProps } from "../../typeUtils"; +import { type PostTestAssertion } from "./testCases/DeployWorkspaceProjectTestCase"; + +export namespace dwpTestUtils { + export function generateExpectedResults(sharedResourceName: string, acrResourceName: string, appResourceName: string): StringOrRegExpProps { + return { + containerAppId: new RegExp(`\/resourceGroups\/${sharedResourceName}\/providers\/Microsoft\.App\/containerApps\/${appResourceName}`, 'i'), + imageName: new RegExp(appResourceName, 'i'), + logAnalyticsWorkspaceId: new RegExp(`\/resourceGroups\/${sharedResourceName}\/providers\/Microsoft\.OperationalInsights\/workspaces\/${sharedResourceName}`, 'i'), + managedEnvironmentId: new RegExp(`\/resourceGroups\/${sharedResourceName}\/providers\/Microsoft\.App\/managedEnvironments\/${sharedResourceName}`, 'i'), + registryId: new RegExp(`\/resourceGroups\/${sharedResourceName}\/providers\/Microsoft\.ContainerRegistry\/registries\/${acrResourceName}.{6}`, 'i'), + registryLoginServer: new RegExp(`${acrResourceName}.{6}\.azurecr\.io`, 'i'), + registryPassword: new RegExp('.*'), + registryUsername: new RegExp(`${acrResourceName}.{6}`, 'i'), + resourceGroupId: new RegExp(`\/resourceGroups\/${sharedResourceName}`, 'i') + }; + } + + export function generatePostTestAssertion(expectedContainerAppSettings: { targetPort: number | undefined, env: EnvironmentVar[] | undefined }): PostTestAssertion { + return async function postTestAssertion(context: IActionContext, resources: DeployWorkspaceProjectResults, errMsg?: string): Promise { + const parsedId = parseAzureResourceId(nonNullProp(resources, 'containerAppId')); + + const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider, { + selectBySubscriptionId: parsedId.subscriptionId, + showLoadingPrompt: false + }); + const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); + + const client = await createContainerAppsAPIClient(Object.assign(context, subscriptionContext)); + const containerApp: ContainerApp = await client.containerApps.get(parsedId.resourceGroup, parsedId.resourceName); + assert.strictEqual(containerApp.configuration?.ingress?.targetPort, expectedContainerAppSettings.targetPort, errMsg ? errMsg + ' (container app target port)' : undefined); + assert.strictEqual(containerApp.template?.containers?.[0].image, `${resources.registryLoginServer}/${resources.imageName}`, errMsg ? errMsg + ' (container image name)' : undefined); + assert.deepStrictEqual(containerApp.template?.containers?.[0].env, expectedContainerAppSettings.env, errMsg ? errMsg + ' (container environment variables)' : undefined); + } + } +} diff --git a/test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts b/test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts new file mode 100644 index 000000000..b5d608bd8 --- /dev/null +++ b/test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { type DeploymentConfigurationSettings, type DeployWorkspaceProjectResults, type IActionContext } from "../../../../extension.bundle"; +import { type StringOrRegExpProps } from "../../../typeUtils"; + +export interface DeployWorkspaceProjectTestCase { + /** + * Label to display when executing the test + */ + label: string; + /** + * The list of inputs that will be passed directly to `TestUserInput.runWithInputs()` + */ + inputs: (string | RegExp)[]; + /** + * The expected results that should be returned after executing the command + */ + expectedResults?: StringOrRegExpProps; + /** + * The expected `.vscode` settings that should be present in the workspace folder root after executing the command + */ + expectedVSCodeSettings?: VSCodeSettings; + /** + * A post test callback that can be added for further verifying any of the created resources before final suite teardown + */ + postTestAssertion?: PostTestAssertion; +} + +export type PostTestAssertion = (context: IActionContext, results: DeployWorkspaceProjectResults, errMsg?: string) => void | Promise; + +export interface VSCodeSettings { + deploymentConfigurations?: StringOrRegExpProps[]; +} diff --git a/test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts b/test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts new file mode 100644 index 000000000..a71d76bc9 --- /dev/null +++ b/test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts @@ -0,0 +1,116 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { randomUtils } from "@microsoft/vscode-azext-utils"; +import * as path from "path"; +import { type DeploymentConfigurationSettings } from "../../../../extension.bundle"; +import { type StringOrRegExpProps } from "../../../typeUtils"; +import { dwpTestUtils } from "../dwpTestUtils"; +import { type DeployWorkspaceProjectTestCase } from "./DeployWorkspaceProjectTestCase"; + +export function generateMonoRepoBasicTestCases(): DeployWorkspaceProjectTestCase[] { + const sharedResourceName: string = 'monorepo-basic' + randomUtils.getRandomHexString(4); + const acrResourceName: string = sharedResourceName.replace(/[^a-zA-Z0-9]+/g, ''); + + return [ + { + label: "Deploy App 1", + inputs: [ + new RegExp('monorepo-basic', 'i'), + path.join('app1', 'Dockerfile'), + new RegExp('Create new container apps environment', 'i'), + 'Continue', + sharedResourceName, + 'app1', + `.${path.sep}app1`, + path.join('app1', '.env.example'), + 'East US', + 'Save' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, 'app1'), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app1') + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 3000, env: [{ name: 'MESSAGE', value: 'container apps (app1)' }] }) + }, + { + label: "Deploy App 2", + inputs: [ + new RegExp('monorepo-basic', 'i'), + new RegExp('Create and deploy new app configuration', 'i'), + path.join('app2', 'Dockerfile'), + new RegExp('(Recommended)', 'i'), // Select a container app environment + 'Continue', + 'app2', + `.${path.sep}app2`, + path.join('app2', '.env.example'), + 'Save' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, 'app2'), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app1'), + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app2'), + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 3001, env: [{ name: 'MESSAGE', value: 'container apps (app2)' }] }) + }, + { + label: "Deploy App 3", + inputs: [ + new RegExp('monorepo-basic', 'i'), + new RegExp('Create and deploy new app configuration', 'i'), + path.join('app3', 'Dockerfile'), + new RegExp('(Recommended)', 'i'), // Select a container app environment + 'Continue', + 'app3', + `.${path.sep}app3`, + path.join('app3', '.env.example'), + 'Save' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, 'app3'), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app1'), + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app2'), + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app3'), + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 3002, env: [{ name: 'MESSAGE', value: 'container apps (app3)' }] }) + }, + { + label: "Re-deploy App 1", + inputs: [ + new RegExp('monorepo-basic', 'i'), + 'app1', + 'Continue' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, 'app1'), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app1'), + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app2'), + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, 'app3'), + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 3000, env: [{ name: 'MESSAGE', value: 'container apps (app1)' }] }) + } + ]; +} + +function generateExpectedDeploymentConfiguration(sharedResourceName: string, acrResourceName: string, appResourceName: string): StringOrRegExpProps { + return { + label: appResourceName, + type: 'AcrDockerBuildRequest', + dockerfilePath: path.join(appResourceName, 'Dockerfile'), + srcPath: appResourceName, + envPath: path.join(appResourceName, '.env.example'), + resourceGroup: sharedResourceName, + containerApp: appResourceName, + containerRegistry: new RegExp(`${acrResourceName}.{6}`, 'i'), + }; +} diff --git a/test/nightly/deployWorkspaceProject/testScenarios.ts b/test/nightly/deployWorkspaceProject/testScenarios.ts new file mode 100644 index 000000000..4ddfbd0e5 --- /dev/null +++ b/test/nightly/deployWorkspaceProject/testScenarios.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { type DeployWorkspaceProjectTestCase } from "./testCases/DeployWorkspaceProjectTestCase"; +import { generateMonoRepoBasicTestCases } from "./testCases/monoRepoBasicTestCases"; + +interface TestScenario { + label: string; + folderName: string; + testCases: DeployWorkspaceProjectTestCase[]; +} + +export const testScenarios: TestScenario[] = [ + { + label: 'monorepo', + folderName: 'monorepo-basic', + testCases: generateMonoRepoBasicTestCases() + }, + // { + // label: 'albumapi-javascript', + // folderName: 'albumapi-javascript', + // testCases: generateAlbumApiJavaScriptTestCases() + // } +]; diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts new file mode 100644 index 000000000..92bedefd5 --- /dev/null +++ b/test/nightly/global.nightly.test.ts @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { longRunningTestsEnabled } from '../global.test'; + +export const resourceGroupsToDelete: string[] = []; + +suiteSetup(async function (this: Mocha.Context): Promise { + if (!longRunningTestsEnabled) { + return; + } + await vscode.commands.executeCommand('azureResourceGroups.logIn'); +}); + +// Add suiteteardown for resourcegroups diff --git a/test/testUtils.ts b/test/testUtils.ts index 6704f2b7f..c4d09d764 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -7,6 +7,21 @@ import * as assert from 'assert'; import * as path from 'path'; import { workspace, type Uri, type WorkspaceFolder } from "vscode"; +export function assertStringPropsMatch(results: Record, expectedResults: Record, errMsg?: string): void { + assert.strictEqual(Object.keys(results).length, Object.keys(expectedResults).length, errMsg); + + for (const key in expectedResults) { + const result: string | undefined = results[key]; + const expectedResult: string | RegExp | undefined = expectedResults[key]; + + if (result && expectedResult instanceof RegExp) { + assert.match(result, expectedResult, errMsg); + } else { + assert.strictEqual(result, expectedResult, errMsg); + } + } +} + export function getWorkspaceFolderUri(folderName: string): Uri { let workspaceFolderUri: Uri | undefined; diff --git a/test/typeUtils.ts b/test/typeUtils.ts new file mode 100644 index 000000000..5ad68cd23 --- /dev/null +++ b/test/typeUtils.ts @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Defines all object props to be either string or RegExp + */ +export type StringOrRegExpProps = { + [Prop in keyof T]: string | RegExp; +}; From a819e8c3dfffe291bd9fd37371996c44e9b4308a Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:27:01 -0700 Subject: [PATCH 16/54] Add method for cleaning workspace folder settings --- .../deployWorkspaceProject.test.ts | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts index ec6017e38..465919abf 100644 --- a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -11,31 +11,21 @@ import { AzExtFsExtra, deployWorkspaceProject, dwpSettingUtilsV2, settingUtils, import { assertStringPropsMatch, getWorkspaceFolderUri } from '../../testUtils'; import { testScenarios } from './testScenarios'; -suite('deployWorkspaceProject', function (this: Mocha.Suite) { +suite('deployWorkspaceProject', function () { for (const scenario of testScenarios) { suite(scenario.label, function () { const workspaceFolderUri: Uri = getWorkspaceFolderUri(scenario.folderName); const rootFolder: WorkspaceFolder | undefined = workspace.getWorkspaceFolder(workspaceFolderUri); assert.ok(rootFolder, 'Could not retrieve root workspace folder.'); - suiteSetup(async function () { - console.log('running suite setup for: ', workspaceFolderUri.fsPath) - const settingsPath: string = settingUtils.getDefaultRootWorkspaceSettingsPath(rootFolder); - const vscodeFolderPath: string = path.dirname(settingsPath); - if (await AzExtFsExtra.pathExists(vscodeFolderPath)) { - AzExtFsExtra.deleteResource(vscodeFolderPath, { recursive: true }); - } - }); - - // add same reset logic for suiteTeardown + suiteSetup(getMethodCleanWorkspaceFolderSettings(rootFolder)); + suiteTeardown(getMethodCleanWorkspaceFolderSettings(rootFolder)); for (const testCase of scenario.testCases) { test(testCase.label, async function () { await runWithTestActionContext('deployWorkspaceProject', async context => { await context.ui.runWithInputs(testCase.inputs, async () => { - console.log("starting test for: ", testCase.label) const results: DeployWorkspaceProjectResults = await deployWorkspaceProject(context); - console.log("finished running: ", testCase.label) assertStringPropsMatch(results as Partial>, testCase.expectedResults as Record, 'DeployWorkspaceProject results mismatch.'); const deploymentConfigurationsV2: DeploymentConfigurationSettings[] = await dwpSettingUtilsV2.getWorkspaceDeploymentConfigurations(rootFolder) ?? []; @@ -52,3 +42,14 @@ suite('deployWorkspaceProject', function (this: Mocha.Suite) { }); } }); + +function getMethodCleanWorkspaceFolderSettings(rootFolder: WorkspaceFolder) { + return async function cleanWorkspaceFolderSettings(): Promise { + const settingsPath: string = settingUtils.getDefaultRootWorkspaceSettingsPath(rootFolder); + const vscodeFolderPath: string = path.dirname(settingsPath); + if (await AzExtFsExtra.pathExists(vscodeFolderPath)) { + await AzExtFsExtra.deleteResource(vscodeFolderPath, { recursive: true }); + } + } +} + From 9831624c0cee02765cf03b0452bd2f3f72560444 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:46:07 -0700 Subject: [PATCH 17/54] Add delete resource groups functionality --- test/nightly/global.nightly.test.ts | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 92bedefd5..c5162a68e 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -3,7 +3,13 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { ResourceManagementClient } from '@azure/arm-resources'; +import { createAzureClient } from '@microsoft/vscode-azext-azureutils'; +import { createTestActionContext, type TestActionContext } from '@microsoft/vscode-azext-dev'; +import { createSubscriptionContext, subscriptionExperience, type ISubscriptionContext } from '@microsoft/vscode-azext-utils'; +import { type AzureSubscription } from '@microsoft/vscode-azureresources-api'; import * as vscode from 'vscode'; +import { ext } from '../../extension.bundle'; import { longRunningTestsEnabled } from '../global.test'; export const resourceGroupsToDelete: string[] = []; @@ -12,7 +18,32 @@ suiteSetup(async function (this: Mocha.Context): Promise { if (!longRunningTestsEnabled) { return; } + await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); -// Add suiteteardown for resourcegroups +suiteTeardown(async function (this: Mocha.Context): Promise { + if (!longRunningTestsEnabled) { + return; + } + + await deleteResourceGroups(); +}); + +// Todo: re-test this +async function deleteResourceGroups(): Promise { + const context: TestActionContext = await createTestActionContext(); + const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); + const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); + + const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); + await Promise.all(resourceGroupsToDelete.map(async resourceGroup => { + if ((await rgClient.resourceGroups.checkExistence(resourceGroup)).body) { + console.log(`Started delete of resource group "${resourceGroup}"...`); + await rgClient.resourceGroups.beginDeleteAndWait(resourceGroup); + console.log(`Successfully started delete of resource group "${resourceGroup}".`); + } else { + console.log(`Ignoring resource group "${resourceGroup}" because it does not exist.`); + } + })); +} From 59185191bee8e640c43371da58d16995d8242a28 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:55:04 -0700 Subject: [PATCH 18/54] Add test workspace fields --- test/test.code-workspace | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/test.code-workspace b/test/test.code-workspace index 4411dceb3..de0abcdfb 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -3,6 +3,14 @@ { "name": "dockerfiles", "path": "./testProjects/dockerfiles" - } + }, + { + "name": "monorepo-basic", + "path": "testProject/monorepo-basic" + }, + // { + // "name": "albumapi-javascript", + // "path": "testProject/albumapi-javascript" + // }, ] } From 5d52072b3da8ad3a784c659b00f38346392c0991 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:56:19 -0700 Subject: [PATCH 19/54] Revert scripts --- package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 2470a0ce0..86fd14720 100644 --- a/package.json +++ b/package.json @@ -734,16 +734,17 @@ } }, "scripts": { - "vscode:prepublish": "npm run cleanReadme", - "build": "tsc && gulp webpack-prod", + "vscode:prepublish": "npm run webpack-prod", + "build": "tsc", "cleanReadme": "gulp cleanReadme", "compile": "tsc -watch", "package": "vsce package --githubBranch main --no-dependencies", "lint": "eslint --ext .ts .", "lint-fix": "eslint --ext .ts . --fix", - "pretest": "", + "pretest": "npm run webpack-prod", "test": "node ./dist/test/runTest.js", - "webpack": "tsc && gulp webpack-dev", + "webpack": "npm run build && gulp webpack-dev", + "webpack-prod": "npm run build && gulp webpack-prod", "webpack-profile": "webpack --profile --json --mode production > webpack-stats.json && echo Use http://webpack.github.io/analyse to analyze the stats", "prepare": "husky install" }, From a92417e56fd25c9389bdd45c6e678612daba8992 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:17:56 -0700 Subject: [PATCH 20/54] Add monorepo-basic test project --- test/testProjects/monorepo-basic/.gitignore | 2 ++ test/testProjects/monorepo-basic/README.md | 3 +++ test/testProjects/monorepo-basic/app1/.env.example | 1 + test/testProjects/monorepo-basic/app1/Dockerfile | 6 ++++++ test/testProjects/monorepo-basic/app1/package.json | 9 +++++++++ test/testProjects/monorepo-basic/app1/server.js | 12 ++++++++++++ test/testProjects/monorepo-basic/app2/.env.example | 1 + test/testProjects/monorepo-basic/app2/Dockerfile | 6 ++++++ test/testProjects/monorepo-basic/app2/package.json | 9 +++++++++ test/testProjects/monorepo-basic/app2/server.js | 12 ++++++++++++ test/testProjects/monorepo-basic/app3/.env.example | 1 + test/testProjects/monorepo-basic/app3/Dockerfile | 6 ++++++ test/testProjects/monorepo-basic/app3/package.json | 9 +++++++++ test/testProjects/monorepo-basic/app3/server.js | 12 ++++++++++++ 14 files changed, 89 insertions(+) create mode 100644 test/testProjects/monorepo-basic/.gitignore create mode 100644 test/testProjects/monorepo-basic/README.md create mode 100644 test/testProjects/monorepo-basic/app1/.env.example create mode 100644 test/testProjects/monorepo-basic/app1/Dockerfile create mode 100644 test/testProjects/monorepo-basic/app1/package.json create mode 100644 test/testProjects/monorepo-basic/app1/server.js create mode 100644 test/testProjects/monorepo-basic/app2/.env.example create mode 100644 test/testProjects/monorepo-basic/app2/Dockerfile create mode 100644 test/testProjects/monorepo-basic/app2/package.json create mode 100644 test/testProjects/monorepo-basic/app2/server.js create mode 100644 test/testProjects/monorepo-basic/app3/.env.example create mode 100644 test/testProjects/monorepo-basic/app3/Dockerfile create mode 100644 test/testProjects/monorepo-basic/app3/package.json create mode 100644 test/testProjects/monorepo-basic/app3/server.js diff --git a/test/testProjects/monorepo-basic/.gitignore b/test/testProjects/monorepo-basic/.gitignore new file mode 100644 index 000000000..76efb07fd --- /dev/null +++ b/test/testProjects/monorepo-basic/.gitignore @@ -0,0 +1,2 @@ +node_modules +.vscode diff --git a/test/testProjects/monorepo-basic/README.md b/test/testProjects/monorepo-basic/README.md new file mode 100644 index 000000000..3f02450f1 --- /dev/null +++ b/test/testProjects/monorepo-basic/README.md @@ -0,0 +1,3 @@ +# Monorepo-basic + +This extremely minimal Node.js monorepo is used for quickly testing simple scenarios in the Azure Container Apps Extension. diff --git a/test/testProjects/monorepo-basic/app1/.env.example b/test/testProjects/monorepo-basic/app1/.env.example new file mode 100644 index 000000000..ccdd01e41 --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/.env.example @@ -0,0 +1 @@ +MESSAGE='container apps (app1)' \ No newline at end of file diff --git a/test/testProjects/monorepo-basic/app1/Dockerfile b/test/testProjects/monorepo-basic/app1/Dockerfile new file mode 100644 index 000000000..5676b6469 --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine + +COPY . /src +RUN cd /src && npm install +EXPOSE 80 +CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app1/package.json b/test/testProjects/monorepo-basic/app1/package.json new file mode 100644 index 000000000..73a19ffec --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/package.json @@ -0,0 +1,9 @@ +{ + "name": "aca-hello-world-app1", + "version": "1.0.0", + "description": "Simple test app for the ACA tools for VS Code extension", + "main": "server.js", + "scripts": { + "start": "node server.js" + } +} diff --git a/test/testProjects/monorepo-basic/app1/server.js b/test/testProjects/monorepo-basic/app1/server.js new file mode 100644 index 000000000..d7dfa5936 --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/server.js @@ -0,0 +1,12 @@ +const http = require('http'); + +const port = process.env.PORT || 80; +const message = process.env.MESSAGE || 'world'; + +const server = http.createServer((_, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.write(`Hello ${message}\n`); +}); + +server.listen(port); +console.log(`Server running at http://localhost: ${port}`); diff --git a/test/testProjects/monorepo-basic/app2/.env.example b/test/testProjects/monorepo-basic/app2/.env.example new file mode 100644 index 000000000..4d8c89b94 --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/.env.example @@ -0,0 +1 @@ +MESSAGE='container apps (app2)' \ No newline at end of file diff --git a/test/testProjects/monorepo-basic/app2/Dockerfile b/test/testProjects/monorepo-basic/app2/Dockerfile new file mode 100644 index 000000000..5676b6469 --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine + +COPY . /src +RUN cd /src && npm install +EXPOSE 80 +CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app2/package.json b/test/testProjects/monorepo-basic/app2/package.json new file mode 100644 index 000000000..ac888411b --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/package.json @@ -0,0 +1,9 @@ +{ + "name": "aca-hello-world-app2", + "version": "1.0.0", + "description": "Simple test app for the ACA tools for VS Code extension", + "main": "server.js", + "scripts": { + "start": "node server.js" + } +} diff --git a/test/testProjects/monorepo-basic/app2/server.js b/test/testProjects/monorepo-basic/app2/server.js new file mode 100644 index 000000000..d7dfa5936 --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/server.js @@ -0,0 +1,12 @@ +const http = require('http'); + +const port = process.env.PORT || 80; +const message = process.env.MESSAGE || 'world'; + +const server = http.createServer((_, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.write(`Hello ${message}\n`); +}); + +server.listen(port); +console.log(`Server running at http://localhost: ${port}`); diff --git a/test/testProjects/monorepo-basic/app3/.env.example b/test/testProjects/monorepo-basic/app3/.env.example new file mode 100644 index 000000000..7a635af96 --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/.env.example @@ -0,0 +1 @@ +MESSAGE='container apps (app3)' \ No newline at end of file diff --git a/test/testProjects/monorepo-basic/app3/Dockerfile b/test/testProjects/monorepo-basic/app3/Dockerfile new file mode 100644 index 000000000..5676b6469 --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine + +COPY . /src +RUN cd /src && npm install +EXPOSE 80 +CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app3/package.json b/test/testProjects/monorepo-basic/app3/package.json new file mode 100644 index 000000000..1b5b8b78d --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/package.json @@ -0,0 +1,9 @@ +{ + "name": "aca-hello-world-app3", + "version": "1.0.0", + "description": "Simple test app for the ACA tools for VS Code extension", + "main": "server.js", + "scripts": { + "start": "node server.js" + } +} diff --git a/test/testProjects/monorepo-basic/app3/server.js b/test/testProjects/monorepo-basic/app3/server.js new file mode 100644 index 000000000..d7dfa5936 --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/server.js @@ -0,0 +1,12 @@ +const http = require('http'); + +const port = process.env.PORT || 80; +const message = process.env.MESSAGE || 'world'; + +const server = http.createServer((_, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.write(`Hello ${message}\n`); +}); + +server.listen(port); +console.log(`Server running at http://localhost: ${port}`); From 46094735e6400546e03da4983ce2de2bca9b479e Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:24:38 -0700 Subject: [PATCH 21/54] Add resource groups to delete --- .../deployWorkspaceProject/deployWorkspaceProject.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts index 465919abf..e66dfc347 100644 --- a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -3,12 +3,14 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { parseAzureResourceGroupId } from '@microsoft/vscode-azext-azureutils'; import { runWithTestActionContext } from '@microsoft/vscode-azext-dev'; import * as assert from 'assert'; import * as path from 'path'; import { workspace, type Uri, type WorkspaceFolder } from 'vscode'; import { AzExtFsExtra, deployWorkspaceProject, dwpSettingUtilsV2, settingUtils, type DeploymentConfigurationSettings, type DeployWorkspaceProjectResults } from '../../../extension.bundle'; import { assertStringPropsMatch, getWorkspaceFolderUri } from '../../testUtils'; +import { resourceGroupsToDelete } from '../global.nightly.test'; import { testScenarios } from './testScenarios'; suite('deployWorkspaceProject', function () { @@ -26,6 +28,11 @@ suite('deployWorkspaceProject', function () { await runWithTestActionContext('deployWorkspaceProject', async context => { await context.ui.runWithInputs(testCase.inputs, async () => { const results: DeployWorkspaceProjectResults = await deployWorkspaceProject(context); + if (results.resourceGroupId) { + const resourceGroupName: string = parseAzureResourceGroupId(results.resourceGroupId).resourceGroup; + resourceGroupsToDelete.push(resourceGroupName); + } + assertStringPropsMatch(results as Partial>, testCase.expectedResults as Record, 'DeployWorkspaceProject results mismatch.'); const deploymentConfigurationsV2: DeploymentConfigurationSettings[] = await dwpSettingUtilsV2.getWorkspaceDeploymentConfigurations(rootFolder) ?? []; From 2636f2ee16774763c23fb5b23f172054073bed23 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:13:27 -0700 Subject: [PATCH 22/54] Fix test workspace paths --- test/test.code-workspace | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.code-workspace b/test/test.code-workspace index de0abcdfb..8ea4b16c6 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -6,11 +6,11 @@ }, { "name": "monorepo-basic", - "path": "testProject/monorepo-basic" + "path": "./testProjects/monorepo-basic" }, // { // "name": "albumapi-javascript", - // "path": "testProject/albumapi-javascript" + // "path": "./testProjects/albumapi-javascript" // }, ] } From af1d275815cd263cd46b31dc73ec5ef17796912d Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:20:49 -0700 Subject: [PATCH 23/54] Use different port numbers --- test/testProjects/monorepo-basic/app1/Dockerfile | 2 +- test/testProjects/monorepo-basic/app2/Dockerfile | 2 +- test/testProjects/monorepo-basic/app3/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/testProjects/monorepo-basic/app1/Dockerfile b/test/testProjects/monorepo-basic/app1/Dockerfile index 5676b6469..7551b0939 100644 --- a/test/testProjects/monorepo-basic/app1/Dockerfile +++ b/test/testProjects/monorepo-basic/app1/Dockerfile @@ -2,5 +2,5 @@ FROM node:lts-alpine COPY . /src RUN cd /src && npm install -EXPOSE 80 +EXPOSE 3000 CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app2/Dockerfile b/test/testProjects/monorepo-basic/app2/Dockerfile index 5676b6469..5eebedd05 100644 --- a/test/testProjects/monorepo-basic/app2/Dockerfile +++ b/test/testProjects/monorepo-basic/app2/Dockerfile @@ -2,5 +2,5 @@ FROM node:lts-alpine COPY . /src RUN cd /src && npm install -EXPOSE 80 +EXPOSE 3001 CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app3/Dockerfile b/test/testProjects/monorepo-basic/app3/Dockerfile index 5676b6469..252ccdcc7 100644 --- a/test/testProjects/monorepo-basic/app3/Dockerfile +++ b/test/testProjects/monorepo-basic/app3/Dockerfile @@ -2,5 +2,5 @@ FROM node:lts-alpine COPY . /src RUN cd /src && npm install -EXPOSE 80 +EXPOSE 3002 CMD ["node", "/src/server.js"] From 7df2569d39f035dd6eef79fb169e0b3cab84fa60 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 23:21:01 -0700 Subject: [PATCH 24/54] Timeout test --- .../deployWorkspaceProject.test.ts | 4 +++- test/nightly/global.nightly.test.ts | 14 +++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts index e66dfc347..084dd4e5d 100644 --- a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -13,7 +13,9 @@ import { assertStringPropsMatch, getWorkspaceFolderUri } from '../../testUtils'; import { resourceGroupsToDelete } from '../global.nightly.test'; import { testScenarios } from './testScenarios'; -suite('deployWorkspaceProject', function () { +suite('deployWorkspaceProject', function (this: Mocha.Suite) { + this.timeout(7 * 60 * 1000); + for (const scenario of testScenarios) { suite(scenario.label, function () { const workspaceFolderUri: Uri = getWorkspaceFolderUri(scenario.folderName); diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index c5162a68e..7978e6dc2 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -22,16 +22,16 @@ suiteSetup(async function (this: Mocha.Context): Promise { await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); -suiteTeardown(async function (this: Mocha.Context): Promise { - if (!longRunningTestsEnabled) { - return; - } +// suiteTeardown(async function (this: Mocha.Context): Promise { +// if (!longRunningTestsEnabled) { +// return; +// } - await deleteResourceGroups(); -}); +// await deleteResourceGroups(); +// }); // Todo: re-test this -async function deleteResourceGroups(): Promise { +export async function deleteResourceGroups(): Promise { const context: TestActionContext = await createTestActionContext(); const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); From ecb27876a2066ae6cdd82565cc70007300a61ab6 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 13 Jun 2024 23:42:21 -0700 Subject: [PATCH 25/54] Test with delete rg --- test/nightly/global.nightly.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 7978e6dc2..c5162a68e 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -22,16 +22,16 @@ suiteSetup(async function (this: Mocha.Context): Promise { await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); -// suiteTeardown(async function (this: Mocha.Context): Promise { -// if (!longRunningTestsEnabled) { -// return; -// } +suiteTeardown(async function (this: Mocha.Context): Promise { + if (!longRunningTestsEnabled) { + return; + } -// await deleteResourceGroups(); -// }); + await deleteResourceGroups(); +}); // Todo: re-test this -export async function deleteResourceGroups(): Promise { +async function deleteResourceGroups(): Promise { const context: TestActionContext = await createTestActionContext(); const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); From 92e7f69a9cd55764f84aa153c85b025126f75092 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:00:39 -0700 Subject: [PATCH 26/54] Update skip logic --- .../deployWorkspaceProject/deployWorkspaceProject.test.ts | 7 +++++++ test/nightly/global.nightly.test.ts | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts index 084dd4e5d..21ceccb40 100644 --- a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -9,6 +9,7 @@ import * as assert from 'assert'; import * as path from 'path'; import { workspace, type Uri, type WorkspaceFolder } from 'vscode'; import { AzExtFsExtra, deployWorkspaceProject, dwpSettingUtilsV2, settingUtils, type DeploymentConfigurationSettings, type DeployWorkspaceProjectResults } from '../../../extension.bundle'; +import { longRunningTestsEnabled } from '../../global.test'; import { assertStringPropsMatch, getWorkspaceFolderUri } from '../../testUtils'; import { resourceGroupsToDelete } from '../global.nightly.test'; import { testScenarios } from './testScenarios'; @@ -16,6 +17,12 @@ import { testScenarios } from './testScenarios'; suite('deployWorkspaceProject', function (this: Mocha.Suite) { this.timeout(7 * 60 * 1000); + suiteSetup(function (this: Mocha.Context) { + if (!longRunningTestsEnabled) { + this.skip(); + } + }); + for (const scenario of testScenarios) { suite(scenario.label, function () { const workspaceFolderUri: Uri = getWorkspaceFolderUri(scenario.folderName); diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index c5162a68e..17238ff05 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -22,7 +22,7 @@ suiteSetup(async function (this: Mocha.Context): Promise { await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); -suiteTeardown(async function (this: Mocha.Context): Promise { +suiteTeardown(async function (): Promise { if (!longRunningTestsEnabled) { return; } @@ -41,7 +41,7 @@ async function deleteResourceGroups(): Promise { if ((await rgClient.resourceGroups.checkExistence(resourceGroup)).body) { console.log(`Started delete of resource group "${resourceGroup}"...`); await rgClient.resourceGroups.beginDeleteAndWait(resourceGroup); - console.log(`Successfully started delete of resource group "${resourceGroup}".`); + console.log(`Successfully deleted resource group "${resourceGroup}".`); } else { console.log(`Ignoring resource group "${resourceGroup}" because it does not exist.`); } From 34acb2214d4f1eece66ee5dac75bddbd734e0e21 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:16:27 -0700 Subject: [PATCH 27/54] Test rg activation --- test/global.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/global.test.ts b/test/global.test.ts index 556216829..33924628a 100644 --- a/test/global.test.ts +++ b/test/global.test.ts @@ -19,6 +19,7 @@ suiteSetup(async function (this: Mocha.Context): Promise { assert.fail('Failed to find extension.'); } else { await extension.activate(); + await vscode.extensions.getExtension('ms-azuretools.vscode-azureresourcegroups')?.activate(); } registerOnActionStartHandler(context => { From 2622bf2f7e24e0efe4d56f9ac872ef7bf37a15b8 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:21:41 -0700 Subject: [PATCH 28/54] Test log statements --- test/nightly/global.nightly.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 17238ff05..345d303c4 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -32,12 +32,17 @@ suiteTeardown(async function (): Promise { // Todo: re-test this async function deleteResourceGroups(): Promise { + console.log("deleteResourceGroups...") const context: TestActionContext = await createTestActionContext(); + console.log("acquiring subscription") const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); + console.log("got subscription", subscription.subscriptionId) const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); - + console.log("created subscription context: ", subscriptionContext) const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); + console.log("created resource group client") await Promise.all(resourceGroupsToDelete.map(async resourceGroup => { + console.log("promise for resource group: ", resourceGroup) if ((await rgClient.resourceGroups.checkExistence(resourceGroup)).body) { console.log(`Started delete of resource group "${resourceGroup}"...`); await rgClient.resourceGroups.beginDeleteAndWait(resourceGroup); From feb3530b1189560a372b75c0abec9a4fc87f1830 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:45:14 -0700 Subject: [PATCH 29/54] Test upgrade arm package --- package-lock.json | 2 +- package.json | 2 +- test/nightly/global.nightly.test.ts | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3120115e5..b18f1d7a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@azure/arm-appcontainers": "^2.0.0", "@azure/arm-containerregistry": "^10.0.0", "@azure/arm-operationalinsights": "^8.0.0", - "@azure/arm-resources": "^5.0.1", + "@azure/arm-resources": "^5.2.0", "@azure/container-registry": "1.0.0-beta.5", "@azure/core-rest-pipeline": "1.10.3", "@azure/storage-blob": "^12.4.1", diff --git a/package.json b/package.json index 04c17cb45..154f578d7 100644 --- a/package.json +++ b/package.json @@ -781,7 +781,7 @@ "@azure/arm-appcontainers": "^2.0.0", "@azure/arm-containerregistry": "^10.0.0", "@azure/arm-operationalinsights": "^8.0.0", - "@azure/arm-resources": "^5.0.1", + "@azure/arm-resources": "^5.2.0", "@azure/container-registry": "1.0.0-beta.5", "@azure/core-rest-pipeline": "1.10.3", "@azure/storage-blob": "^12.4.1", diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 345d303c4..621d85e6e 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -32,14 +32,11 @@ suiteTeardown(async function (): Promise { // Todo: re-test this async function deleteResourceGroups(): Promise { - console.log("deleteResourceGroups...") const context: TestActionContext = await createTestActionContext(); - console.log("acquiring subscription") const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); - console.log("got subscription", subscription.subscriptionId) const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); - console.log("created subscription context: ", subscriptionContext) const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); + console.log("created resource group client") await Promise.all(resourceGroupsToDelete.map(async resourceGroup => { console.log("promise for resource group: ", resourceGroup) From 13113509ea5ee8246b2f83ad77701a4d53b21d81 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:07:20 -0700 Subject: [PATCH 30/54] Your guess is as good as mine --- test/nightly/global.nightly.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 621d85e6e..5d4612e27 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { ResourceManagementClient } from '@azure/arm-resources'; -import { createAzureClient } from '@microsoft/vscode-azext-azureutils'; +import { createAzureClient, registerAzureUtilsExtensionVariables } from '@microsoft/vscode-azext-azureutils'; import { createTestActionContext, type TestActionContext } from '@microsoft/vscode-azext-dev'; -import { createSubscriptionContext, subscriptionExperience, type ISubscriptionContext } from '@microsoft/vscode-azext-utils'; +import { createSubscriptionContext, registerUIExtensionVariables, subscriptionExperience, type ISubscriptionContext } from '@microsoft/vscode-azext-utils'; import { type AzureSubscription } from '@microsoft/vscode-azureresources-api'; import * as vscode from 'vscode'; import { ext } from '../../extension.bundle'; @@ -35,6 +35,10 @@ async function deleteResourceGroups(): Promise { const context: TestActionContext = await createTestActionContext(); const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); + + registerUIExtensionVariables(ext); + registerAzureUtilsExtensionVariables(ext); + const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); console.log("created resource group client") From e0858c214dc3066d8aa6b41ff40ede99a2bfc306 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:23:43 -0700 Subject: [PATCH 31/54] Add timeout --- test/nightly/global.nightly.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 5d4612e27..fc5021f1e 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -22,7 +22,9 @@ suiteSetup(async function (this: Mocha.Context): Promise { await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); -suiteTeardown(async function (): Promise { +suiteTeardown(async function (this: Mocha.Context): Promise { + this.timeout(10 * 60 * 1000) + if (!longRunningTestsEnabled) { return; } From a2ccc28b410c243101392ab422b2cc3b07b5f5ae Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:27:33 -0700 Subject: [PATCH 32/54] Add timeout --- test/nightly/global.nightly.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index fc5021f1e..645093268 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -15,10 +15,11 @@ import { longRunningTestsEnabled } from '../global.test'; export const resourceGroupsToDelete: string[] = []; suiteSetup(async function (this: Mocha.Context): Promise { + this.timeout(2 * 60 * 1000); + if (!longRunningTestsEnabled) { return; } - await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); @@ -28,7 +29,6 @@ suiteTeardown(async function (this: Mocha.Context): Promise { if (!longRunningTestsEnabled) { return; } - await deleteResourceGroups(); }); From f2dd372532ef5e42e06480fde7f4d95ae02097bc Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:52:19 -0700 Subject: [PATCH 33/54] Clean up delete logic and increase timeout --- test/global.test.ts | 15 ++++++++------- test/nightly/global.nightly.test.ts | 19 +++++++------------ 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/test/global.test.ts b/test/global.test.ts index 33924628a..f21ce3621 100644 --- a/test/global.test.ts +++ b/test/global.test.ts @@ -3,30 +3,31 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { registerAzureUtilsExtensionVariables } from '@microsoft/vscode-azext-azureutils'; import { TestOutputChannel, TestUserInput } from '@microsoft/vscode-azext-dev'; import * as assert from 'assert'; import * as vscode from 'vscode'; -import { ext, registerOnActionStartHandler } from '../extension.bundle'; +import { ext, registerOnActionStartHandler, registerUIExtensionVariables } from '../extension.bundle'; -export let longRunningTestsEnabled: boolean; +export const longRunningTestsEnabled: boolean = !/^(false|0)?$/i.test(process.env.AzCode_UseAzureFederatedCredentials || ''); // Runs before all tests suiteSetup(async function (this: Mocha.Context): Promise { - this.timeout(1 * 60 * 1000); + this.timeout(4 * 60 * 1000); const extension = vscode.extensions.getExtension('ms-azuretools.vscode-azurecontainerapps'); if (!extension) { assert.fail('Failed to find extension.'); } else { await extension.activate(); - await vscode.extensions.getExtension('ms-azuretools.vscode-azureresourcegroups')?.activate(); } + ext.outputChannel = new TestOutputChannel(); + registerUIExtensionVariables(ext); + registerAzureUtilsExtensionVariables(ext); + registerOnActionStartHandler(context => { // Use `TestUserInput` by default so we get an error if an unexpected call to `context.ui` occurs, rather than timing out context.ui = new TestUserInput(vscode); }); - - ext.outputChannel = new TestOutputChannel(); - longRunningTestsEnabled = !/^(false|0)?$/i.test(process.env.AzCode_UseAzureFederatedCredentials || ''); }); diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 645093268..e789c3903 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { ResourceManagementClient } from '@azure/arm-resources'; -import { createAzureClient, registerAzureUtilsExtensionVariables } from '@microsoft/vscode-azext-azureutils'; +import { createAzureClient } from '@microsoft/vscode-azext-azureutils'; import { createTestActionContext, type TestActionContext } from '@microsoft/vscode-azext-dev'; -import { createSubscriptionContext, registerUIExtensionVariables, subscriptionExperience, type ISubscriptionContext } from '@microsoft/vscode-azext-utils'; +import { createSubscriptionContext, subscriptionExperience, type ISubscriptionContext } from '@microsoft/vscode-azext-utils'; import { type AzureSubscription } from '@microsoft/vscode-azureresources-api'; import * as vscode from 'vscode'; import { ext } from '../../extension.bundle'; @@ -15,20 +15,21 @@ import { longRunningTestsEnabled } from '../global.test'; export const resourceGroupsToDelete: string[] = []; suiteSetup(async function (this: Mocha.Context): Promise { - this.timeout(2 * 60 * 1000); - if (!longRunningTestsEnabled) { return; } + + this.timeout(2 * 60 * 1000); await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); suiteTeardown(async function (this: Mocha.Context): Promise { - this.timeout(10 * 60 * 1000) - if (!longRunningTestsEnabled) { return; } + + // Account for the fact that it can take an extremely long time to delete managed environments + this.timeout(30 * 60 * 1000); await deleteResourceGroups(); }); @@ -37,15 +38,9 @@ async function deleteResourceGroups(): Promise { const context: TestActionContext = await createTestActionContext(); const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); - - registerUIExtensionVariables(ext); - registerAzureUtilsExtensionVariables(ext); - const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); - console.log("created resource group client") await Promise.all(resourceGroupsToDelete.map(async resourceGroup => { - console.log("promise for resource group: ", resourceGroup) if ((await rgClient.resourceGroups.checkExistence(resourceGroup)).body) { console.log(`Started delete of resource group "${resourceGroup}"...`); await rgClient.resourceGroups.beginDeleteAndWait(resourceGroup); From 2f92f2bbb6c83839b2e51ae59b2828cbccbf4bf8 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:24:52 -0700 Subject: [PATCH 34/54] Uset set instead of a list --- .../deployWorkspaceProject.test.ts | 2 +- test/nightly/global.nightly.test.ts | 20 +++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts index 21ceccb40..fd09d4f45 100644 --- a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -39,7 +39,7 @@ suite('deployWorkspaceProject', function (this: Mocha.Suite) { const results: DeployWorkspaceProjectResults = await deployWorkspaceProject(context); if (results.resourceGroupId) { const resourceGroupName: string = parseAzureResourceGroupId(results.resourceGroupId).resourceGroup; - resourceGroupsToDelete.push(resourceGroupName); + resourceGroupsToDelete.add(resourceGroupName); } assertStringPropsMatch(results as Partial>, testCase.expectedResults as Record, 'DeployWorkspaceProject results mismatch.'); diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index e789c3903..0d7380a4a 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -12,13 +12,12 @@ import * as vscode from 'vscode'; import { ext } from '../../extension.bundle'; import { longRunningTestsEnabled } from '../global.test'; -export const resourceGroupsToDelete: string[] = []; +export const resourceGroupsToDelete = new Set(); suiteSetup(async function (this: Mocha.Context): Promise { if (!longRunningTestsEnabled) { return; } - this.timeout(2 * 60 * 1000); await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); @@ -28,25 +27,24 @@ suiteTeardown(async function (this: Mocha.Context): Promise { return; } - // Account for the fact that it can take an extremely long time to delete managed environments + // Account for the fact that it can take an extremely long time to delete managed environment resources this.timeout(30 * 60 * 1000); await deleteResourceGroups(); }); -// Todo: re-test this async function deleteResourceGroups(): Promise { const context: TestActionContext = await createTestActionContext(); const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); - await Promise.all(resourceGroupsToDelete.map(async resourceGroup => { - if ((await rgClient.resourceGroups.checkExistence(resourceGroup)).body) { - console.log(`Started delete of resource group "${resourceGroup}"...`); - await rgClient.resourceGroups.beginDeleteAndWait(resourceGroup); - console.log(`Successfully deleted resource group "${resourceGroup}".`); - } else { - console.log(`Ignoring resource group "${resourceGroup}" because it does not exist.`); + await Promise.all(Array.from(resourceGroupsToDelete).map(async resourceGroup => { + if (!(await rgClient.resourceGroups.checkExistence(resourceGroup)).body) { + return; } + + console.log(`Deleting resource group "${resourceGroup}"...`); + await rgClient.resourceGroups.beginDeleteAndWait(resourceGroup); + console.log(`Successfully deleted resource group "${resourceGroup}".`); })); } From 0b2a1de4941a517d82d52852c92e1a2903e26594 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:32:57 -0700 Subject: [PATCH 35/54] Update arm dep --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3120115e5..b18f1d7a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@azure/arm-appcontainers": "^2.0.0", "@azure/arm-containerregistry": "^10.0.0", "@azure/arm-operationalinsights": "^8.0.0", - "@azure/arm-resources": "^5.0.1", + "@azure/arm-resources": "^5.2.0", "@azure/container-registry": "1.0.0-beta.5", "@azure/core-rest-pipeline": "1.10.3", "@azure/storage-blob": "^12.4.1", diff --git a/package.json b/package.json index 04c17cb45..154f578d7 100644 --- a/package.json +++ b/package.json @@ -781,7 +781,7 @@ "@azure/arm-appcontainers": "^2.0.0", "@azure/arm-containerregistry": "^10.0.0", "@azure/arm-operationalinsights": "^8.0.0", - "@azure/arm-resources": "^5.0.1", + "@azure/arm-resources": "^5.2.0", "@azure/container-registry": "1.0.0-beta.5", "@azure/core-rest-pipeline": "1.10.3", "@azure/storage-blob": "^12.4.1", From 6039db412486a1d724c449ba1526697d6c0e3f93 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:38:31 -0700 Subject: [PATCH 36/54] Update timeouts --- test/global.test.ts | 2 +- .../deployWorkspaceProject/deployWorkspaceProject.test.ts | 2 +- test/nightly/global.nightly.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/global.test.ts b/test/global.test.ts index f21ce3621..8caffc75f 100644 --- a/test/global.test.ts +++ b/test/global.test.ts @@ -13,7 +13,7 @@ export const longRunningTestsEnabled: boolean = !/^(false|0)?$/i.test(process.en // Runs before all tests suiteSetup(async function (this: Mocha.Context): Promise { - this.timeout(4 * 60 * 1000); + this.timeout(1 * 60 * 1000); const extension = vscode.extensions.getExtension('ms-azuretools.vscode-azurecontainerapps'); if (!extension) { diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts index fd09d4f45..c57ddde98 100644 --- a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -15,7 +15,7 @@ import { resourceGroupsToDelete } from '../global.nightly.test'; import { testScenarios } from './testScenarios'; suite('deployWorkspaceProject', function (this: Mocha.Suite) { - this.timeout(7 * 60 * 1000); + this.timeout(15 * 60 * 1000); suiteSetup(function (this: Mocha.Context) { if (!longRunningTestsEnabled) { diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 0d7380a4a..160a7308a 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -18,7 +18,7 @@ suiteSetup(async function (this: Mocha.Context): Promise { if (!longRunningTestsEnabled) { return; } - this.timeout(2 * 60 * 1000); + this.timeout(1 * 60 * 1000); await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); From 04b73ff0aa8b5f8ad19aa9d548b60474c1a55b10 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:50:48 -0700 Subject: [PATCH 37/54] Add monorepo test project --- test/test.code-workspace | 4 ++++ test/testProjects/monorepo-basic/.gitignore | 2 ++ test/testProjects/monorepo-basic/README.md | 3 +++ test/testProjects/monorepo-basic/app1/.env.example | 2 ++ test/testProjects/monorepo-basic/app1/Dockerfile | 6 ++++++ test/testProjects/monorepo-basic/app1/package.json | 9 +++++++++ test/testProjects/monorepo-basic/app1/server.js | 12 ++++++++++++ test/testProjects/monorepo-basic/app2/.env.example | 2 ++ test/testProjects/monorepo-basic/app2/Dockerfile | 6 ++++++ test/testProjects/monorepo-basic/app2/package.json | 9 +++++++++ test/testProjects/monorepo-basic/app2/server.js | 12 ++++++++++++ test/testProjects/monorepo-basic/app3/.env.example | 2 ++ test/testProjects/monorepo-basic/app3/Dockerfile | 6 ++++++ test/testProjects/monorepo-basic/app3/package.json | 9 +++++++++ test/testProjects/monorepo-basic/app3/server.js | 12 ++++++++++++ 15 files changed, 96 insertions(+) create mode 100644 test/testProjects/monorepo-basic/.gitignore create mode 100644 test/testProjects/monorepo-basic/README.md create mode 100644 test/testProjects/monorepo-basic/app1/.env.example create mode 100644 test/testProjects/monorepo-basic/app1/Dockerfile create mode 100644 test/testProjects/monorepo-basic/app1/package.json create mode 100644 test/testProjects/monorepo-basic/app1/server.js create mode 100644 test/testProjects/monorepo-basic/app2/.env.example create mode 100644 test/testProjects/monorepo-basic/app2/Dockerfile create mode 100644 test/testProjects/monorepo-basic/app2/package.json create mode 100644 test/testProjects/monorepo-basic/app2/server.js create mode 100644 test/testProjects/monorepo-basic/app3/.env.example create mode 100644 test/testProjects/monorepo-basic/app3/Dockerfile create mode 100644 test/testProjects/monorepo-basic/app3/package.json create mode 100644 test/testProjects/monorepo-basic/app3/server.js diff --git a/test/test.code-workspace b/test/test.code-workspace index 4411dceb3..ec14e6edf 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -3,6 +3,10 @@ { "name": "dockerfiles", "path": "./testProjects/dockerfiles" + }, + { + "name": "monorepo-basic", + "path": "./testProjects/monorepo-basic" } ] } diff --git a/test/testProjects/monorepo-basic/.gitignore b/test/testProjects/monorepo-basic/.gitignore new file mode 100644 index 000000000..76efb07fd --- /dev/null +++ b/test/testProjects/monorepo-basic/.gitignore @@ -0,0 +1,2 @@ +node_modules +.vscode diff --git a/test/testProjects/monorepo-basic/README.md b/test/testProjects/monorepo-basic/README.md new file mode 100644 index 000000000..2213f189f --- /dev/null +++ b/test/testProjects/monorepo-basic/README.md @@ -0,0 +1,3 @@ +# ACA Hello World v2 + +This extremely minimal Node.js monorepo is used for quickly testing simple scenarios in the Azure Container Apps Extension. \ No newline at end of file diff --git a/test/testProjects/monorepo-basic/app1/.env.example b/test/testProjects/monorepo-basic/app1/.env.example new file mode 100644 index 000000000..f6b943bb5 --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/.env.example @@ -0,0 +1,2 @@ +MESSAGE='container apps (app1)' +PORT=3000 diff --git a/test/testProjects/monorepo-basic/app1/Dockerfile b/test/testProjects/monorepo-basic/app1/Dockerfile new file mode 100644 index 000000000..7551b0939 --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine + +COPY . /src +RUN cd /src && npm install +EXPOSE 3000 +CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app1/package.json b/test/testProjects/monorepo-basic/app1/package.json new file mode 100644 index 000000000..73a19ffec --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/package.json @@ -0,0 +1,9 @@ +{ + "name": "aca-hello-world-app1", + "version": "1.0.0", + "description": "Simple test app for the ACA tools for VS Code extension", + "main": "server.js", + "scripts": { + "start": "node server.js" + } +} diff --git a/test/testProjects/monorepo-basic/app1/server.js b/test/testProjects/monorepo-basic/app1/server.js new file mode 100644 index 000000000..d7dfa5936 --- /dev/null +++ b/test/testProjects/monorepo-basic/app1/server.js @@ -0,0 +1,12 @@ +const http = require('http'); + +const port = process.env.PORT || 80; +const message = process.env.MESSAGE || 'world'; + +const server = http.createServer((_, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.write(`Hello ${message}\n`); +}); + +server.listen(port); +console.log(`Server running at http://localhost: ${port}`); diff --git a/test/testProjects/monorepo-basic/app2/.env.example b/test/testProjects/monorepo-basic/app2/.env.example new file mode 100644 index 000000000..dd82c9d77 --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/.env.example @@ -0,0 +1,2 @@ +MESSAGE='container apps (app2)' +PORT=3001 diff --git a/test/testProjects/monorepo-basic/app2/Dockerfile b/test/testProjects/monorepo-basic/app2/Dockerfile new file mode 100644 index 000000000..5eebedd05 --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine + +COPY . /src +RUN cd /src && npm install +EXPOSE 3001 +CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app2/package.json b/test/testProjects/monorepo-basic/app2/package.json new file mode 100644 index 000000000..ac888411b --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/package.json @@ -0,0 +1,9 @@ +{ + "name": "aca-hello-world-app2", + "version": "1.0.0", + "description": "Simple test app for the ACA tools for VS Code extension", + "main": "server.js", + "scripts": { + "start": "node server.js" + } +} diff --git a/test/testProjects/monorepo-basic/app2/server.js b/test/testProjects/monorepo-basic/app2/server.js new file mode 100644 index 000000000..d7dfa5936 --- /dev/null +++ b/test/testProjects/monorepo-basic/app2/server.js @@ -0,0 +1,12 @@ +const http = require('http'); + +const port = process.env.PORT || 80; +const message = process.env.MESSAGE || 'world'; + +const server = http.createServer((_, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.write(`Hello ${message}\n`); +}); + +server.listen(port); +console.log(`Server running at http://localhost: ${port}`); diff --git a/test/testProjects/monorepo-basic/app3/.env.example b/test/testProjects/monorepo-basic/app3/.env.example new file mode 100644 index 000000000..b22bf27fe --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/.env.example @@ -0,0 +1,2 @@ +MESSAGE='container apps (app3)' +PORT=3002 diff --git a/test/testProjects/monorepo-basic/app3/Dockerfile b/test/testProjects/monorepo-basic/app3/Dockerfile new file mode 100644 index 000000000..252ccdcc7 --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine + +COPY . /src +RUN cd /src && npm install +EXPOSE 3002 +CMD ["node", "/src/server.js"] diff --git a/test/testProjects/monorepo-basic/app3/package.json b/test/testProjects/monorepo-basic/app3/package.json new file mode 100644 index 000000000..1b5b8b78d --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/package.json @@ -0,0 +1,9 @@ +{ + "name": "aca-hello-world-app3", + "version": "1.0.0", + "description": "Simple test app for the ACA tools for VS Code extension", + "main": "server.js", + "scripts": { + "start": "node server.js" + } +} diff --git a/test/testProjects/monorepo-basic/app3/server.js b/test/testProjects/monorepo-basic/app3/server.js new file mode 100644 index 000000000..9d64f1787 --- /dev/null +++ b/test/testProjects/monorepo-basic/app3/server.js @@ -0,0 +1,12 @@ +const http = require('http'); + +const port = process.env.PORT || 80; +const message = process.env.MESSAGE || 'world'; + +const server = http.createServer((_, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write(`Hello ${message}\n`); +}); + +server.listen(port); +console.log(`Server running at http://localhost: ${port}`); From f1cd5ee90df1009650e9fe910bf3808834fe00eb Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:54:41 -0700 Subject: [PATCH 38/54] Update readme title --- test/testProjects/monorepo-basic/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testProjects/monorepo-basic/README.md b/test/testProjects/monorepo-basic/README.md index 2213f189f..3f02450f1 100644 --- a/test/testProjects/monorepo-basic/README.md +++ b/test/testProjects/monorepo-basic/README.md @@ -1,3 +1,3 @@ -# ACA Hello World v2 +# Monorepo-basic -This extremely minimal Node.js monorepo is used for quickly testing simple scenarios in the Azure Container Apps Extension. \ No newline at end of file +This extremely minimal Node.js monorepo is used for quickly testing simple scenarios in the Azure Container Apps Extension. From 973d4a06df209738115df996fbab23653489fb07 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:12:53 -0700 Subject: [PATCH 39/54] Update timeouts --- test/global.test.ts | 2 +- test/nightly/global.nightly.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/global.test.ts b/test/global.test.ts index 8caffc75f..17270f084 100644 --- a/test/global.test.ts +++ b/test/global.test.ts @@ -13,7 +13,7 @@ export const longRunningTestsEnabled: boolean = !/^(false|0)?$/i.test(process.en // Runs before all tests suiteSetup(async function (this: Mocha.Context): Promise { - this.timeout(1 * 60 * 1000); + this.timeout(2 * 60 * 1000); const extension = vscode.extensions.getExtension('ms-azuretools.vscode-azurecontainerapps'); if (!extension) { diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 160a7308a..0d7380a4a 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -18,7 +18,7 @@ suiteSetup(async function (this: Mocha.Context): Promise { if (!longRunningTestsEnabled) { return; } - this.timeout(1 * 60 * 1000); + this.timeout(2 * 60 * 1000); await vscode.commands.executeCommand('azureResourceGroups.logIn'); }); From c8fb59be9bea03a6d34fe5ea3e1ad0312becc6b7 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:35:47 -0700 Subject: [PATCH 40/54] Update ports --- test/testProjects/monorepo-basic/app1/.env.example | 1 - test/testProjects/monorepo-basic/app1/server.js | 6 +++--- test/testProjects/monorepo-basic/app2/.env.example | 1 - test/testProjects/monorepo-basic/app2/server.js | 6 +++--- test/testProjects/monorepo-basic/app3/.env.example | 1 - test/testProjects/monorepo-basic/app3/server.js | 2 +- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/test/testProjects/monorepo-basic/app1/.env.example b/test/testProjects/monorepo-basic/app1/.env.example index f6b943bb5..9774d4ca3 100644 --- a/test/testProjects/monorepo-basic/app1/.env.example +++ b/test/testProjects/monorepo-basic/app1/.env.example @@ -1,2 +1 @@ MESSAGE='container apps (app1)' -PORT=3000 diff --git a/test/testProjects/monorepo-basic/app1/server.js b/test/testProjects/monorepo-basic/app1/server.js index d7dfa5936..112d7be02 100644 --- a/test/testProjects/monorepo-basic/app1/server.js +++ b/test/testProjects/monorepo-basic/app1/server.js @@ -1,11 +1,11 @@ const http = require('http'); -const port = process.env.PORT || 80; +const port = process.env.PORT || 3000; const message = process.env.MESSAGE || 'world'; const server = http.createServer((_, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.write(`Hello ${message}\n`); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write(`Hello ${message}\n`); }); server.listen(port); diff --git a/test/testProjects/monorepo-basic/app2/.env.example b/test/testProjects/monorepo-basic/app2/.env.example index dd82c9d77..6169562de 100644 --- a/test/testProjects/monorepo-basic/app2/.env.example +++ b/test/testProjects/monorepo-basic/app2/.env.example @@ -1,2 +1 @@ MESSAGE='container apps (app2)' -PORT=3001 diff --git a/test/testProjects/monorepo-basic/app2/server.js b/test/testProjects/monorepo-basic/app2/server.js index d7dfa5936..abccb6a24 100644 --- a/test/testProjects/monorepo-basic/app2/server.js +++ b/test/testProjects/monorepo-basic/app2/server.js @@ -1,11 +1,11 @@ const http = require('http'); -const port = process.env.PORT || 80; +const port = process.env.PORT || 3001; const message = process.env.MESSAGE || 'world'; const server = http.createServer((_, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.write(`Hello ${message}\n`); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write(`Hello ${message}\n`); }); server.listen(port); diff --git a/test/testProjects/monorepo-basic/app3/.env.example b/test/testProjects/monorepo-basic/app3/.env.example index b22bf27fe..b653a1fe5 100644 --- a/test/testProjects/monorepo-basic/app3/.env.example +++ b/test/testProjects/monorepo-basic/app3/.env.example @@ -1,2 +1 @@ MESSAGE='container apps (app3)' -PORT=3002 diff --git a/test/testProjects/monorepo-basic/app3/server.js b/test/testProjects/monorepo-basic/app3/server.js index 9d64f1787..afeae7f2a 100644 --- a/test/testProjects/monorepo-basic/app3/server.js +++ b/test/testProjects/monorepo-basic/app3/server.js @@ -1,6 +1,6 @@ const http = require('http'); -const port = process.env.PORT || 80; +const port = process.env.PORT || 3002; const message = process.env.MESSAGE || 'world'; const server = http.createServer((_, res) => { From d1bf0cf508bf4c3fc8c7c392c7712f1e358c4bc6 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 17 Jun 2024 10:04:34 -0700 Subject: [PATCH 41/54] Add albumapi-js repo --- test/testProjects/albumapi-js/.gitignore | 355 ++++++ test/testProjects/albumapi-js/LICENSE.md | 21 + test/testProjects/albumapi-js/README.md | 3 + test/testProjects/albumapi-js/src/.DS_Store | Bin 0 -> 6148 bytes .../albumapi-js/src/.dockerignore | 23 + test/testProjects/albumapi-js/src/Dockerfile | 10 + test/testProjects/albumapi-js/src/app.js | 23 + test/testProjects/albumapi-js/src/bin/www | 86 ++ .../src/controllers/AlbumController.js | 7 + .../albumapi-js/src/models/Album.js | 50 + .../albumapi-js/src/package-lock.json | 1004 +++++++++++++++++ .../testProjects/albumapi-js/src/package.json | 16 + .../albumapi-js/src/routes/index.js | 15 + 13 files changed, 1613 insertions(+) create mode 100644 test/testProjects/albumapi-js/.gitignore create mode 100644 test/testProjects/albumapi-js/LICENSE.md create mode 100644 test/testProjects/albumapi-js/README.md create mode 100644 test/testProjects/albumapi-js/src/.DS_Store create mode 100644 test/testProjects/albumapi-js/src/.dockerignore create mode 100644 test/testProjects/albumapi-js/src/Dockerfile create mode 100644 test/testProjects/albumapi-js/src/app.js create mode 100644 test/testProjects/albumapi-js/src/bin/www create mode 100644 test/testProjects/albumapi-js/src/controllers/AlbumController.js create mode 100644 test/testProjects/albumapi-js/src/models/Album.js create mode 100644 test/testProjects/albumapi-js/src/package-lock.json create mode 100644 test/testProjects/albumapi-js/src/package.json create mode 100644 test/testProjects/albumapi-js/src/routes/index.js diff --git a/test/testProjects/albumapi-js/.gitignore b/test/testProjects/albumapi-js/.gitignore new file mode 100644 index 000000000..b5a6be64c --- /dev/null +++ b/test/testProjects/albumapi-js/.gitignore @@ -0,0 +1,355 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Test project shouldn't start with .vscode directory +.vscode + +# Exceptions +!src/bin diff --git a/test/testProjects/albumapi-js/LICENSE.md b/test/testProjects/albumapi-js/LICENSE.md new file mode 100644 index 000000000..9e841e7a2 --- /dev/null +++ b/test/testProjects/albumapi-js/LICENSE.md @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/test/testProjects/albumapi-js/README.md b/test/testProjects/albumapi-js/README.md new file mode 100644 index 000000000..bbca48f32 --- /dev/null +++ b/test/testProjects/albumapi-js/README.md @@ -0,0 +1,3 @@ +# Azure Container Apps Album API + +Originally adapted from [this](https://github.com/Azure-Samples/containerapps-albumapi-javascript) repository, the companion repository for the [Azure Container Apps code-to-cloud quickstart](https://docs.microsoft.com/en-us/azure/container-apps/quickstart-code-to-cloud?tabs=bash%2Ccsharp&pivots=acr-remote). diff --git a/test/testProjects/albumapi-js/src/.DS_Store b/test/testProjects/albumapi-js/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..058ad2b668e41184785f41ab9f74b3c4e737aa9e GIT binary patch literal 6148 zcmeHKJ5Iwu5S>jdWE6^siqaK*#05-bPLKBYon&VWv?v8RGE99!D=*p~Q< z4)EN~XoGospeM{)J%5kc-D0&V@|~CcHqOk8Bw1(08jNrnzJ6XlzhD2vPLE*k?wcz3 zJ*5-Mp)mQhD#z=T$RQ`^URrLDuM6^(HQb+BIt__popa4({x(cjeZb=A<(;?z3E zI0HJ^6AN>|954rtaR6&JM>tco+8i(k%z?@Q{ysz~jIqa3Q9d20WD5Wckd{DO{?ULD zCxEfXQV|)1)1g2e>iibN>2TyD&x<{liaMN}+!@#LcXob<;^gkgM?xnTD_U(1m;-GG zrg}Q(_5Wsk|KA>DXXb!8@UI+jL9$AgcqG5J_8yMc+6d(qg@bveVl@N}S&G5srT79x Z0{Ms=z}RD{hz!Dh1jGib%z= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== "listen") { + throw error; + } + + var bind = typeof port === "string" ? "Pipe " + port : "Port " + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case "EACCES": + console.error(bind + " requires elevated privileges"); + process.exit(1); + break; + case "EADDRINUSE": + console.error(bind + " is already in use"); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port; + console.log("Listening on " + bind); +} \ No newline at end of file diff --git a/test/testProjects/albumapi-js/src/controllers/AlbumController.js b/test/testProjects/albumapi-js/src/controllers/AlbumController.js new file mode 100644 index 000000000..995e5852e --- /dev/null +++ b/test/testProjects/albumapi-js/src/controllers/AlbumController.js @@ -0,0 +1,7 @@ +var Albums = require("../models/Album"); + +exports.index = async function (req, res) { + const albums = await Albums.getAlbums(); + console.log("Retrieved Albums"); + res.json(albums); +}; diff --git a/test/testProjects/albumapi-js/src/models/Album.js b/test/testProjects/albumapi-js/src/models/Album.js new file mode 100644 index 000000000..6e41673c3 --- /dev/null +++ b/test/testProjects/albumapi-js/src/models/Album.js @@ -0,0 +1,50 @@ +const albums = [ + { + id: 1, + title: "You, Me and an App ID", + artist: "Daprize", + price: 56.99, + image_url: "https://aka.ms/albums-daprlogo", + }, + { + id: 2, + title: "Seven Revision Army", + artist: "The Blue-Green Stripes", + price: 17.99, + image_url: "https://aka.ms/albums-containerappslogo", + }, + { + id: 3, + title: "Scale It Up", + artist: "KEDA Club", + price: 39.99, + image_url: "https://aka.ms/albums-kedalogo", + }, + { + id: 4, + title: "Lost in Translation", + artist: "MegaDNS", + price: 39.99, + image_url: "https://aka.ms/albums-envoylogo", + }, + { + id: 5, + title: "Lock Down your Love", + artist: "V is for VNET", + price: 39.99, + image_url: "https://aka.ms/albums-vnetlogo", + }, + { + id: 6, + title: "Sweet Container O' Mine", + artist: "Guns N Probeses", + price: 39.99, + image_url: "https://aka.ms/albums-containerappslogo", + }, +]; + +const getAlbums = async function () { + return Promise.resolve(albums); +}; + +exports.getAlbums = getAlbums; diff --git a/test/testProjects/albumapi-js/src/package-lock.json b/test/testProjects/albumapi-js/src/package-lock.json new file mode 100644 index 000000000..f19cebbf3 --- /dev/null +++ b/test/testProjects/albumapi-js/src/package-lock.json @@ -0,0 +1,1004 @@ +{ + "name": "node", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "node", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "axios": "^0.26.0", + "express": "^4.17.3", + "morgan": "^1.10.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/axios": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", + "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + } + }, + "dependencies": { + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "axios": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", + "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "requires": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + } + } +} diff --git a/test/testProjects/albumapi-js/src/package.json b/test/testProjects/albumapi-js/src/package.json new file mode 100644 index 000000000..2aa4203f2 --- /dev/null +++ b/test/testProjects/albumapi-js/src/package.json @@ -0,0 +1,16 @@ +{ + "name": "node", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node ./bin/www" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^0.26.0", + "express": "^4.17.3", + "morgan": "^1.10.0" + } +} \ No newline at end of file diff --git a/test/testProjects/albumapi-js/src/routes/index.js b/test/testProjects/albumapi-js/src/routes/index.js new file mode 100644 index 000000000..12e9a1ee4 --- /dev/null +++ b/test/testProjects/albumapi-js/src/routes/index.js @@ -0,0 +1,15 @@ +var express = require("express"); +var router = express.Router(); +const orderController = require("../controllers/AlbumController"); + +// Root/Index Routes +router.get("/", function (req, res, next) { + res.json({ + message: "Call the /albums route to retrieve a list of albums", + }); +}); + +// get albums +router.get("/albums", orderController.index); + +module.exports = router; From 9c4a75721b84a43b9c3690379d37cb0d1564bb3e Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 17 Jun 2024 10:18:57 -0700 Subject: [PATCH 42/54] Update ms learn test cases --- .../testCases/msLearnJsTestCases.ts | 69 ++++++++++++++++++ .../deployWorkspaceProject/testScenarios.ts | 11 +-- test/test.code-workspace | 8 +- .../{albumapi-js => mslearn-js}/.gitignore | 0 .../{albumapi-js => mslearn-js}/LICENSE.md | 0 .../{albumapi-js => mslearn-js}/README.md | 0 .../{albumapi-js => mslearn-js}/src/.DS_Store | Bin .../src/.dockerignore | 0 .../src/Dockerfile | 0 .../{albumapi-js => mslearn-js}/src/app.js | 0 .../{albumapi-js => mslearn-js}/src/bin/www | 0 .../src/controllers/AlbumController.js | 0 .../src/models/Album.js | 0 .../src/package-lock.json | 0 .../src/package.json | 0 .../src/routes/index.js | 0 16 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 test/nightly/deployWorkspaceProject/testCases/msLearnJsTestCases.ts rename test/testProjects/{albumapi-js => mslearn-js}/.gitignore (100%) rename test/testProjects/{albumapi-js => mslearn-js}/LICENSE.md (100%) rename test/testProjects/{albumapi-js => mslearn-js}/README.md (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/.DS_Store (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/.dockerignore (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/Dockerfile (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/app.js (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/bin/www (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/controllers/AlbumController.js (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/models/Album.js (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/package-lock.json (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/package.json (100%) rename test/testProjects/{albumapi-js => mslearn-js}/src/routes/index.js (100%) diff --git a/test/nightly/deployWorkspaceProject/testCases/msLearnJsTestCases.ts b/test/nightly/deployWorkspaceProject/testCases/msLearnJsTestCases.ts new file mode 100644 index 000000000..b8e3b0980 --- /dev/null +++ b/test/nightly/deployWorkspaceProject/testCases/msLearnJsTestCases.ts @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { randomUtils } from "@microsoft/vscode-azext-utils"; +import * as path from "path"; +import { type DeploymentConfigurationSettings } from "../../../../extension.bundle"; +import { type StringOrRegExpProps } from "../../../typeUtils"; +import { dwpTestUtils } from "../dwpTestUtils"; +import { type DeployWorkspaceProjectTestCase } from "./DeployWorkspaceProjectTestCase"; + +export function generateMsLearnJsTestCases(): DeployWorkspaceProjectTestCase[] { + const folderName: string = 'mslearn-js'; + const appResourceName: string = 'album-api'; + const sharedResourceName: string = appResourceName + randomUtils.getRandomHexString(4); + const acrResourceName: string = sharedResourceName.replace(/[^a-zA-Z0-9]+/g, ''); + + return [ + { + label: 'Deploy App', + inputs: [ + new RegExp(folderName, 'i'), + new RegExp('Create new container apps environment', 'i'), + 'Continue', + sharedResourceName, + appResourceName, + `.${path.sep}src`, + 'East US', + 'Save' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, appResourceName), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, appResourceName) + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 8080, env: undefined }) + }, + { + label: 'Re-deploy App', + inputs: [ + new RegExp(folderName, 'i'), + appResourceName, + 'Continue' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, appResourceName), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, appResourceName) + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 8080, env: undefined }) + } + ]; +} + +function generateExpectedDeploymentConfiguration(sharedResourceName: string, acrResourceName: string, appResourceName: string): StringOrRegExpProps { + return { + label: appResourceName, + type: 'AcrDockerBuildRequest', + dockerfilePath: path.join('src', 'Dockerfile'), + srcPath: 'src', + envPath: '', + resourceGroup: sharedResourceName, + containerApp: appResourceName, + containerRegistry: new RegExp(`${acrResourceName}.{6}`, 'i'), + }; +} diff --git a/test/nightly/deployWorkspaceProject/testScenarios.ts b/test/nightly/deployWorkspaceProject/testScenarios.ts index 4ddfbd0e5..dbcea3d23 100644 --- a/test/nightly/deployWorkspaceProject/testScenarios.ts +++ b/test/nightly/deployWorkspaceProject/testScenarios.ts @@ -5,6 +5,7 @@ import { type DeployWorkspaceProjectTestCase } from "./testCases/DeployWorkspaceProjectTestCase"; import { generateMonoRepoBasicTestCases } from "./testCases/monoRepoBasicTestCases"; +import { generateMsLearnJsTestCases } from "./testCases/msLearnJsTestCases"; interface TestScenario { label: string; @@ -18,9 +19,9 @@ export const testScenarios: TestScenario[] = [ folderName: 'monorepo-basic', testCases: generateMonoRepoBasicTestCases() }, - // { - // label: 'albumapi-javascript', - // folderName: 'albumapi-javascript', - // testCases: generateAlbumApiJavaScriptTestCases() - // } + { + label: 'mslearn-js', + folderName: 'mslearn-js', + testCases: generateMsLearnJsTestCases() + } ]; diff --git a/test/test.code-workspace b/test/test.code-workspace index 8ea4b16c6..b3af158fa 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -8,9 +8,9 @@ "name": "monorepo-basic", "path": "./testProjects/monorepo-basic" }, - // { - // "name": "albumapi-javascript", - // "path": "./testProjects/albumapi-javascript" - // }, + { + "name": "mslearn-js", + "path": "./testProjects/mslearn-js" + }, ] } diff --git a/test/testProjects/albumapi-js/.gitignore b/test/testProjects/mslearn-js/.gitignore similarity index 100% rename from test/testProjects/albumapi-js/.gitignore rename to test/testProjects/mslearn-js/.gitignore diff --git a/test/testProjects/albumapi-js/LICENSE.md b/test/testProjects/mslearn-js/LICENSE.md similarity index 100% rename from test/testProjects/albumapi-js/LICENSE.md rename to test/testProjects/mslearn-js/LICENSE.md diff --git a/test/testProjects/albumapi-js/README.md b/test/testProjects/mslearn-js/README.md similarity index 100% rename from test/testProjects/albumapi-js/README.md rename to test/testProjects/mslearn-js/README.md diff --git a/test/testProjects/albumapi-js/src/.DS_Store b/test/testProjects/mslearn-js/src/.DS_Store similarity index 100% rename from test/testProjects/albumapi-js/src/.DS_Store rename to test/testProjects/mslearn-js/src/.DS_Store diff --git a/test/testProjects/albumapi-js/src/.dockerignore b/test/testProjects/mslearn-js/src/.dockerignore similarity index 100% rename from test/testProjects/albumapi-js/src/.dockerignore rename to test/testProjects/mslearn-js/src/.dockerignore diff --git a/test/testProjects/albumapi-js/src/Dockerfile b/test/testProjects/mslearn-js/src/Dockerfile similarity index 100% rename from test/testProjects/albumapi-js/src/Dockerfile rename to test/testProjects/mslearn-js/src/Dockerfile diff --git a/test/testProjects/albumapi-js/src/app.js b/test/testProjects/mslearn-js/src/app.js similarity index 100% rename from test/testProjects/albumapi-js/src/app.js rename to test/testProjects/mslearn-js/src/app.js diff --git a/test/testProjects/albumapi-js/src/bin/www b/test/testProjects/mslearn-js/src/bin/www similarity index 100% rename from test/testProjects/albumapi-js/src/bin/www rename to test/testProjects/mslearn-js/src/bin/www diff --git a/test/testProjects/albumapi-js/src/controllers/AlbumController.js b/test/testProjects/mslearn-js/src/controllers/AlbumController.js similarity index 100% rename from test/testProjects/albumapi-js/src/controllers/AlbumController.js rename to test/testProjects/mslearn-js/src/controllers/AlbumController.js diff --git a/test/testProjects/albumapi-js/src/models/Album.js b/test/testProjects/mslearn-js/src/models/Album.js similarity index 100% rename from test/testProjects/albumapi-js/src/models/Album.js rename to test/testProjects/mslearn-js/src/models/Album.js diff --git a/test/testProjects/albumapi-js/src/package-lock.json b/test/testProjects/mslearn-js/src/package-lock.json similarity index 100% rename from test/testProjects/albumapi-js/src/package-lock.json rename to test/testProjects/mslearn-js/src/package-lock.json diff --git a/test/testProjects/albumapi-js/src/package.json b/test/testProjects/mslearn-js/src/package.json similarity index 100% rename from test/testProjects/albumapi-js/src/package.json rename to test/testProjects/mslearn-js/src/package.json diff --git a/test/testProjects/albumapi-js/src/routes/index.js b/test/testProjects/mslearn-js/src/routes/index.js similarity index 100% rename from test/testProjects/albumapi-js/src/routes/index.js rename to test/testProjects/mslearn-js/src/routes/index.js From 27943e6e25e0c72f59941a50ce460dc127284a6f Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:43:37 -0700 Subject: [PATCH 43/54] Update names of things --- .vscode/launch.json | 2 +- ...sTestCases.ts => albumApiJavaScriptTestCases.ts} | 4 ++-- .../nightly/deployWorkspaceProject/testScenarios.ts | 8 ++++---- test/test.code-workspace | 4 ++-- .../.gitignore | 0 .../LICENSE.md | 0 .../README.md | 0 .../src/.DS_Store | Bin .../src/.dockerignore | 0 .../src/Dockerfile | 0 .../src/app.js | 0 .../src/bin/www | 0 .../src/controllers/AlbumController.js | 0 .../src/models/Album.js | 0 .../src/package-lock.json | 0 .../src/package.json | 0 .../src/routes/index.js | 0 test/testUtils.ts | 7 +------ 18 files changed, 10 insertions(+), 15 deletions(-) rename test/nightly/deployWorkspaceProject/testCases/{msLearnJsTestCases.ts => albumApiJavaScriptTestCases.ts} (95%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/.gitignore (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/LICENSE.md (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/README.md (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/.DS_Store (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/.dockerignore (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/Dockerfile (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/app.js (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/bin/www (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/controllers/AlbumController.js (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/models/Album.js (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/package-lock.json (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/package.json (100%) rename test/testProjects/{mslearn-js => containerapps-albumapi-javascript}/src/routes/index.js (100%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 333eb703e..a2a5afc78 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -92,7 +92,7 @@ "MOCHA_timeout": "0", // Disable time-outs "DEBUGTELEMETRY": "v", "NODE_DEBUG": "", - "ENABLE_LONG_RUNNING_TESTS": "" + "AzCode_UseAzureFederatedCredentials": "" } }, { diff --git a/test/nightly/deployWorkspaceProject/testCases/msLearnJsTestCases.ts b/test/nightly/deployWorkspaceProject/testCases/albumApiJavaScriptTestCases.ts similarity index 95% rename from test/nightly/deployWorkspaceProject/testCases/msLearnJsTestCases.ts rename to test/nightly/deployWorkspaceProject/testCases/albumApiJavaScriptTestCases.ts index b8e3b0980..dcdbf3e54 100644 --- a/test/nightly/deployWorkspaceProject/testCases/msLearnJsTestCases.ts +++ b/test/nightly/deployWorkspaceProject/testCases/albumApiJavaScriptTestCases.ts @@ -10,8 +10,8 @@ import { type StringOrRegExpProps } from "../../../typeUtils"; import { dwpTestUtils } from "../dwpTestUtils"; import { type DeployWorkspaceProjectTestCase } from "./DeployWorkspaceProjectTestCase"; -export function generateMsLearnJsTestCases(): DeployWorkspaceProjectTestCase[] { - const folderName: string = 'mslearn-js'; +export function generateAlbumApiJavaScriptTestCases(): DeployWorkspaceProjectTestCase[] { + const folderName: string = 'albumapi-js'; const appResourceName: string = 'album-api'; const sharedResourceName: string = appResourceName + randomUtils.getRandomHexString(4); const acrResourceName: string = sharedResourceName.replace(/[^a-zA-Z0-9]+/g, ''); diff --git a/test/nightly/deployWorkspaceProject/testScenarios.ts b/test/nightly/deployWorkspaceProject/testScenarios.ts index dbcea3d23..1139f987b 100644 --- a/test/nightly/deployWorkspaceProject/testScenarios.ts +++ b/test/nightly/deployWorkspaceProject/testScenarios.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { generateAlbumApiJavaScriptTestCases } from "./testCases/albumApiJavaScriptTestCases"; import { type DeployWorkspaceProjectTestCase } from "./testCases/DeployWorkspaceProjectTestCase"; import { generateMonoRepoBasicTestCases } from "./testCases/monoRepoBasicTestCases"; -import { generateMsLearnJsTestCases } from "./testCases/msLearnJsTestCases"; interface TestScenario { label: string; @@ -20,8 +20,8 @@ export const testScenarios: TestScenario[] = [ testCases: generateMonoRepoBasicTestCases() }, { - label: 'mslearn-js', - folderName: 'mslearn-js', - testCases: generateMsLearnJsTestCases() + label: 'albumapi-js', + folderName: 'albumapi-js', + testCases: generateAlbumApiJavaScriptTestCases() } ]; diff --git a/test/test.code-workspace b/test/test.code-workspace index b3af158fa..8fe574154 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -9,8 +9,8 @@ "path": "./testProjects/monorepo-basic" }, { - "name": "mslearn-js", - "path": "./testProjects/mslearn-js" + "name": "albumapi-js", + "path": "./testProjects/containerapps-albumapi-javascript" }, ] } diff --git a/test/testProjects/mslearn-js/.gitignore b/test/testProjects/containerapps-albumapi-javascript/.gitignore similarity index 100% rename from test/testProjects/mslearn-js/.gitignore rename to test/testProjects/containerapps-albumapi-javascript/.gitignore diff --git a/test/testProjects/mslearn-js/LICENSE.md b/test/testProjects/containerapps-albumapi-javascript/LICENSE.md similarity index 100% rename from test/testProjects/mslearn-js/LICENSE.md rename to test/testProjects/containerapps-albumapi-javascript/LICENSE.md diff --git a/test/testProjects/mslearn-js/README.md b/test/testProjects/containerapps-albumapi-javascript/README.md similarity index 100% rename from test/testProjects/mslearn-js/README.md rename to test/testProjects/containerapps-albumapi-javascript/README.md diff --git a/test/testProjects/mslearn-js/src/.DS_Store b/test/testProjects/containerapps-albumapi-javascript/src/.DS_Store similarity index 100% rename from test/testProjects/mslearn-js/src/.DS_Store rename to test/testProjects/containerapps-albumapi-javascript/src/.DS_Store diff --git a/test/testProjects/mslearn-js/src/.dockerignore b/test/testProjects/containerapps-albumapi-javascript/src/.dockerignore similarity index 100% rename from test/testProjects/mslearn-js/src/.dockerignore rename to test/testProjects/containerapps-albumapi-javascript/src/.dockerignore diff --git a/test/testProjects/mslearn-js/src/Dockerfile b/test/testProjects/containerapps-albumapi-javascript/src/Dockerfile similarity index 100% rename from test/testProjects/mslearn-js/src/Dockerfile rename to test/testProjects/containerapps-albumapi-javascript/src/Dockerfile diff --git a/test/testProjects/mslearn-js/src/app.js b/test/testProjects/containerapps-albumapi-javascript/src/app.js similarity index 100% rename from test/testProjects/mslearn-js/src/app.js rename to test/testProjects/containerapps-albumapi-javascript/src/app.js diff --git a/test/testProjects/mslearn-js/src/bin/www b/test/testProjects/containerapps-albumapi-javascript/src/bin/www similarity index 100% rename from test/testProjects/mslearn-js/src/bin/www rename to test/testProjects/containerapps-albumapi-javascript/src/bin/www diff --git a/test/testProjects/mslearn-js/src/controllers/AlbumController.js b/test/testProjects/containerapps-albumapi-javascript/src/controllers/AlbumController.js similarity index 100% rename from test/testProjects/mslearn-js/src/controllers/AlbumController.js rename to test/testProjects/containerapps-albumapi-javascript/src/controllers/AlbumController.js diff --git a/test/testProjects/mslearn-js/src/models/Album.js b/test/testProjects/containerapps-albumapi-javascript/src/models/Album.js similarity index 100% rename from test/testProjects/mslearn-js/src/models/Album.js rename to test/testProjects/containerapps-albumapi-javascript/src/models/Album.js diff --git a/test/testProjects/mslearn-js/src/package-lock.json b/test/testProjects/containerapps-albumapi-javascript/src/package-lock.json similarity index 100% rename from test/testProjects/mslearn-js/src/package-lock.json rename to test/testProjects/containerapps-albumapi-javascript/src/package-lock.json diff --git a/test/testProjects/mslearn-js/src/package.json b/test/testProjects/containerapps-albumapi-javascript/src/package.json similarity index 100% rename from test/testProjects/mslearn-js/src/package.json rename to test/testProjects/containerapps-albumapi-javascript/src/package.json diff --git a/test/testProjects/mslearn-js/src/routes/index.js b/test/testProjects/containerapps-albumapi-javascript/src/routes/index.js similarity index 100% rename from test/testProjects/mslearn-js/src/routes/index.js rename to test/testProjects/containerapps-albumapi-javascript/src/routes/index.js diff --git a/test/testUtils.ts b/test/testUtils.ts index c4d09d764..bc7ce7ac8 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as path from 'path'; import { workspace, type Uri, type WorkspaceFolder } from "vscode"; export function assertStringPropsMatch(results: Record, expectedResults: Record, errMsg?: string): void { @@ -23,17 +22,13 @@ export function assertStringPropsMatch(results: Record Date: Mon, 17 Jun 2024 14:55:52 -0700 Subject: [PATCH 44/54] Misc changes --- .vscode/launch.json | 4 ++-- .../testCases/monoRepoBasicTestCases.ts | 9 +++++---- test/testUtils.ts | 7 +------ 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 333eb703e..cc24d3b1a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -92,7 +92,7 @@ "MOCHA_timeout": "0", // Disable time-outs "DEBUGTELEMETRY": "v", "NODE_DEBUG": "", - "ENABLE_LONG_RUNNING_TESTS": "" + "AzCode_UseAzureFederatedCredentials": "" } }, { @@ -115,7 +115,7 @@ "DEBUGTELEMETRY": "v", "NODE_DEBUG": "", "DEBUG_WEBPACK": "1", - "ENABLE_LONG_RUNNING_TESTS": "" + "AzCode_UseAzureFederatedCredentials": "" } }, { diff --git a/test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts b/test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts index a71d76bc9..3c1c07990 100644 --- a/test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts +++ b/test/nightly/deployWorkspaceProject/testCases/monoRepoBasicTestCases.ts @@ -11,6 +11,7 @@ import { dwpTestUtils } from "../dwpTestUtils"; import { type DeployWorkspaceProjectTestCase } from "./DeployWorkspaceProjectTestCase"; export function generateMonoRepoBasicTestCases(): DeployWorkspaceProjectTestCase[] { + const folderName: string = 'monorepo-basic'; const sharedResourceName: string = 'monorepo-basic' + randomUtils.getRandomHexString(4); const acrResourceName: string = sharedResourceName.replace(/[^a-zA-Z0-9]+/g, ''); @@ -18,7 +19,7 @@ export function generateMonoRepoBasicTestCases(): DeployWorkspaceProjectTestCase { label: "Deploy App 1", inputs: [ - new RegExp('monorepo-basic', 'i'), + new RegExp(folderName, 'i'), path.join('app1', 'Dockerfile'), new RegExp('Create new container apps environment', 'i'), 'Continue', @@ -40,7 +41,7 @@ export function generateMonoRepoBasicTestCases(): DeployWorkspaceProjectTestCase { label: "Deploy App 2", inputs: [ - new RegExp('monorepo-basic', 'i'), + new RegExp(folderName, 'i'), new RegExp('Create and deploy new app configuration', 'i'), path.join('app2', 'Dockerfile'), new RegExp('(Recommended)', 'i'), // Select a container app environment @@ -62,7 +63,7 @@ export function generateMonoRepoBasicTestCases(): DeployWorkspaceProjectTestCase { label: "Deploy App 3", inputs: [ - new RegExp('monorepo-basic', 'i'), + new RegExp(folderName, 'i'), new RegExp('Create and deploy new app configuration', 'i'), path.join('app3', 'Dockerfile'), new RegExp('(Recommended)', 'i'), // Select a container app environment @@ -85,7 +86,7 @@ export function generateMonoRepoBasicTestCases(): DeployWorkspaceProjectTestCase { label: "Re-deploy App 1", inputs: [ - new RegExp('monorepo-basic', 'i'), + new RegExp(folderName, 'i'), 'app1', 'Continue' ], diff --git a/test/testUtils.ts b/test/testUtils.ts index c4d09d764..bc7ce7ac8 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as path from 'path'; import { workspace, type Uri, type WorkspaceFolder } from "vscode"; export function assertStringPropsMatch(results: Record, expectedResults: Record, errMsg?: string): void { @@ -23,17 +22,13 @@ export function assertStringPropsMatch(results: Record Date: Thu, 20 Jun 2024 18:27:25 -0700 Subject: [PATCH 45/54] Add shared subscription context --- .../nightly/deployWorkspaceProject/dwpTestUtils.ts | 14 ++++---------- test/nightly/global.nightly.test.ts | 10 +++++++--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/test/nightly/deployWorkspaceProject/dwpTestUtils.ts b/test/nightly/deployWorkspaceProject/dwpTestUtils.ts index e7eb2c003..c99acf8b5 100644 --- a/test/nightly/deployWorkspaceProject/dwpTestUtils.ts +++ b/test/nightly/deployWorkspaceProject/dwpTestUtils.ts @@ -5,11 +5,11 @@ import { type ContainerApp, type EnvironmentVar } from "@azure/arm-appcontainers"; import { parseAzureResourceId } from "@microsoft/vscode-azext-azureutils"; -import { createSubscriptionContext, nonNullProp, subscriptionExperience, type IActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils"; -import { type AzureSubscription } from "@microsoft/vscode-azureresources-api"; +import { nonNullProp, type IActionContext } from "@microsoft/vscode-azext-utils"; import * as assert from "assert"; -import { createContainerAppsAPIClient, ext, type DeployWorkspaceProjectResults } from "../../../extension.bundle"; +import { createContainerAppsAPIClient, type DeployWorkspaceProjectResults } from "../../../extension.bundle"; import { type StringOrRegExpProps } from "../../typeUtils"; +import { subscriptionContext } from "../global.nightly.test"; import { type PostTestAssertion } from "./testCases/DeployWorkspaceProjectTestCase"; export namespace dwpTestUtils { @@ -30,15 +30,9 @@ export namespace dwpTestUtils { export function generatePostTestAssertion(expectedContainerAppSettings: { targetPort: number | undefined, env: EnvironmentVar[] | undefined }): PostTestAssertion { return async function postTestAssertion(context: IActionContext, resources: DeployWorkspaceProjectResults, errMsg?: string): Promise { const parsedId = parseAzureResourceId(nonNullProp(resources, 'containerAppId')); - - const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider, { - selectBySubscriptionId: parsedId.subscriptionId, - showLoadingPrompt: false - }); - const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); - const client = await createContainerAppsAPIClient(Object.assign(context, subscriptionContext)); const containerApp: ContainerApp = await client.containerApps.get(parsedId.resourceGroup, parsedId.resourceName); + assert.strictEqual(containerApp.configuration?.ingress?.targetPort, expectedContainerAppSettings.targetPort, errMsg ? errMsg + ' (container app target port)' : undefined); assert.strictEqual(containerApp.template?.containers?.[0].image, `${resources.registryLoginServer}/${resources.imageName}`, errMsg ? errMsg + ' (container image name)' : undefined); assert.deepStrictEqual(containerApp.template?.containers?.[0].env, expectedContainerAppSettings.env, errMsg ? errMsg + ' (container environment variables)' : undefined); diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index 0d7380a4a..dd213e5f2 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -12,14 +12,20 @@ import * as vscode from 'vscode'; import { ext } from '../../extension.bundle'; import { longRunningTestsEnabled } from '../global.test'; +export let subscriptionContext: ISubscriptionContext; export const resourceGroupsToDelete = new Set(); suiteSetup(async function (this: Mocha.Context): Promise { if (!longRunningTestsEnabled) { - return; + this.skip(); } + this.timeout(2 * 60 * 1000); await vscode.commands.executeCommand('azureResourceGroups.logIn'); + + const context: TestActionContext = await createTestActionContext(); + const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); + subscriptionContext = createSubscriptionContext(subscription); }); suiteTeardown(async function (this: Mocha.Context): Promise { @@ -34,8 +40,6 @@ suiteTeardown(async function (this: Mocha.Context): Promise { async function deleteResourceGroups(): Promise { const context: TestActionContext = await createTestActionContext(); - const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider); - const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription); const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); await Promise.all(Array.from(resourceGroupsToDelete).map(async resourceGroup => { From 9c87453f00df55e3e9b9cbc4e3655d6cea3c70b6 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 25 Jun 2024 21:23:05 -0400 Subject: [PATCH 46/54] Alternate registry naming solution --- .../internal/SharedResourcesNameStep.ts | 21 ++----------------- .../acr/createAcr/RegistryNameStep.ts | 11 ++++++++-- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts index 96bd9c6be..c8d41c828 100644 --- a/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts +++ b/src/commands/deployWorkspaceProject/internal/SharedResourcesNameStep.ts @@ -18,12 +18,7 @@ export class SharedResourcesNameStep extends AzureWizardPromptStep { if ((context.resourceGroup || context.managedEnvironment) && !context.registry) { // Generate a new name automatically without prompting - context.newRegistryName = await RegistryNameStep.tryGenerateRelatedName(context, context.managedEnvironment?.name || nonNullValueAndProp(context.resourceGroup, 'name')); - - if (!context.newRegistryName) { - // Extremely unlikely that this code block would ever trigger - throw new Error(localize('failedToGenerateName', 'Failed to generate an available container registry name.')); - } + context.newRegistryName = await RegistryNameStep.generateRelatedName(context, context.managedEnvironment?.name || nonNullValueAndProp(context.resourceGroup, 'name')); } } @@ -39,10 +34,7 @@ export class SharedResourcesNameStep extends AzureWizardPromptStep { const resourceNameUnavailable: string = localize('resourceNameUnavailable', 'Resource name "{0}" is unavailable.', name); - if (context.registry) { - // Skip check, one already exists so don't need to worry about naming - } else { - context.newRegistryName = await RegistryNameStep.tryGenerateRelatedName(context, name); - if (!context.newRegistryName) { - return localize('timeoutError', 'Timed out waiting for registry name to be generated. Please try another name.'); - } - } - const resourceGroupAvailable: boolean = !!context.resourceGroup || await ResourceGroupListStep.isNameAvailable(context, name); if (!resourceGroupAvailable) { return `Resource group: ${resourceNameUnavailable}`; diff --git a/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts b/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts index 9b19b4b4f..f138c26c2 100644 --- a/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts +++ b/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts @@ -52,7 +52,10 @@ export class RegistryNameStep extends AzureWizardPromptStep { } } - public static async tryGenerateRelatedName(context: ISubscriptionActionContext & { registry?: Registry }, name: string): Promise { + /** + * @throws Throws an error if the function is unable to generate a valid registry name within the internally allotted timeout + */ + public static async generateRelatedName(context: ISubscriptionActionContext & { registry?: Registry }, name: string): Promise { let registryAvailable: boolean = false; let generatedName: string = ''; @@ -62,13 +65,17 @@ export class RegistryNameStep extends AzureWizardPromptStep { do { if (Date.now() > start + timeoutMs) { - return undefined; + break; } generatedName = generateRelatedName(name); registryAvailable = !!context.registry || !!(await RegistryNameStep.isNameAvailable(context, generatedName)).nameAvailable; } while (!registryAvailable) + if (!registryAvailable) { + throw new Error(localize('failedToGenerateName', 'Failed to generate an available container registry name.')); + } + return generatedName; function generateRelatedName(name: string): string { From 88a008ff8cd1dd12de49959cbb9a8da918371fc0 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:15:05 -0400 Subject: [PATCH 47/54] Rename test scenarios --- .../deployWorkspaceProject/deployWorkspaceProject.test.ts | 4 ++-- .../{testScenarios.ts => dwpTestScenarios.ts} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename test/nightly/deployWorkspaceProject/{testScenarios.ts => dwpTestScenarios.ts} (88%) diff --git a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts index c57ddde98..539a354a8 100644 --- a/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts +++ b/test/nightly/deployWorkspaceProject/deployWorkspaceProject.test.ts @@ -12,7 +12,7 @@ import { AzExtFsExtra, deployWorkspaceProject, dwpSettingUtilsV2, settingUtils, import { longRunningTestsEnabled } from '../../global.test'; import { assertStringPropsMatch, getWorkspaceFolderUri } from '../../testUtils'; import { resourceGroupsToDelete } from '../global.nightly.test'; -import { testScenarios } from './testScenarios'; +import { dwpTestScenarios } from './dwpTestScenarios'; suite('deployWorkspaceProject', function (this: Mocha.Suite) { this.timeout(15 * 60 * 1000); @@ -23,7 +23,7 @@ suite('deployWorkspaceProject', function (this: Mocha.Suite) { } }); - for (const scenario of testScenarios) { + for (const scenario of dwpTestScenarios) { suite(scenario.label, function () { const workspaceFolderUri: Uri = getWorkspaceFolderUri(scenario.folderName); const rootFolder: WorkspaceFolder | undefined = workspace.getWorkspaceFolder(workspaceFolderUri); diff --git a/test/nightly/deployWorkspaceProject/testScenarios.ts b/test/nightly/deployWorkspaceProject/dwpTestScenarios.ts similarity index 88% rename from test/nightly/deployWorkspaceProject/testScenarios.ts rename to test/nightly/deployWorkspaceProject/dwpTestScenarios.ts index 4ddfbd0e5..b2d7e3fb4 100644 --- a/test/nightly/deployWorkspaceProject/testScenarios.ts +++ b/test/nightly/deployWorkspaceProject/dwpTestScenarios.ts @@ -6,13 +6,13 @@ import { type DeployWorkspaceProjectTestCase } from "./testCases/DeployWorkspaceProjectTestCase"; import { generateMonoRepoBasicTestCases } from "./testCases/monoRepoBasicTestCases"; -interface TestScenario { +interface DeployWorkspaceProjectTestScenario { label: string; folderName: string; testCases: DeployWorkspaceProjectTestCase[]; } -export const testScenarios: TestScenario[] = [ +export const dwpTestScenarios: DeployWorkspaceProjectTestScenario[] = [ { label: 'monorepo', folderName: 'monorepo-basic', From c46d62c3b2e37416e09267bae25767165b2d73bb Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:19:17 -0400 Subject: [PATCH 48/54] Use a more generic interface comment --- .../testCases/DeployWorkspaceProjectTestCase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts b/test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts index b5d608bd8..8b62e4100 100644 --- a/test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts +++ b/test/nightly/deployWorkspaceProject/testCases/DeployWorkspaceProjectTestCase.ts @@ -12,7 +12,7 @@ export interface DeployWorkspaceProjectTestCase { */ label: string; /** - * The list of inputs that will be passed directly to `TestUserInput.runWithInputs()` + * The list of inputs that will be passed to the test UI */ inputs: (string | RegExp)[]; /** From 15f98e335e995d174ead8c90b36a4c1422c1ca24 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:03:06 -0700 Subject: [PATCH 49/54] Simplify generateRelatedName --- .../containerRegistry/acr/createAcr/RegistryNameStep.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts b/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts index f138c26c2..fcedce591 100644 --- a/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts +++ b/src/commands/image/imageSource/containerRegistry/acr/createAcr/RegistryNameStep.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { type ContainerRegistryManagementClient, type Registry, type RegistryNameStatus } from "@azure/arm-containerregistry"; +import { type ContainerRegistryManagementClient, type RegistryNameStatus } from "@azure/arm-containerregistry"; import { AzureWizardPromptStep, randomUtils, type ISubscriptionActionContext } from "@microsoft/vscode-azext-utils"; import { createContainerRegistryManagementClient } from "../../../../../../utils/azureClients"; import { localize } from "../../../../../../utils/localize"; @@ -53,9 +53,9 @@ export class RegistryNameStep extends AzureWizardPromptStep { } /** - * @throws Throws an error if the function is unable to generate a valid registry name within the internally allotted timeout + * @throws Throws an error if the function is unable to generate a valid registry name within the allotted time */ - public static async generateRelatedName(context: ISubscriptionActionContext & { registry?: Registry }, name: string): Promise { + public static async generateRelatedName(context: ISubscriptionActionContext, name: string): Promise { let registryAvailable: boolean = false; let generatedName: string = ''; @@ -69,7 +69,7 @@ export class RegistryNameStep extends AzureWizardPromptStep { } generatedName = generateRelatedName(name); - registryAvailable = !!context.registry || !!(await RegistryNameStep.isNameAvailable(context, generatedName)).nameAvailable; + registryAvailable = !!(await RegistryNameStep.isNameAvailable(context, generatedName)).nameAvailable; } while (!registryAvailable) if (!registryAvailable) { From 072819bde43b80712e1728c8f2902837e43e6d6e Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:13:33 -0700 Subject: [PATCH 50/54] allSettled --- test/nightly/global.nightly.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts index dd213e5f2..4ab0a5734 100644 --- a/test/nightly/global.nightly.test.ts +++ b/test/nightly/global.nightly.test.ts @@ -42,7 +42,7 @@ async function deleteResourceGroups(): Promise { const context: TestActionContext = await createTestActionContext(); const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); - await Promise.all(Array.from(resourceGroupsToDelete).map(async resourceGroup => { + await Promise.allSettled(Array.from(resourceGroupsToDelete).map(async resourceGroup => { if (!(await rgClient.resourceGroups.checkExistence(resourceGroup)).body) { return; } From 4194a58191b7107d5ea8adbb08537a20bf0f68bb Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:53:36 -0700 Subject: [PATCH 51/54] Add go test repo --- .../containerapps-albumapi-go/.gitignore | 93 +++++++++++++++++++ .../containerapps-albumapi-go/LICENSE.md | 21 +++++ .../containerapps-albumapi-go/README.md | 3 + .../src/.dockerignore | 24 +++++ .../containerapps-albumapi-go/src/Dockerfile | 19 ++++ .../src/controllers/album/album.go | 23 +++++ .../containerapps-albumapi-go/src/go.mod | 8 ++ .../containerapps-albumapi-go/src/go.sum | 4 + .../containerapps-albumapi-go/src/main.go | 50 ++++++++++ .../src/models/models.go | 43 +++++++++ 10 files changed, 288 insertions(+) create mode 100644 test/testProjects/containerapps-albumapi-go/.gitignore create mode 100644 test/testProjects/containerapps-albumapi-go/LICENSE.md create mode 100644 test/testProjects/containerapps-albumapi-go/README.md create mode 100644 test/testProjects/containerapps-albumapi-go/src/.dockerignore create mode 100644 test/testProjects/containerapps-albumapi-go/src/Dockerfile create mode 100644 test/testProjects/containerapps-albumapi-go/src/controllers/album/album.go create mode 100644 test/testProjects/containerapps-albumapi-go/src/go.mod create mode 100644 test/testProjects/containerapps-albumapi-go/src/go.sum create mode 100644 test/testProjects/containerapps-albumapi-go/src/main.go create mode 100644 test/testProjects/containerapps-albumapi-go/src/models/models.go diff --git a/test/testProjects/containerapps-albumapi-go/.gitignore b/test/testProjects/containerapps-albumapi-go/.gitignore new file mode 100644 index 000000000..fbee278b2 --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/.gitignore @@ -0,0 +1,93 @@ +# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig + +# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,go +# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,macos,go + +### Go ### +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work + +### Go Patch ### +/vendor/ +/Godeps/ + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope +.vscode/*.code-snippets + +# Ignore code-workspaces +*.code-workspace + +# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,go + +# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) + diff --git a/test/testProjects/containerapps-albumapi-go/LICENSE.md b/test/testProjects/containerapps-albumapi-go/LICENSE.md new file mode 100644 index 000000000..79656060d --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/LICENSE.md @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE \ No newline at end of file diff --git a/test/testProjects/containerapps-albumapi-go/README.md b/test/testProjects/containerapps-albumapi-go/README.md new file mode 100644 index 000000000..04249a7f0 --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/README.md @@ -0,0 +1,3 @@ +# Azure Container Apps Album API + +Originally adapted from [this](https://github.com/azure-samples/containerapps-albumapi-go) repository, the companion repository for the [Azure Container Apps code-to-cloud quickstart](https://learn.microsoft.com/en-us/azure/container-apps/quickstart-code-to-cloud?tabs=bash%2Cgo&pivots=with-dockerfile). diff --git a/test/testProjects/containerapps-albumapi-go/src/.dockerignore b/test/testProjects/containerapps-albumapi-go/src/.dockerignore new file mode 100644 index 000000000..720e7a089 --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/src/.dockerignore @@ -0,0 +1,24 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +README.md diff --git a/test/testProjects/containerapps-albumapi-go/src/Dockerfile b/test/testProjects/containerapps-albumapi-go/src/Dockerfile new file mode 100644 index 000000000..fcffe03b3 --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/src/Dockerfile @@ -0,0 +1,19 @@ +# Dockerfile References: https://docs.docker.com/engine/reference/builder/ + +# Start from the latest golang base image +FROM golang:latest + +# Set the Current Working Directory inside the container +WORKDIR /app + +# Add files to app folder +ADD . /app + +# Build the Go app +RUN go build -o main . + +# Expose ports to the outside world +EXPOSE 8080 + +# Command to run the executable +CMD ["./main"] diff --git a/test/testProjects/containerapps-albumapi-go/src/controllers/album/album.go b/test/testProjects/containerapps-albumapi-go/src/controllers/album/album.go new file mode 100644 index 000000000..4ea01a0bb --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/src/controllers/album/album.go @@ -0,0 +1,23 @@ +package album + +import ( + "album-service/models" + "encoding/json" + "fmt" + "net/http" +) + +func init() { + fmt.Println("Initialize - album package") +} + +// Get function +func Get(w http.ResponseWriter, r *http.Request) { + + // serialize data + j, _ := json.Marshal(models.GetAlbums()) + + // set response + w.Header().Set("Content-Type", "application/json") + w.Write(j) +} \ No newline at end of file diff --git a/test/testProjects/containerapps-albumapi-go/src/go.mod b/test/testProjects/containerapps-albumapi-go/src/go.mod new file mode 100644 index 000000000..8d8bad649 --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/src/go.mod @@ -0,0 +1,8 @@ +module album-service + +go 1.17 + +require ( + github.com/gorilla/mux v1.8.0 + github.com/rs/cors v1.8.2 +) diff --git a/test/testProjects/containerapps-albumapi-go/src/go.sum b/test/testProjects/containerapps-albumapi-go/src/go.sum new file mode 100644 index 000000000..05363f9df --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/src/go.sum @@ -0,0 +1,4 @@ +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= +github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= diff --git a/test/testProjects/containerapps-albumapi-go/src/main.go b/test/testProjects/containerapps-albumapi-go/src/main.go new file mode 100644 index 000000000..a4deffdbc --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/src/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "album-service/controllers/album" + "fmt" + "log" + "net/http" + "os" + "strings" + + "github.com/gorilla/mux" + "github.com/rs/cors" +) + +func main() { + + // router implementation + router := mux.NewRouter() + + // adding cors + c := cors.AllowAll() + handler := c.Handler(router) + + port, ok := os.LookupEnv("PORT") + if !ok { + port = "8080" + } + + router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, "Access /albums to see the list of albums") + }) + + router.HandleFunc("/albums", album.Get).Methods("GET") + + // listen and serve + log.Printf("will listen on %v\n", port) + if err := http.ListenAndServe(":" + port, trailingSlashHandler(handler)); err != nil { + log.Fatalf("unable to start http server, %s", err) + } +} + +func trailingSlashHandler(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + r.URL.Path = strings.TrimSuffix(r.URL.Path, "/") + } + next.ServeHTTP(w, r) + }) +} diff --git a/test/testProjects/containerapps-albumapi-go/src/models/models.go b/test/testProjects/containerapps-albumapi-go/src/models/models.go new file mode 100644 index 000000000..2064186e5 --- /dev/null +++ b/test/testProjects/containerapps-albumapi-go/src/models/models.go @@ -0,0 +1,43 @@ +package models + +import ( + "fmt" +) + +func init() { + fmt.Println("Initialize - models package") +} + +type Album struct { + Id int `json:"id"` + Title string `json:"title"` + Artist string `json:"artist"` + Price float64 `json:"price"` + Image_URL string `json:"image_url"` +} + +func GetAlbums() []Album { + + var albums []Album + + album1 := Album{Id: 1, Title: "You, Me and an App ID", Artist: "Daprize", Price: 56.99, Image_URL: "https://aka.ms/albums-daprlogo"} + albums = append(albums, album1) + + album2 := Album{Id: 2, Title: "Seven Revision Army", Artist: "The Blue-Green Stripes", Price: 39.99, Image_URL: "https://aka.ms/albums-containerappslogo"} + albums = append(albums, album2) + + album3 := Album{Id: 3, Title: "Scale It Up", Artist: "KEDA Club", Price: 17.99, Image_URL: "https://aka.ms/albums-kedalogo"} + albums = append(albums, album3) + + album4 := Album{Id: 4, Title: "Lost in Translation", Artist: "MegaDNS", Price: 39.99, Image_URL: "https://aka.ms/albums-envoylogo"} + albums = append(albums, album4) + + album5 := Album{Id: 5, Title: "Lock Down Your Love", Artist: "V is for VNET", Price: 39.99, Image_URL: "https://aka.ms/albums-vnetlogo"} + albums = append(albums, album5) + + album6 := Album{Id: 6, Title: "Sweet Container O' Mine", Artist: "Guns N Probeses", Price: 29.99, Image_URL: "https://aka.ms/albums-containerappslogo"} + albums = append(albums, album6) + + return albums + +}; \ No newline at end of file From 603479bc6a0b261e0d029fe797fb207062d4bb9e Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:54:18 -0700 Subject: [PATCH 52/54] Update readme link --- test/testProjects/containerapps-albumapi-javascript/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testProjects/containerapps-albumapi-javascript/README.md b/test/testProjects/containerapps-albumapi-javascript/README.md index bbca48f32..c061f118f 100644 --- a/test/testProjects/containerapps-albumapi-javascript/README.md +++ b/test/testProjects/containerapps-albumapi-javascript/README.md @@ -1,3 +1,3 @@ # Azure Container Apps Album API -Originally adapted from [this](https://github.com/Azure-Samples/containerapps-albumapi-javascript) repository, the companion repository for the [Azure Container Apps code-to-cloud quickstart](https://docs.microsoft.com/en-us/azure/container-apps/quickstart-code-to-cloud?tabs=bash%2Ccsharp&pivots=acr-remote). +Originally adapted from [this](https://github.com/Azure-Samples/containerapps-albumapi-javascript) repository, the companion repository for the [Azure Container Apps code-to-cloud quickstart](https://learn.microsoft.com/en-us/azure/container-apps/quickstart-code-to-cloud?tabs=bash%2Cjavascript&pivots=with-dockerfile). From f543a3420b563073313ebc9da6552a2887b7c027 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:03:13 -0700 Subject: [PATCH 53/54] Golang test cases --- .../dwpTestScenarios.ts | 14 ++-- .../testCases/albumApiGolangTestCases.ts | 69 +++++++++++++++++++ test/test.code-workspace | 4 ++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 test/nightly/deployWorkspaceProject/testCases/albumApiGolangTestCases.ts diff --git a/test/nightly/deployWorkspaceProject/dwpTestScenarios.ts b/test/nightly/deployWorkspaceProject/dwpTestScenarios.ts index 58fe3bb51..f3f774215 100644 --- a/test/nightly/deployWorkspaceProject/dwpTestScenarios.ts +++ b/test/nightly/deployWorkspaceProject/dwpTestScenarios.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { generateAlbumApiGolangTestCases } from "./testCases/albumApiGolangTestCases"; import { generateAlbumApiJavaScriptTestCases } from "./testCases/albumApiJavaScriptTestCases"; import { type DeployWorkspaceProjectTestCase } from "./testCases/DeployWorkspaceProjectTestCase"; import { generateMonoRepoBasicTestCases } from "./testCases/monoRepoBasicTestCases"; @@ -15,13 +16,18 @@ interface DeployWorkspaceProjectTestScenario { export const dwpTestScenarios: DeployWorkspaceProjectTestScenario[] = [ { - label: 'monorepo', - folderName: 'monorepo-basic', - testCases: generateMonoRepoBasicTestCases() + label: 'albumapi-go', + folderName: 'albumapi-go', + testCases: generateAlbumApiGolangTestCases() }, { label: 'albumapi-js', folderName: 'albumapi-js', testCases: generateAlbumApiJavaScriptTestCases() - } + }, + { + label: 'monorepo', + folderName: 'monorepo-basic', + testCases: generateMonoRepoBasicTestCases() + }, ]; diff --git a/test/nightly/deployWorkspaceProject/testCases/albumApiGolangTestCases.ts b/test/nightly/deployWorkspaceProject/testCases/albumApiGolangTestCases.ts new file mode 100644 index 000000000..1f1f166ac --- /dev/null +++ b/test/nightly/deployWorkspaceProject/testCases/albumApiGolangTestCases.ts @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { randomUtils } from "@microsoft/vscode-azext-utils"; +import * as path from "path"; +import { type DeploymentConfigurationSettings } from "../../../../extension.bundle"; +import { type StringOrRegExpProps } from "../../../typeUtils"; +import { dwpTestUtils } from "../dwpTestUtils"; +import { type DeployWorkspaceProjectTestCase } from "./DeployWorkspaceProjectTestCase"; + +export function generateAlbumApiGolangTestCases(): DeployWorkspaceProjectTestCase[] { + const folderName: string = 'albumapi-go'; + const appResourceName: string = 'album-api'; + const sharedResourceName: string = appResourceName + randomUtils.getRandomHexString(4); + const acrResourceName: string = sharedResourceName.replace(/[^a-zA-Z0-9]+/g, ''); + + return [ + { + label: 'Deploy App', + inputs: [ + new RegExp(folderName, 'i'), + new RegExp('Create new container apps environment', 'i'), + 'Continue', + sharedResourceName, + appResourceName, + `.${path.sep}src`, + 'East US', + 'Save' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, appResourceName), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, appResourceName) + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 8080, env: undefined }) + }, + { + label: 'Re-deploy App', + inputs: [ + new RegExp(folderName, 'i'), + appResourceName, + 'Continue' + ], + expectedResults: dwpTestUtils.generateExpectedResults(sharedResourceName, acrResourceName, appResourceName), + expectedVSCodeSettings: { + deploymentConfigurations: [ + generateExpectedDeploymentConfiguration(sharedResourceName, acrResourceName, appResourceName) + ] + }, + postTestAssertion: dwpTestUtils.generatePostTestAssertion({ targetPort: 8080, env: undefined }) + } + ]; +} + +function generateExpectedDeploymentConfiguration(sharedResourceName: string, acrResourceName: string, appResourceName: string): StringOrRegExpProps { + return { + label: appResourceName, + type: 'AcrDockerBuildRequest', + dockerfilePath: path.join('src', 'Dockerfile'), + srcPath: 'src', + envPath: '', + resourceGroup: sharedResourceName, + containerApp: appResourceName, + containerRegistry: new RegExp(`${acrResourceName}.{6}`, 'i'), + }; +} diff --git a/test/test.code-workspace b/test/test.code-workspace index 8fe574154..6dd1f921f 100644 --- a/test/test.code-workspace +++ b/test/test.code-workspace @@ -12,5 +12,9 @@ "name": "albumapi-js", "path": "./testProjects/containerapps-albumapi-javascript" }, + { + "name": "albumapi-go", + "path": "./testProjects/containerapps-albumapi-go" + }, ] } From 8ba3c383fb4731db32818bd6bbc1fc55af805a2c Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 27 Jun 2024 17:21:17 -0700 Subject: [PATCH 54/54] Trick for package-lock merge --- .../src/package-lock.json | 1004 ----------------- 1 file changed, 1004 deletions(-) delete mode 100644 test/testProjects/containerapps-albumapi-javascript/src/package-lock.json diff --git a/test/testProjects/containerapps-albumapi-javascript/src/package-lock.json b/test/testProjects/containerapps-albumapi-javascript/src/package-lock.json deleted file mode 100644 index f19cebbf3..000000000 --- a/test/testProjects/containerapps-albumapi-javascript/src/package-lock.json +++ /dev/null @@ -1,1004 +0,0 @@ -{ - "name": "node", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "node", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "axios": "^0.26.0", - "express": "^4.17.3", - "morgan": "^1.10.0" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.19.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.7", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - } - }, - "dependencies": { - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", - "requires": { - "follow-redirects": "^1.14.8" - } - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.19.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.7", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "requires": { - "mime-db": "1.51.0" - } - }, - "morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "requires": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "dependencies": { - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", - "requires": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - } - } -}