diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index ba79c9b3d64..68a8d64ec85 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -57,6 +57,7 @@ dependencies: '@rush-temp/perf-ai-form-recognizer': file:projects/perf-ai-form-recognizer.tgz '@rush-temp/perf-ai-metrics-advisor': file:projects/perf-ai-metrics-advisor.tgz '@rush-temp/perf-ai-text-analytics': file:projects/perf-ai-text-analytics.tgz + '@rush-temp/perf-app-configuration': file:projects/perf-app-configuration.tgz '@rush-temp/perf-core-rest-pipeline': file:projects/perf-core-rest-pipeline.tgz '@rush-temp/perf-eventgrid': file:projects/perf-eventgrid.tgz '@rush-temp/perf-identity': file:projects/perf-identity.tgz @@ -10577,6 +10578,21 @@ packages: integrity: sha512-Kvl28eIyB/TUFjHazX20V+clKd8zLCBx+Tb7zTU3Yp1kei9JNZfqMaDmDlCyfw1bmRLDslq5/xfo/NEMWks0wQ== tarball: file:projects/perf-ai-text-analytics.tgz version: 0.0.0 + file:projects/perf-app-configuration.tgz: + dependencies: + '@types/node': 8.10.66 + '@types/uuid': 8.3.0 + dotenv: 8.6.0 + ts-node: 9.1.1_typescript@4.2.4 + tslib: 2.3.0 + typescript: 4.2.4 + uuid: 8.3.2 + dev: false + name: '@rush-temp/perf-app-configuration' + resolution: + integrity: sha512-i2b4+TTev+rOwl+F2AqZoAyVcrP7/qP4IkOI9KeSEWSjbizV7wKmvzpENQylboaW5EJoe7XqxGIUDLxuDxWVWQ== + tarball: file:projects/perf-app-configuration.tgz + version: 0.0.0 file:projects/perf-core-rest-pipeline.tgz: dependencies: '@types/uuid': 8.3.0 @@ -11947,6 +11963,7 @@ specifiers: '@rush-temp/perf-ai-form-recognizer': file:./projects/perf-ai-form-recognizer.tgz '@rush-temp/perf-ai-metrics-advisor': file:./projects/perf-ai-metrics-advisor.tgz '@rush-temp/perf-ai-text-analytics': file:./projects/perf-ai-text-analytics.tgz + '@rush-temp/perf-app-configuration': file:./projects/perf-app-configuration.tgz '@rush-temp/perf-core-rest-pipeline': file:./projects/perf-core-rest-pipeline.tgz '@rush-temp/perf-eventgrid': file:./projects/perf-eventgrid.tgz '@rush-temp/perf-identity': file:./projects/perf-identity.tgz diff --git a/rush.json b/rush.json index 6335ae217f2..c8b941b088e 100644 --- a/rush.json +++ b/rush.json @@ -784,6 +784,11 @@ "packageName": "@azure-tests/perf-core-rest-pipeline", "projectFolder": "sdk/core/perf-tests/core-rest-pipeline", "versionPolicyName": "test" + }, + { + "packageName": "@azure-tests/perf-app-configuration", + "projectFolder": "sdk/appconfiguration/perf-tests/app-configuration", + "versionPolicyName": "test" } ] } diff --git a/sdk/appconfiguration/perf-tests/app-configuration/README.md b/sdk/appconfiguration/perf-tests/app-configuration/README.md new file mode 100644 index 00000000000..0ba79a26d65 --- /dev/null +++ b/sdk/appconfiguration/perf-tests/app-configuration/README.md @@ -0,0 +1,9 @@ +### Guide + +1. Build the app-config perf tests package `rush build -t perf-app-configuration`. +2. Copy the `sample.env` file and name it as `.env`. +3. Create a App Configuration resource and populate the `.env` file with `APPCONFIG_CONNECTION_STRING` variable. +4. Run the tests as follows + + - list configuration settings + - `npm run perf-test:node -- ListSettingsTest --warmup 2 --duration 7 --iterations 2 --parallel 2` diff --git a/sdk/appconfiguration/perf-tests/app-configuration/package.json b/sdk/appconfiguration/perf-tests/app-configuration/package.json new file mode 100644 index 00000000000..d0dfc313472 --- /dev/null +++ b/sdk/appconfiguration/perf-tests/app-configuration/package.json @@ -0,0 +1,47 @@ +{ + "name": "@azure-tests/perf-app-configuration", + "version": "1.0.0", + "description": "", + "main": "", + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@azure/app-configuration": "^1.2.0-beta.2", + "@azure/core-http": "^2.0.0", + "@azure/test-utils-perfstress": "^1.0.0", + "dotenv": "^8.2.0" + }, + "devDependencies": { + "@types/uuid": "^8.0.0", + "@types/node": "^8.0.0", + "uuid": "^8.3.0", + "tslib": "^2.2.0", + "ts-node": "^9.0.0", + "typescript": "~4.2.0" + }, + "private": true, + "scripts": { + "perf-test:node": "ts-node test/index.spec.ts", + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build": "tsc -p .", + "build:samples": "echo skipped", + "build:test": "echo skipped", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf dist dist-esm test-dist typings *.tgz *.log", + "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "echo skipped", + "lint:fix": "eslint package.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json src test --ext .ts -f html -o app-config-perf-test-lintReport.html || exit 0", + "pack": "npm pack 2>&1", + "prebuild": "npm run clean", + "unit-test:browser": "echo skipped", + "unit-test:node": "echo skipped", + "unit-test": "echo skipped", + "test:browser": "echo skipped", + "test:node": "echo skipped", + "test": "echo skipped" + } +} diff --git a/sdk/appconfiguration/perf-tests/app-configuration/sample.env b/sdk/appconfiguration/perf-tests/app-configuration/sample.env new file mode 100644 index 00000000000..db027248c47 --- /dev/null +++ b/sdk/appconfiguration/perf-tests/app-configuration/sample.env @@ -0,0 +1,3 @@ +# This is the connection string for your app-configuration resource +# You can get this from the Azure portal. +APPCONFIG_CONNECTION_STRING= diff --git a/sdk/appconfiguration/perf-tests/app-configuration/test/appConfigBase.spec.ts b/sdk/appconfiguration/perf-tests/app-configuration/test/appConfigBase.spec.ts new file mode 100644 index 00000000000..cf6eaa5b22b --- /dev/null +++ b/sdk/appconfiguration/perf-tests/app-configuration/test/appConfigBase.spec.ts @@ -0,0 +1,15 @@ +import { PerfStressTest, getEnvVar } from "@azure/test-utils-perfstress"; +import { AppConfigurationClient } from "@azure/app-configuration"; +// Expects the .env file at the same level +import * as dotenv from "dotenv"; +dotenv.config(); + +export abstract class AppConfigTest extends PerfStressTest { + client: AppConfigurationClient; + + constructor() { + super(); + const connectionString = getEnvVar("APPCONFIG_CONNECTION_STRING"); + this.client = new AppConfigurationClient(connectionString); + } +} diff --git a/sdk/appconfiguration/perf-tests/app-configuration/test/index.spec.ts b/sdk/appconfiguration/perf-tests/app-configuration/test/index.spec.ts new file mode 100644 index 00000000000..9ba6ac840be --- /dev/null +++ b/sdk/appconfiguration/perf-tests/app-configuration/test/index.spec.ts @@ -0,0 +1,8 @@ +import { PerfStressProgram, selectPerfStressTest } from "@azure/test-utils-perfstress"; +import { ListSettingsTest } from "./listSettings.spec"; + +console.log("=== Starting the perfStress test ==="); + +const perfStressProgram = new PerfStressProgram(selectPerfStressTest([ListSettingsTest])); + +perfStressProgram.run(); diff --git a/sdk/appconfiguration/perf-tests/app-configuration/test/listSettings.spec.ts b/sdk/appconfiguration/perf-tests/app-configuration/test/listSettings.spec.ts new file mode 100644 index 00000000000..5f7910d81d4 --- /dev/null +++ b/sdk/appconfiguration/perf-tests/app-configuration/test/listSettings.spec.ts @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { generateUuid } from "@azure/core-http"; +import { PerfStressOptionDictionary, executeParallel } from "@azure/test-utils-perfstress"; +import { AppConfigTest } from "./appConfigBase.spec"; + +interface ListTestOptions { + /** + * Number of settings to be created/listed in the test + */ + count: number; +} + +export class ListSettingsTest extends AppConfigTest { + static prefix = generateUuid(); + public options: PerfStressOptionDictionary = { + count: { + required: true, + description: "Number of settings to be listed", + longName: "count", + defaultValue: 10 + } + }; + + public async globalSetup() { + await executeParallel( + async (_count: number, _index: number) => { + await this.client.addConfigurationSetting({ + key: ListSettingsTest.prefix + generateUuid(), + value: "random" + }); + }, + this.parsedOptions.count.value!, + 32 + ); + } + + async runAsync(): Promise { + for await (const response of this.client + .listConfigurationSettings({ keyFilter: ListSettingsTest.prefix + "*" }) + .byPage()) { + for (const _ of response.items) { + } + } + } + + public async globalCleanup() { + const keys: string[] = []; + for await (const response of this.client + .listConfigurationSettings({ keyFilter: ListSettingsTest.prefix + "*" }) + .byPage()) { + for (const setting of response.items) { + keys.push(setting.key); + } + } + await executeParallel( + async (count: number, _: number) => { + await this.client.deleteConfigurationSetting({ key: keys[count] }); + }, + this.parsedOptions.count.value!, + 32 + ); + } +} diff --git a/sdk/appconfiguration/perf-tests/app-configuration/tsconfig.json b/sdk/appconfiguration/perf-tests/app-configuration/tsconfig.json new file mode 100644 index 00000000000..3e6fb394a93 --- /dev/null +++ b/sdk/appconfiguration/perf-tests/app-configuration/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../../tsconfig.package", + "compilerOptions": { + "module": "CommonJS", + "declarationDir": "./typings/latest", + "lib": [ + "ES6", + "ESNext.AsyncIterable" + ], + "noEmit": true + }, + "compileOnSave": true, + "include": [ + "./test/**/*.ts" + ] +}