Skip to content

Commit

Permalink
Merge branch 'main' into feature/ta-v3.2-preview.2
Browse files Browse the repository at this point in the history
  • Loading branch information
kristapratico committed Oct 6, 2021
2 parents fe65c42 + 5f9cad6 commit 971464e
Show file tree
Hide file tree
Showing 3,066 changed files with 512,875 additions and 430,254 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
6 changes: 4 additions & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Service team
####
# PRLabel: %Azure.Identity
/sdk/identity/ @chlowell @mccoyp @schaabs
/sdk/identity/ @chlowell @mccoyp @schaabs @xiangyan99

# PRLabel: %Event Hubs
/sdk/eventhub/ @annatisch @yunhaoling @swathipil @rakshith91
Expand All @@ -39,6 +39,8 @@

# PRLabel: %Communication
/sdk/communication/ @acsdevx-msft
/sdk/communication/azure-communication-phonenumbers/ @RoyHerrod @danielav7 @whisper6284 @AlonsoMondal
/sdk/communication/azure-communication-sms/ @RoyHerrod @arifibrahim4

# PRLabel: %KeyVault
/sdk/keyvault/ @schaabs @chlowell @mccoyp @YalinLi0312
Expand Down Expand Up @@ -101,7 +103,7 @@
/sdk/servicebus/ @annatisch @yunhaoling @swathipil @rakshith91

# PRLabel: %Synapse
/sdk/synapse/ @aim-for-better @idear1203
/sdk/synapse/ @wonner @idear1203 @xiangyan99

# PRLabel: %EngSys
/sdk/template/ @Azure/azure-sdk-eng
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

This repository is for active development of the Azure SDK for Python. For consumers of the SDK we recommend visiting our [public developer docs](https://docs.microsoft.com/python/azure/) or our versioned [developer docs](https://azure.github.io/azure-sdk-for-python).

## _Disclaimer_

_Azure SDK Python packages support for Python 2.7 is ending 01 January 2022. For more information and questions, please refer to https://github.com/Azure/azure-sdk-for-python/issues/20691_

## Getting started

For your convenience, each service has a separate set of libraries that you can choose to use instead of one, large Azure package. To get started with a specific library, see the `README.md` (or `README.rst`) file located in the library's project folder.
Expand Down
2 changes: 1 addition & 1 deletion doc/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Overview of the documents:
- [Developer Set-Up](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/dev_setup.md) : How to create a development environment for this repo
- [Release](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/release.md) : How to release a package when ready
- [Packaging](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/packaging.md) : How to organize packaging information for packages under `azure`
- [Testing](./tests.md): How to write unit and functional tests for a library
- [Testing](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/tests.md): How to write unit and functional tests for a library
- [Docstrings and Type hints](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/docstring_typehint.md): How to document an SDK for compatability with internal tools (API View) and our documentation at [MS Docs][ms_docs] and the [azure.github.io][azure_github_io] site.

The [mgmt](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/mgmt) folder contains information specific to management packages (i.e. packages prefixed by `azure-mgmt`)
Expand Down
2 changes: 1 addition & 1 deletion doc/dev/docstring_typehint.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ All public methods should have docstrings to document the parameters, keywords,

* [Docstrings](#docstrings)
* [Method Docstrings](#method_docstrings)
* [Model and Client Docstrings](#Model_and_Client_Docstrings)
* [Model and Client Docstrings](#model_and_client_docstrings)
* [Type Hints](#type_hints)
* [Type Hints for Python 2.7 and 3.5+](#type_hints_for_python_2.7_and_3.5+)
* [Type Hints for Python 3.5+](#type_hints_for_python_3.5+)
Expand Down
177 changes: 177 additions & 0 deletions doc/dev/test_proxy_migration_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Guide for migrating to the test proxy from vcrpy

This guide describes the changes that service SDKs should make to their test frameworks in order to take advantage of
the Azure SDK test proxy.

Documentation of the motivations and goals of the test proxy can be found [here][general_docs] in the azure-sdk-tools
GitHub repository, and documentation of how to set up and use the proxy can be found [here][detailed_docs].

## Update existing tests

### Current test structure

Test classes currently inherit from AzureTestCase, and test methods can optionally use decorators:

```py
from devtools_testutils import AzureTestCase

class TestExample(AzureTestCase):

def test_example(self):
...

@ExamplePreparer()
def test_example_with_preparer(self):
...
```

### New test structure

To use the proxy, test classes should inherit from AzureRecordedTestCase and recorded test methods should use a
RecordedByProxy decorator:

```py
from devtools_testutils import AzureRecordedTestCase, RecordedByProxy

class TestExample(AzureRecordedTestCase):

@RecordedByProxy
def test_example(self):
...

@ExamplePreparer()
@RecordedByProxy
def test_example_with_preparer(self):
...
```

For async tests, import the RecordedByProxyAsync decorator from `devtools_testutils.aio` and use it in the same
way as RecordedByProxy.

> **Note:** since AzureRecordedTestCase doesn't inherit from `unittest.TestCase`, test class names need to start
> with "Test" in order to be properly collected by pytest by default. For more information, please refer to
> [pytest's documentation][pytest_collection].
## Run the tests

### Perform one-time setup

The test proxy is made available for your tests via a Docker container. Some tests require an SSL connection to work, so
the Docker image used for the container has a certificate imported that you need to trust on your machine. Instructions
on how to do so can be found [here][proxy_cert_docs].

### Start the proxy server

There is a [PowerShell script][docker_start_proxy] in `eng/common/testproxy` that will fetch the proxy Docker image if
you don't already have it, and will start or stop a container running the image for you. You can run the following
command from the root of the `azure-sdk-for-python` directory to start the container whenever you want to make the test
proxy available for running tests:

```powershell
.\eng\common\testproxy\docker-start-proxy.ps1 "start"
```

Note that the proxy is available as long as the container is running. In other words, you don't need to start and
stop the container for each test run or between tests for different SDKs. You can run the above command in the morning
and just stop the container whenever you'd like. To stop the container, run the same command but with `"stop"` in place
of `"start"`. In the future, the proxy container will be set up and started automatically when tests are run, and
starting it manually will be optional.

For more details on proxy startup, please refer to the [proxy documentation][detailed_docs].

### Record or play back tests

Configuring live and playback tests is done with the `AZURE_TEST_RUN_LIVE` environment variable. When this variable is
set to "true" or "yes", live tests will run and produce recordings. When this variable is set to "false" or "no", or
not set at all, tests will run in playback mode and attempt to match existing recordings.

Recordings for a given package will end up in that package's `/tests/recordings` directory, just like they currently
do.

> **Note:** at this time, support for configuring live or playback tests with a `testsettings_local.cfg` file has been
> deprecated in favor of using just `AZURE_TEST_RUN_LIVE`.
### Register sanitizers

Since the test proxy doesn't use [`vcrpy`][vcrpy], tests don't use a scrubber to sanitize values in recordings.
Instead, sanitizers (as well as matchers and transforms) can be registered on the proxy as detailed in
[this][sanitizers] section of the proxy documentation. At the time of writing, sanitizers can be registered via the
`add_sanitizer` method in `devtools_testutils`.

Sanitizers, matchers, and transforms remain registered until the proxy container is stopped, so for any sanitizers that
are shared by different tests, using a session fixture declared in a `conftest.py` file is recommended. Please refer to
[pytest's scoped fixture documentation][pytest_fixtures] for more details.

For example, to sanitize URIs in recordings, you can set up a URI sanitizer for all tests in the pytest session by
adding something like the following in the package's `conftest.py` file:

```python
from devtools_testutils import add_sanitizer

# autouse=True will trigger this fixture on each pytest run, even if it's not explicitly used by a test method
@pytest.fixture(scope="session", autouse=True)
def sanitize_uris():
add_sanitizer(ProxyRecordingSanitizer.URI, value="fakeendpoint")
```

`add_sanitizer` accepts a sanitizer, matcher, or transform type from the ProxyRecordingSanitizer enum as a required
parameter. Keyword-only arguments can be provided to customize the sanitizer; for example, in the snippet above, any
request URIs that match the default URI regular expression will have their domain name replaced with "fakeendpoint". A
request made to `https://tableaccount.table.core.windows.net` will be recorded as being made to
`https://fakeendpoint.table.core.windows.net`.

## Implementation details

### What does the test proxy do?

The gist of the test proxy is that it stands in between your tests and the service. What this means is that test
requests which would usually go straight to the service should instead point to the locally-hosted test proxy.

For example, if an operation would typically make a GET request to
`https://fakeazsdktestaccount.table.core.windows.net/Tables`, that operation should now be sent to
`https://localhost:5001/Tables` instead. The original endpoint should be stored in an `x-recording-upstream-base-uri` --
the proxy will send the original request and record the result.

The RecordedByProxy and RecordedByProxyAsync decorators patch test requests to do this for you.

### How does the test proxy know when and what to record or play back?

This is achieved by making POST requests to the proxy server that say whether to start or stop recording or playing
back, as well as what test is being run.

To start recording a test, the server should be primed with a POST request:

```
URL: https://localhost:5001/record/start
headers {
"x-recording-file": "<path-to-test>/recordings/<testfile>.<testname>"
}
```

This will return a recording ID in an `x-recording-id` header. This ID should be sent as an `x-recording-id` header in
all further requests during the test.

After the test has finished, a POST request should be sent to indicate that recording is complete:

```
URL: https://localhost:5001/record/stop
headers {
"x-recording-id": "<x-recording-id>"
}
```

Running tests in playback follows the same pattern, except that requests will be sent to `/playback/start` and
`/playback/stop` instead. A header, `x-recording-mode`, should be set to `record` for all requests when recording and
`playback` when playing recordings back. More details can be found [here][detailed_docs].

The RecordedByProxy and RecordedByProxyAsync decorators send the appropriate requests at the start and end of each test
case.

[detailed_docs]: https://github.com/Azure/azure-sdk-tools/tree/main/tools/test-proxy/Azure.Sdk.Tools.TestProxy/README.md
[docker_start_proxy]: https://github.com/Azure/azure-sdk-for-python/blob/main/eng/common/testproxy/docker-start-proxy.ps1
[general_docs]: https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/README.md
[proxy_cert_docs]: https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/documentation/trusting-cert-per-language.md
[pytest_collection]: https://docs.pytest.org/latest/goodpractices.html#test-discovery
[pytest_fixtures]: https://docs.pytest.org/latest/fixture.html#scope-sharing-fixtures-across-classes-modules-packages-or-session
[sanitizers]: https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/Azure.Sdk.Tools.TestProxy/README.md#session-and-test-level-transforms-sanitiziers-and-matchers
[vcrpy]: https://vcrpy.readthedocs.io
1 change: 1 addition & 0 deletions eng/.docsettings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ known_content_issues:
- ['sdk/servicebus/azure-servicebus/tests/perf_tests/README.md', '#4554']
- ['sdk/servicefabric/azure-servicefabric/README.md', '#4554']
- ['sdk/storage/azure-storage-blob/swagger/README.md', '#4554']
- ['cognitivelanguage/azure-ai-language-questionanswering/swagger/README.md', '#4554']
- ['sdk/storage/azure-storage-file-datalake/swagger/README.md', '#4554']
- ['sdk/storage/azure-storage-file-share/swagger/README.md', '#4554']
- ['sdk/storage/azure-storage/README.md', '#4554']
Expand Down
4 changes: 3 additions & 1 deletion eng/ci_tools.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ beautifulsoup4==4.9.1
pkginfo==1.5.0.1
pip==20.3
black==21.6b0; python_version >= '3.6'
wrapt<=1.12.1; python_version == '2.7'

# locking packages defined as deps from azure-sdk-tools or azure-devtools
pytoml==0.1.21
Expand All @@ -28,8 +29,9 @@ json-delta==2.0
ConfigArgParse==1.2.3
six==1.14.0
pyyaml==5.3.1
pytest==5.4.2; python_version >= '3.5'
pytest==4.6.9; python_version == '2.7'
pytest==5.4.2; python_version >= '3.5' and python_version <= '3.9'
pytest==6.2.4; python_version >= '3.10'
pytest-cov==2.8.1

# local dev packages
Expand Down
8 changes: 4 additions & 4 deletions eng/common/TestResources/New-TestResources.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,9 @@ try {
$sp.Id
}

# If the ServiceDirectory is an absolute path use the last directory name
# (e.g. D:\foo\bar\ -> bar)
$serviceName = if (Split-Path -IsAbsolute $ServiceDirectory) {
# If the ServiceDirectory has multiple segments use the last directory name
# e.g. D:\foo\bar -> bar or foo/bar -> bar
$serviceName = if (Split-Path $ServiceDirectory) {
Split-Path -Leaf $ServiceDirectory
} else {
$ServiceDirectory
Expand Down Expand Up @@ -916,4 +916,4 @@ Run this in an Azure DevOps CI (with approrpiate variables configured) before
executing live tests. The script will output variables as secrets (to enable
log redaction).
#>
#>
6 changes: 5 additions & 1 deletion eng/common/pipelines/templates/steps/cache-ps-modules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ steps:
. ./eng/common/scripts/Helpers/PSModule-Helpers.ps1
Write-Host "##vso[task.setvariable variable=CachedPSModulePath]$global:CurrentUserModulePath"
displayName: Set PS Modules Cache Directory
# Containers should bake modules into the image to save on pipeline time
condition: and(succeeded(), eq(variables['Container'], ''))
- task: Cache@2
inputs:
key: 'PSModulePath | $(CacheSalt) | $(Agent.OS) | $(Build.SourcesDirectory)/eng/common/scripts/Import-AzModules.ps1'
path: $(CachedPSModulePath)
displayName: Cache PS Modules
displayName: Cache PS Modules
# Containers should bake modules into the image to save on pipeline time
condition: and(succeeded(), eq(variables['Container'], ''))
19 changes: 19 additions & 0 deletions eng/common/pipelines/templates/steps/detect-api-changes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
parameters:
ArtifactPath: $(Build.ArtifactStagingDirectory)
Artifacts: []

steps:
- task: Powershell@2
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/scripts/Detect-Api-Changes.ps1
arguments: >
-ArtifactList ('${{ convertToJson(parameters.Artifacts) }}' | ConvertFrom-Json | Select-Object Name)
-ArtifactPath ${{parameters.ArtifactPath}}
-CommitSha '$(Build.SourceVersion)'
-BuildId $(Build.BuildId)
-PullRequestNumber $(System.PullRequest.PullRequestNumber)
-RepoFullName $(Build.Repository.Name)
pwsh: true
workingDirectory: $(Pipeline.Workspace)
displayName: Detect API changes
condition: and(succeededOrFailed(), eq(variables['Build.Reason'],'PullRequest'))
36 changes: 36 additions & 0 deletions eng/common/pipelines/templates/steps/policheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
parameters:
ExclusionDataBaseFileName: ''
TargetDirectory: ''
PublishAnalysisLogs: false
PoliCheckBlobSAS: "$(azuresdk-policheck-blob-SAS)"
ExclusionFilePath: "$(Build.SourcesDirectory)/eng/guardian-tools/policheck/PolicheckExclusions.xml"

steps:
- pwsh: |
azcopy copy "https://azuresdkartifacts.blob.core.windows.net/policheck/${{ parameters.ExclusionDataBaseFileName }}.mdb?${{ parameters.PoliCheckBlobSAS }}" `
"$(Build.BinariesDirectory)"
displayName: 'Download PoliCheck Exclusion Database'
- task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2
displayName: 'Run PoliCheck'
inputs:
targetType: F
targetArgument: "$(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}"
result: PoliCheck.sarif
optionsFC: 0
optionsXS: 1
optionsPE: 1|2|3|4
optionsRulesDBPath: "$(Build.BinariesDirectory)/${{ parameters.ExclusionDataBaseFileName }}.mdb"
optionsUEPATH: ${{ parameters.ExclusionFilePath }}

- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@2
displayName: 'Post Analysis (PoliCheck)'
inputs:
GdnBreakAllTools: false
GdnBreakGdnToolPoliCheck: true
GdnBreakGdnToolPoliCheckSeverity: Warning
continueOnError: true

- ${{ if eq(parameters.PublishAnalysisLogs, 'true') }}:
- task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3
displayName: 'Publish Security Analysis Logs'
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ steps:
DefaultBranchVariableName: TargetBranchName

- pwsh: |
$packageInfoJson = '${{ convertToJson(parameters.PackageInfoLocations) }}'.Trim('"')
$packageInfoJson = '${{ convertToJson(parameters.PackageInfoLocations) }}'.Trim('"').Replace("\\", "/")
$packageInfoLocations = ConvertFrom-Json $packageInfoJson
${{ parameters.ScriptDirectory }}/Update-DocsMsMetadata.ps1 `
-PackageInfoJsonLocations $packageInfoLocations `
Expand Down
8 changes: 4 additions & 4 deletions eng/common/pipelines/templates/steps/verify-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ parameters:
default: 'not-specified'
- name: ServiceName
type: string
default: 'not-specified'
default: ''
- name: ServiceDirectory
type: string
default: ''
Expand All @@ -17,10 +17,10 @@ steps:
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/scripts/Verify-ChangeLog.ps1
arguments: >
-PackageName ${{ parameters.PackageName }}
-ServiceDirectory ${{ coalesce(parameters.ServiceDirectory, parameters.ServiceName) }}
-PackageName '${{ parameters.PackageName }}'
-ServiceDirectory '${{ coalesce(parameters.ServiceDirectory, parameters.ServiceName) }}'
-ForRelease $${{ parameters.ForRelease }}
pwsh: true
workingDirectory: $(Pipeline.Workspace)
displayName: Verify ChangeLogEntry for ${{ parameters.PackageName }}
continueOnError: false
continueOnError: false
Loading

0 comments on commit 971464e

Please sign in to comment.