Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into get_testserver_working

* 'main' of https://github.com/Azure/azure-sdk-for-python: (45 commits)
  ignore coretestserver readme (Azure#19436)
  Add Ubuntu 20 to local dns bypass template (Azure#19432)
  Sync eng/common directory with azure-sdk-tools for PR 1729 (Azure#19415)
  Async/BearerTokenCredentialPolicy consistently calls on_exception (Azure#19195)
  [EventHubs] Fix bug in sending stress test code and update default stress test settings (Azure#19429)
  [EventHubs] Get IoT Hub Name from Redirect Address in sample (Azure#19314)
  [textanalytics] regen on v3.1 (Azure#19193)
  Adapt EG to arm template (Azure#19262)
  [Key Vault] Extend pipeline test timeout (Azure#19404)
  Update platform matrix to ubuntu 20 (Azure#19296)
  [AppConfig] Add lock to SyncTokenPolicy (Azure#19395)
  Regenerate monitor code (Azure#19375)
  Increment version for keyvault releases (Azure#19402)
  Aggregation should be a list (Azure#19381)
  [azure-mgmt-monitor] skip test to unblock ci (Azure#19390)
  Cloud event should parse smaller ms precisions (Azure#19259)
  Update release date (Azure#19399)
  [Communication]: use x-ms-date for hmac (Azure#19396)
  [Key Vault] Performance tests for certificates, keys, and secrets (Azure#19002)
  Deprecate azure-monitor (Azure#19384)
  ...
  • Loading branch information
iscai-msft committed Jun 24, 2021
2 parents 1483f8c + e1c0bc4 commit 4cbf6a8
Show file tree
Hide file tree
Showing 1,427 changed files with 74,971 additions and 44,341 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ build/
TestResults/
ENV_DIR/

# Perf test profiling
cProfile-*.pstats

# tox generated artifacts
test-junit-*.xml
pylint-*.out.txt
Expand Down
35 changes: 29 additions & 6 deletions doc/dev/perfstress_tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
1. [The perfstress framework](#the-perfstress-framework)
- [The PerfStressTest base](#the-perfstresstest-base)
- [Default command options](#default-command-options)
- [Running with test proxy](#running-with-test-proxy)
2. [Adding performance tests to an SDK](#adding-performance-tests-to-an-sdk)
- [Writing a test](#writing-a-test)
- [Adding legacy T1 tests](#adding-legacy-t1-tests)
Expand Down Expand Up @@ -38,6 +39,16 @@ class PerfStressTest:
async def global_cleanup(self):
# Can be optionally defined. Only run once, regardless of parallelism.

async def record_and_start_playback(self):
# Set up the recording on the test proxy, and configure the proxy in playback mode.
# This function is only run if a test proxy URL is provided (-x).
# There should be no need to overwrite this function.

async def stop_playback(self):
# Configure the proxy out of playback mode and discard the recording.
# This function is only run if a test proxy URL is provided (-x).
# There should be no need to overwrite this function.

async def setup(self):
# Can be optionally defined. Run once per test instance, after global_setup.

Expand Down Expand Up @@ -65,12 +76,24 @@ class PerfStressTest:
```
## Default command options
The framework has a series of common command line options built in:
- `--duration=10` Number of seconds to run as many operations (the "run" function) as possible. Default is 10.
- `--iterations=1` Number of test iterations to run. Default is 1.
- `--parallel=1` Number of tests to run in parallel. Default is 1.
- `--warm-up=5` Number of seconds to spend warming up the connection before measuring begins. Default is 5.
- `-d --duration=10` Number of seconds to run as many operations (the "run" function) as possible. Default is 10.
- `-i --iterations=1` Number of test iterations to run. Default is 1.
- `-p --parallel=1` Number of tests to run in parallel. Default is 1.
- `-w --warm-up=5` Number of seconds to spend warming up the connection before measuring begins. Default is 5.
- `--sync` Whether to run the tests in sync or async. Default is False (async).
- `--no-cleanup` Whether to keep newly created resources after test run. Default is False (resources will be deleted).
- `-x --test-proxy` Whether to run the tests against the test proxy server. Specfiy the URL for the proxy endpoint (e.g. "https://localhost:5001").
- `--profile` Whether to run the perftest with cProfile. If enabled (default is False), the output file of the **last completed single iteration** will be written to the current working directory in the format `"cProfile-<TestClassName>-<TestID>-<sync/async>.pstats"`.


## Running with the test proxy
Follow the instructions here to install and run the test proxy server:
https://github.com/Azure/azure-sdk-tools/tree/feature/http-recording-server/tools/test-proxy/Azure.Sdk.Tools.TestProxy

Once running, in a separate process run the perf test in question, combined with the `-x` flag to specify the proxy endpoint.
```cmd
(env) ~/azure-storage-blob/tests> perfstress DownloadTest -x "https://localhost:5001"
```

# Adding performance tests to an SDK
The performance tests will be in a submodule called `perfstress_tests` within the `tests` directory in an SDK project.
Expand Down Expand Up @@ -351,5 +374,5 @@ Using the `perfstress` command alone will list the available perf tests found. N

Please add a `README.md` to the perfstress_tests directory so that others know how to setup and run the perf tests, along with a description of the available tests and any support command line options. README files in a `tests/perfstress_tests` directory should already be filtered from CI validation for SDK readmes.
Some examples can be found here:
- [Azure Storage Blob](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/storage/azure-storage-blob/tests/perfstress_tests/README.md)
- [Azure Service Bus](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/servicebus/azure-servicebus/tests/perf_tests/README.md)
- [Azure Storage Blob](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/storage/azure-storage-blob/tests/perfstress_tests/README.md)
- [Azure Service Bus](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/servicebus/azure-servicebus/tests/perf_tests/README.md)
2 changes: 2 additions & 0 deletions eng/.docsettings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ known_content_issues:
- ['sdk/storage/README.md', '#4554']
- ['sdk/textanalytics/azure-ai-textanalytics/samples/README.md', '#4554']
- ['sdk/monitor/azure-monitor-opentelemetry-exporter/README.md', '#4554']
- ['sdk/monitor/azure-monitor/README.md', '#4554']
- ['sdk/digitaltwins/azure-digitaltwins-core/swagger/README.md', '#4554']
- ['sdk/textanalytics/azure-ai-textanalytics/swagger/README.md', '#4554']
- ['sdk/translation/azure-ai-translation-document/swagger/README.md', '#4554']
Expand Down Expand Up @@ -138,6 +139,7 @@ known_content_issues:
- ['sdk/digitaltwins/azure-digitaltwins-core/swagger/README.md', '#4554']
- ['sdk/textanalytics/azure-ai-textanalytics/swagger/README.md', '#4554']
- ['sdk/appconfiguration/azure-appconfiguration/swagger/README.md', '#4554']
- ['sdk/core/azure-core/tests/testserver_tests/coretestserver/README.md', '#4554']
package_indexing_exclusion_list:
- 'azure-sdk-tools'
- 'azure-template'
2 changes: 1 addition & 1 deletion eng/common/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Common Engineering System

Updates under this directory should only be made in the `azure-sdk-tools` repo as any changes under this directory outside of that repo will end up getting overwritten with future updates. For information about making updates see [common engineering system docs](https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md)
Updates under this directory should only be made in the `azure-sdk-tools` repo as any changes under this directory outside of that repo will end up getting overwritten with future updates. For information about making updates see [common engineering system docs](https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md)
2 changes: 1 addition & 1 deletion eng/common/docgeneration/Generate-DocIndex.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,5 @@ else
{
LogWarning "The function for 'GetGithubIoDocIndexFn' was not found.`
Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.`
See https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md#code-structure"
See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
}
4 changes: 3 additions & 1 deletion eng/common/pipelines/templates/steps/bypass-local-dns.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ steps:
succeededOrFailed(),
or(
eq(variables['OSVmImage'], 'ubuntu-18.04'),
eq(variables['OSVmImage'], 'MMSUbuntu18.04')
eq(variables['OSVmImage'], 'ubuntu-20.04'),
eq(variables['OSVmImage'], 'MMSUbuntu18.04'),
eq(variables['OSVmImage'], 'MMSUbuntu20.04')
),
eq(variables['Container'], '')
)
2 changes: 1 addition & 1 deletion eng/common/pipelines/templates/steps/check-spelling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# and some ref (branch, tag, etc.) or commit hash. Only runs on PRs.
# ContinueOnError - true: Pipeline warns on spelling error
# false: Pipeline fails on spelling error
# TargetBranch - Target ref (e.g. master) to compare to create file change
# TargetBranch - Target ref (e.g. main) to compare to create file change
# list.
# CspellConfigPath - Path to cspell.json config location

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ parameters:
default: ''
- name: PRBranchName
type: string
default: 'master-rdme'
default: 'main-rdme'
- name: PRLabels
type: string
default: 'auto-merge'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ steps:
if (($LASTEXITCODE -eq 0) -and ($filesInCommonDir.Count -gt 0))
{
Write-Host "##vso[task.LogIssue type=error;]Changes to files under 'eng/common' directory should not be made in this Repo`n${filesInCommonDir}"
Write-Host "##vso[task.LogIssue type=error;]Please follow workflow at https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md"
Write-Host "##vso[task.LogIssue type=error;]Please follow workflow at https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md"
exit 1
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ steps:
- script: >
dotnet tool install
Azure.Sdk.Tools.PipelineGenerator
--version 1.0.2-dev.20210309.1
--version 1.0.2-dev.20210621.4
--add-source https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk/nuget/v3/index.json
--tool-path ${{parameters.ToolPath}}
workingDirectory: $(Pipeline.Workspace)/pipeline-generator
Expand Down
4 changes: 2 additions & 2 deletions eng/common/pipelines/templates/steps/set-default-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ steps:
- pwsh: |
$setDefaultBranch = (git remote show ${{ parameters.RemoteRepo }} | Out-String) -replace "(?ms).*HEAD branch: (\w+).*", '$1'
if ($LASTEXITCODE -ne 0) {
Write-Host "Not able to fetch the default branch from git command. Set to master."
$setDefaultBranch = 'master'
Write-Host "Not able to fetch the default branch from git command. Set to main."
$setDefaultBranch = 'main'
}
Write-Host "Setting DefaultBranch=$setDefaultBranch"
Write-Host "##vso[task.setvariable variable=DefaultBranch]$setDefaultBranch"
Expand Down
8 changes: 6 additions & 2 deletions eng/common/scripts/Create-APIReview.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ else
{
Write-Host "The function for 'FindArtifactForApiReviewFn' was not found.`
Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.`
See https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md#code-structure"
See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
exit(1)
}

Expand Down Expand Up @@ -104,7 +104,7 @@ if ($packages)
Write-Host "Version: $($version)"
Write-Host "SDK Type: $($pkgInfo.SdkType)"

# Run create review step only if build is triggered from master branch or if version is GA.
# Run create review step only if build is triggered from main branch or if version is GA.
# This is to avoid invalidating review status by a build triggered from feature branch
if ( ($SourceBranch -eq $DefaultBranch) -or (-not $version.IsPrerelease))
{
Expand All @@ -121,6 +121,10 @@ if ($packages)
# Ignore API review status for prerelease version
Write-Host "Package version is not GA. Ignoring API view approval status"
}
elseif (!$pkgInfo.ReleaseStatus -or $pkgInfo.ReleaseStatus -eq "Unreleased")
{
Write-Host "Release date is not set for current version in change log file for package. Ignoring API review approval status since package is not yet ready for release."
}
else
{
# Return error code if status code is 201 for new data plane package
Expand Down
11 changes: 9 additions & 2 deletions eng/common/scripts/Package-Properties.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class PackageProps
[string]$SdkType
[boolean]$IsNewSdk
[string]$ArtifactName
[string]$ReleaseStatus

PackageProps([string]$name, [string]$version, [string]$directoryPath, [string]$serviceDirectory)
{
Expand Down Expand Up @@ -48,6 +49,12 @@ class PackageProps
if (Test-Path (Join-Path $directoryPath "CHANGELOG.md"))
{
$this.ChangeLogPath = Join-Path $directoryPath "CHANGELOG.md"
# Get release date for current version and set in package property
$changeLogEntry = Get-ChangeLogEntry -ChangeLogLocation $this.ChangeLogPath -VersionString $this.Version
if ($changeLogEntry -and !$changeLogEntry.ReleaseStatus)
{
$this.ReleaseStatus = $changeLogEntry.ReleaseStatus.Trim().Trim("()")
}
}
else
{
Expand Down Expand Up @@ -126,7 +133,7 @@ function Get-AllPkgProperties ([string]$ServiceDirectory = $null)
return $pkgPropsResult
}

# Given the metadata url under https://github.com/Azure/azure-sdk/tree/master/_data/releases/latest,
# Given the metadata url under https://github.com/Azure/azure-sdk/tree/main/_data/releases/latest,
# the function will return the csv metadata back as part of response.
function Get-CSVMetadata ([string]$MetadataUri=$MetadataUri)
{
Expand All @@ -143,7 +150,7 @@ function Get-PkgPropsForEntireService ($serviceDirectoryPath)
{
LogError "The function for '$GetPackageInfoFromRepoFn' was not found.`
Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.`
See https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md#code-structure"
See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
}

foreach ($directory in (Get-ChildItem $serviceDirectoryPath -Directory))
Expand Down
2 changes: 1 addition & 1 deletion eng/common/scripts/Prepare-Release.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ else
{
LogError "The function 'SetPackageVersion' was not found.`
Make sure it is present in eng/scripts/Language-Settings.ps1.`
See https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md#code-structure"
See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
exit 1
}

Expand Down
1 change: 1 addition & 0 deletions eng/common/scripts/Save-Package-Properties.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ if ($allPackageProperties)
Write-Host "Package Version: $($pkg.Version)"
Write-Host "Package SDK Type: $($pkg.SdkType)"
Write-Host "Artifact Name: $($pkg.ArtifactName)"
Write-Host "Release date: $($pkg.ReleaseStatus)"
$configFilePrefix = $pkg.Name
if ($pkg.ArtifactName)
{
Expand Down
2 changes: 1 addition & 1 deletion eng/common/scripts/Update-DocsMsPackages.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ if ($UpdateDocsMsPackagesFn -and (Test-Path "Function:$UpdateDocsMsPackagesFn"))
} else {
LogError "The function for '$UpdateFn' was not found.`
Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.`
See https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md#code-structure"
See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
exit 1
}
2 changes: 1 addition & 1 deletion eng/common/scripts/artifact-metadata-parsing.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function RetrievePackages($artifactLocation) {
{
LogError "The function for '$GetPackageInfoFromPackageFileFn' was not found.`
Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.`
See https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md#code-structure"
See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
}
}

Expand Down
2 changes: 1 addition & 1 deletion eng/common/scripts/copy-docs-to-blobstorage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,6 @@ else
{
LogWarning "The function for '$PublishGithubIODocsFn' was not found.`
Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.`
See https://github.com/Azure/azure-sdk-tools/blob/master/doc/common/common_engsys.md#code-structure"
See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
}

2 changes: 1 addition & 1 deletion eng/common/scripts/update-docs-metadata.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ param (

. (Join-Path $PSScriptRoot common.ps1)

$releaseReplaceRegex = "(https://github.com/$RepoId/(?:blob|tree)/)master"
$releaseReplaceRegex = "(https://github.com/$RepoId/(?:blob|tree)/)main"

function GetMetaData {
if (Test-Path Variable:MetadataUri) {
Expand Down
4 changes: 2 additions & 2 deletions eng/pipelines/templates/jobs/smoke.tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
- job: smoke_test_eligibility
displayName: Check Smoke Test Eligibility
pool:
name: "azsdk-pool-mms-ubuntu-1804-general"
vmImage: "MMSUbuntu18.04"
name: "azsdk-pool-mms-ubuntu-2004-general"
vmImage: "MMSUbuntu20.04"
steps:
- ${{ each artifact in parameters.Artifacts }}:
- ${{ if and(ne(variables['Skip.Release'], 'true'), ne(artifact.skipPublishPackage, 'true')) }}:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"matrix": {
"Agent": {
"ubuntu-18.04": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" },
"ubuntu-20.04": { "OSVmImage": "MMSUbuntu20.04", "Pool": "azsdk-pool-mms-ubuntu-2004-general" },
"windows-2019": { "OSVmImage": "MMS2019", "Pool": "azsdk-pool-mms-win-2019-general" }
},
"PythonVersion": [ "3.6", "3.8", "3.9" ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
},
"matrix": {
"Agent": {
"ubuntu-18.04": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" }
"ubuntu-20.04": { "OSVmImage": "MMSUbuntu20.04", "Pool": "azsdk-pool-mms-ubuntu-2004-general" }
},
"PythonVersion": [ "pypy3", "3.6", "3.7", "3.8", "3.9" ],
"CoverageArg": "--disablecov"
Expand Down
8 changes: 4 additions & 4 deletions eng/pipelines/templates/stages/platform-matrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"matrix": {
"Agent": {
"ubuntu-18.04": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" },
"ubuntu-20.04": { "OSVmImage": "MMSUbuntu20.04", "Pool": "azsdk-pool-mms-ubuntu-2004-general" },
"windows-2019": { "OSVmImage": "MMS2019", "Pool": "azsdk-pool-mms-win-2019-general" },
"macOS-10.15": { "OSVmImage": "macOS-10.15", "Pool": "Azure Pipelines" }
},
Expand All @@ -17,9 +17,9 @@
"include": [
{
"CoverageConfig": {
"ubuntu1804_39_coverage": {
"OSVmImage": "MMSUbuntu18.04",
"Pool": "azsdk-pool-mms-ubuntu-1804-general",
"ubuntu2004_39_coverage": {
"OSVmImage": "MMSUbuntu20.04",
"Pool": "azsdk-pool-mms-ubuntu-2004-general",
"PythonVersion": "3.9",
"CoverageArg": "",
"TestSamples": "false"
Expand Down
2 changes: 1 addition & 1 deletion scripts/auto_release/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,4 +417,4 @@ def main():
my_print(e)
else:
with open(f'{OUT_PATH}/output.txt', 'w') as file_out:
file_out.writelines([f'{NEW_BRANCH}\n', "master" if TRACK == '2' else 'release/v3'])
file_out.writelines([f'{NEW_BRANCH}\n', "main" if TRACK == '2' else 'release/v3'])
1 change: 1 addition & 0 deletions scripts/devops_tasks/common_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"azure",
"azure-mgmt",
"azure-storage",
"azure-monitor",
"azure-mgmt-regionmove"
]
MANAGEMENT_PACKAGE_IDENTIFIERS = [
Expand Down
2 changes: 1 addition & 1 deletion scripts/devops_tasks/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
test_tools_req_file = os.path.abspath(os.path.join(root_dir, "eng", "test_tools.txt"))

GIT_REPO_NAME = "azure-sdk-for-python"
GIT_MASTER_BRANCH = "master"
GIT_MASTER_BRANCH = "main"
VENV_NAME = "regressionenv"
AZURE_SDK_FOR_PYTHON_GIT_URL = "https://github.com/Azure/azure-sdk-for-python.git"
TEMP_FOLDER_NAME = ".tmp_code_path"
Expand Down
Loading

0 comments on commit 4cbf6a8

Please sign in to comment.