diff --git a/extension.bundle.ts b/extension.bundle.ts index f903f673..45fe5e5b 100644 --- a/extension.bundle.ts +++ b/extension.bundle.ts @@ -29,7 +29,6 @@ export * as constants from './src/constants'; // Export activate/deactivate for main.js export { activateInternal, deactivateInternal } from './src/extension'; export { ext } from './src/extensionVariables'; -export { AzureAccountTreeItem } from './src/tree/AzureAccountTreeItem'; export { SiteTreeItem } from './src/tree/SiteTreeItem'; export * from './src/utils/azureClients'; export { getRandomHexString } from './src/utils/randomUtils'; diff --git a/src/extensionVariables.ts b/src/extensionVariables.ts index d46304a2..50194314 100644 --- a/src/extensionVariables.ts +++ b/src/extensionVariables.ts @@ -7,7 +7,6 @@ import { type IAzExtOutputChannel, type IExperimentationServiceAdapter } from "@ import { type AzureHostExtensionApi } from "@microsoft/vscode-azext-utils/hostapi"; import { type ExtensionContext } from "vscode"; import { type AppServiceFileSystem } from "./AppServiceFileSystem"; -import { type AzureAccountTreeItem } from "./tree/AzureAccountTreeItem"; /** * Namespace for common variables used throughout the extension. They must be initialized in the activate() method of extension.ts @@ -19,7 +18,6 @@ export namespace ext { export let fileSystem: AppServiceFileSystem; export const prefix: string = 'appService'; - export let azureAccountTreeItem: AzureAccountTreeItem; export let experimentationService: IExperimentationServiceAdapter; export let rgApi: AzureHostExtensionApi; } diff --git a/src/tree/AzureAccountTreeItem.ts b/src/tree/AzureAccountTreeItem.ts deleted file mode 100644 index a42b0ac6..00000000 --- a/src/tree/AzureAccountTreeItem.ts +++ /dev/null @@ -1,18 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { AzureAccountTreeItemBase } from '@microsoft/vscode-azext-azureutils'; -import { type ISubscriptionContext } from '@microsoft/vscode-azext-utils'; -import { SubscriptionTreeItem } from './SubscriptionTreeItem'; - -export class AzureAccountTreeItem extends AzureAccountTreeItemBase { - public constructor(testAccount?: {}) { - super(undefined, testAccount); - } - - public createSubscriptionTreeItem(root: ISubscriptionContext): SubscriptionTreeItem { - return new SubscriptionTreeItem(this, root); - } -} diff --git a/test/global.test.ts b/test/global.test.ts index 7d80b519..9b64854b 100644 --- a/test/global.test.ts +++ b/test/global.test.ts @@ -3,9 +3,10 @@ * 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 vscode from 'vscode'; -import { ext, registerOnActionStartHandler } from '../extension.bundle'; +import { ext, registerOnActionStartHandler, registerUIExtensionVariables } from '../extension.bundle'; const longRunningLocalTestsEnabled: boolean = !/^(false|0)?$/i.test(process.env.AzCode_EnableLongRunningTestsLocal || ''); const longRunningRemoteTestsEnabled: boolean = !/^(false|0)?$/i.test(process.env.AzCode_UseAzureFederatedCredentials || ''); @@ -16,7 +17,10 @@ export const longRunningTestsEnabled: boolean = longRunningLocalTestsEnabled || suiteSetup(async function (this: Mocha.Context): Promise { this.timeout(120 * 1000); await vscode.commands.executeCommand('appService.Refresh'); // activate the extension before tests begin + 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 diff --git a/test/nightly/azureResourceWebAppActions.test.ts b/test/nightly/azureResourceWebAppActions.test.ts index 5940ac46..bf94b97a 100644 --- a/test/nightly/azureResourceWebAppActions.test.ts +++ b/test/nightly/azureResourceWebAppActions.test.ts @@ -9,11 +9,14 @@ import { runWithTestActionContext } from '@microsoft/vscode-azext-dev'; import * as assert from 'assert'; import { DialogResponses, addAppSetting, constants, createWebAppAdvanced, deleteAppSetting, deleteWebApp, editScmType, getRandomHexString } from '../../extension.bundle'; import { longRunningTestsEnabled } from '../global.test'; -import { getRotatingLocation, getRotatingPricingTier } from './getRotatingValue'; -import { resourceGroupsToDelete, webSiteClient } from './global.resource.test'; +import { getRotatingPricingTier } from './getRotatingValue'; +import { resourceGroupsToDelete, webSiteClient } from './global.nightly.test'; -suite('Web App actions', function (this: Mocha.Suite): void { +const azcodeResourcePrefix: string = 'azc-app'; + +suite.only('Web App actions', function (this: Mocha.Suite): void { this.timeout(6 * 60 * 1000); + let resourceName: string; const WebsiteOS0: WebsiteOS = (new Date().getDate()) % 2 === 0 ? WebsiteOS.linux : WebsiteOS.windows; const WebsiteOS1: WebsiteOS = WebsiteOS0 === WebsiteOS.windows ? WebsiteOS.linux : WebsiteOS.windows; @@ -22,12 +25,12 @@ suite('Web App actions', function (this: Mocha.Suite): void { if (!longRunningTestsEnabled) { this.skip(); } - resourceName = getRandomHexString(); + resourceName = azcodeResourcePrefix + getRandomHexString(6); }); test(`Create New ${WebsiteOS0} Web App (Advanced)`, async () => { - const testInputs: (string | RegExp)[] = [resourceName, '$(plus) Create new resource group', resourceName, ...getInput(WebsiteOS0), getRotatingLocation(), '$(plus) Create new App Service plan', resourceName, getRotatingPricingTier(), '$(plus) Create new Application Insights resource', resourceName]; - resourceGroupsToDelete.push(resourceName); + const testInputs: (string | RegExp)[] = [resourceName, '$(plus) Create new resource group', resourceName, ...getInput(WebsiteOS0), 'East US', '$(plus) Create new App Service plan', resourceName, getRotatingPricingTier(), 'Disabled', '$(plus) Create new Application Insights resource', resourceName]; + resourceGroupsToDelete.add(resourceName); await runWithTestActionContext('CreateWebAppAdvanced', async context => { await context.ui.runWithInputs(testInputs, async () => { await createWebAppAdvanced(context); @@ -38,12 +41,12 @@ suite('Web App actions', function (this: Mocha.Suite): void { }); test(`Create New ${WebsiteOS1} Web App (Advanced)`, async () => { - const resourceGroupName: string = getRandomHexString(); - const webAppName: string = getRandomHexString(); - const appServicePlanName: string = getRandomHexString(); - const applicationInsightsName: string = getRandomHexString(); - resourceGroupsToDelete.push(resourceGroupName); - const testInputs: (string | RegExp)[] = [webAppName, '$(plus) Create new resource group', resourceGroupName, ...getInput(WebsiteOS1), getRotatingLocation(), '$(plus) Create new App Service plan', appServicePlanName, getRotatingPricingTier(), '$(plus) Create new Application Insights resource', applicationInsightsName]; + const resourceGroupName: string = azcodeResourcePrefix + getRandomHexString(6); + const webAppName: string = azcodeResourcePrefix + getRandomHexString(6); + const appServicePlanName: string = azcodeResourcePrefix + getRandomHexString(6); + const applicationInsightsName: string = azcodeResourcePrefix + getRandomHexString(6); + resourceGroupsToDelete.add(resourceGroupName); + const testInputs: (string | RegExp)[] = [webAppName, '$(plus) Create new resource group', resourceGroupName, ...getInput(WebsiteOS1), 'West US', '$(plus) Create new App Service plan', appServicePlanName, getRotatingPricingTier(), '$(plus) Create new Application Insights resource', applicationInsightsName]; await runWithTestActionContext('CreateWebAppAdvanced', async context => { await context.ui.runWithInputs(testInputs, async () => { await createWebAppAdvanced(context); diff --git a/test/nightly/deploy.test.ts b/test/nightly/deploy.test.ts index 20db9e28..e491ec1f 100644 --- a/test/nightly/deploy.test.ts +++ b/test/nightly/deploy.test.ts @@ -15,7 +15,7 @@ import * as vscode from 'vscode'; import { createGenericClient, createWebAppAdvanced, deploy, ext, getRandomHexString, nonNullProp, type SiteTreeItem } from '../../extension.bundle'; import { longRunningTestsEnabled } from '../global.test'; import { getRotatingLocation, getRotatingPricingTier } from './getRotatingValue'; -import { resourceGroupsToDelete, webSiteClient } from './global.resource.test'; +import { resourceGroupsToDelete, webSiteClient } from './global.nightly.test'; interface ITestCase { /** @@ -123,7 +123,7 @@ suite('Create Web App and deploy', function (this: Mocha.Suite): void { async function testCreateWebAppAndDeploy(os: string, promptForOs: boolean, runtime: string, workspacePath: string, expectedVersion: string, zipFile?: string): Promise { const resourceName: string = getRandomHexString(); const resourceGroupName = getRandomHexString(); - resourceGroupsToDelete.push(resourceGroupName); + resourceGroupsToDelete.add(resourceGroupName); const testInputs: (string | RegExp)[] = [resourceName, '$(plus) Create new resource group', resourceGroupName, runtime]; if (promptForOs) { diff --git a/test/nightly/global.nightly.test.ts b/test/nightly/global.nightly.test.ts new file mode 100644 index 00000000..e3c975e9 --- /dev/null +++ b/test/nightly/global.nightly.test.ts @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE.md in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { type WebSiteManagementClient } from '@azure/arm-appservice'; +import { ResourceManagementClient } from '@azure/arm-resources'; +import { createAzureClient } from '@microsoft/vscode-azext-azureutils'; +import { createTestActionContext, type TestActionContext } from '@microsoft/vscode-azext-dev'; +import { type AzureSubscription } from '@microsoft/vscode-azureresources-api'; +import * as vscode from 'vscode'; +import { createSubscriptionContext, createWebSiteClient, ext, subscriptionExperience, type ISubscriptionContext } from '../../extension.bundle'; +import { longRunningTestsEnabled } from '../global.test'; + +export let subscriptionContext: ISubscriptionContext; +export let webSiteClient: WebSiteManagementClient; +export const resourceGroupsToDelete = new Set(); + +suiteSetup(async function (this: Mocha.Context): Promise { + if (!longRunningTestsEnabled) { + 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.rgApi.appResourceTree); + subscriptionContext = createSubscriptionContext(subscription); + + webSiteClient = await createWebSiteClient([context, subscriptionContext]); +}); + +suiteTeardown(async function (this: Mocha.Context): Promise { + if (!longRunningTestsEnabled) { + return; + } + + this.timeout(10 * 60 * 1000); + await deleteResourceGroups(); +}); + +async function deleteResourceGroups(): Promise { + const context: TestActionContext = await createTestActionContext(); + const rgClient: ResourceManagementClient = createAzureClient([context, subscriptionContext], ResourceManagementClient); + + await Promise.allSettled(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}".`); + })); +} diff --git a/test/nightly/global.resource.test.ts b/test/nightly/global.resource.test.ts deleted file mode 100644 index 45f9b6ec..00000000 --- a/test/nightly/global.resource.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See LICENSE.md in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { type WebSiteManagementClient } from '@azure/arm-appservice'; -import { createTestActionContext, TestAzureAccount } from '@microsoft/vscode-azext-dev'; -import * as vscode from 'vscode'; -import { AzureAccountTreeItem, createWebSiteClient, ext, type ISubscriptionContext } from '../../extension.bundle'; -import { longRunningTestsEnabled } from '../global.test'; - -export let testAccount: TestAzureAccount; -export let webSiteClient: WebSiteManagementClient; -export const resourceGroupsToDelete: string[] = []; - -suiteSetup(async function (this: Mocha.Context): Promise { - this.skip(); - if (longRunningTestsEnabled) { - this.timeout(2 * 60 * 1000); - testAccount = new TestAzureAccount(vscode); - await testAccount.signIn(); - ext.azureAccountTreeItem = new AzureAccountTreeItem(testAccount); - webSiteClient = await createWebSiteClient([await createTestActionContext(), testAccount.getSubscriptionContext()]); - } -}); - -suiteTeardown(async function (this: Mocha.Context): Promise { - if (longRunningTestsEnabled) { - this.timeout(10 * 60 * 1000); - // await Promise.all(resourceGroupsToDelete.map(async resource => { - // await beginDeleteResourceGroup(resource); - // })); - // ext.azureAccountTreeItem.dispose(); - } -});