Skip to content

Commit 1c726a9

Browse files
pvaneckmccoyp
andauthored
[Docs] Add info about test proxy sanitizer opt-out (#35579)
Added some documentation updates regarding test proxy sanitization. Signed-off-by: Paul Van Eck <[email protected]> Co-authored-by: McCoy Patiño <[email protected]>
1 parent ace7926 commit 1c726a9

File tree

2 files changed

+68
-12
lines changed

2 files changed

+68
-12
lines changed

doc/dev/test_proxy_troubleshooting.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,43 @@ To match requests for query parameter content instead of exact ordering, you can
144144
`ignore_query_ordering=True`. Calling this method inside the body of a test function will update the matcher for only
145145
that test, which is recommended.
146146

147+
### Sanitization impacting request URL/body/headers
148+
149+
In some cases, a value in a response body is used in the following request as part of the URL, body, or headers. If this value is sanitized, the recorded request might differ than what is expected during playback. Common culprits include sanitization of "name", "id", and "Location" fields. To resolve this, you can either opt out of specific sanitization or add another sanitizer to align with the sanitized value.
150+
151+
#### Opt out
152+
153+
You can opt out of sanitization for the fields that are used for your requests by calling the `remove_batch_sanitizer` method from `devtools_testutils` with the [sanitizer IDs][test_proxy_sanitizers] to exclude. Generally, this is done in the `conftest.py` file, in the one of the session-scoped fixtures. Example:
154+
155+
```python
156+
from devtools_testutils import remove_batch_sanitizers, test_proxy
157+
158+
159+
@pytest.fixture(scope="session", autouse=True)
160+
def add_sanitizers(test_proxy):
161+
...
162+
# Remove the following body key sanitizer: AZSDK3493: $..name
163+
remove_batch_sanitizers(["AZSDK3493"])
164+
```
165+
166+
Some sanitizer IDs that are often opted out of are:
167+
- `AZSDK2003`: `Location` - Header regex sanitizer
168+
- `AZSDK3430`: `$..id` - Body key sanitizer
169+
- `AZSDK3493`: `$..name` - Body key sanitizer
170+
171+
However, **please be mindful when opting out of a sanitizer, and ensure that no sensitive data is being exposed**.
172+
173+
#### Add another sanitizer
174+
175+
Alternatively, you can add another sanitizer to align the recorded request with the expected request, modifying the URL, body, or headers as needed. Example:
176+
177+
```python
178+
from devtools_testutils import add_uri_regex_sanitizer
179+
180+
181+
add_uri_regex_sanitizer(regex="(?<=https://.+/foo/bar/)(?<id>[^/?\\.]+)", group_for_replace="id", value="Sanitized")
182+
```
183+
147184
## Recordings not being produced
148185

149186
Ensure the environment variable `AZURE_SKIP_LIVE_RECORDING` **isn't** set to "true", and that `AZURE_TEST_RUN_LIVE`
@@ -245,4 +282,5 @@ chmod +x .../azure-sdk-for-python/.proxy/Azure.Sdk.Tools.TestProxy
245282
[pytest_collection]: https://docs.pytest.org/latest/goodpractices.html#test-discovery
246283
[pytest_commands]: https://docs.pytest.org/latest/usage.html
247284
[record_request_failure]: https://github.com/Azure/azure-sdk-for-python/blob/e23d9a6b1edcc1127ded40b9993029495b4ad08c/tools/azure-sdk-tools/devtools_testutils/proxy_testcase.py#L97
285+
[test_proxy_sanitizers]: https://github.com/Azure/azure-sdk-tools/blob/57382d5dc00b10a2f9cfd597293eeee0c2dbd8fd/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/SanitizerDictionary.cs#L65
248286
[wrong_exception]: https://github.com/Azure/azure-sdk-tools/issues/2907

doc/dev/tests.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ testing infrastructure, and demonstrates how to write and run tests for a servic
2424
- [Update test recordings](#update-test-recordings)
2525
- [Sanitize secrets](#sanitize-secrets)
2626
- [Special case: SAS tokens](#special-case-sas-tokens)
27+
- [Opt out of specific sanitizers](#opt-out-of-specific-sanitizers)
2728
- [Functional vs. unit tests](#functional-vs-unit-tests)
2829
- [Further reading](#further-reading)
2930

@@ -163,7 +164,7 @@ the
163164

164165
## Write or run tests
165166

166-
Newer SDK tests utilize the [Azure SDK Tools Test Proxy][proxy_general_docs] to record and playback HTTP interactions.
167+
Newer SDK tests utilize the [Azure SDK Tools Test Proxy][proxy_general_docs] to record and playback HTTP interactions, while also automatically sanitizing sensitive information from recordings.
167168
To migrate an existing test suite to use the test proxy, or to learn more about using the test proxy, refer to the
168169
[test proxy migration guide][proxy_migration_guide].
169170

@@ -356,7 +357,7 @@ set for test resources and authentication. With the `AZURE_TEST_RUN_LIVE` enviro
356357
This will generate test recordings and enable playback testing. Set `AZURE_TEST_RUN_LIVE` to "false" and run tests with
357358
the same command to verify that playback tests pass.
358359

359-
Playback test errors most frequently indicate a need for additional sanitizers and/or matchers (see
360+
Playback test errors most frequently indicate a need to add/remove sanitizers and/or add matchers (see
360361
[Sanitize secrets](#sanitize-secrets)). If you encounter any unexpected errors, refer to the
361362
[test proxy troubleshooting guide][troubleshooting_guide].
362363

@@ -437,11 +438,14 @@ The `.json` files created from running tests in live mode can include authorizat
437438
access signatures, and other secrets. The recordings are included in our public GitHub repository, making it important
438439
for us to remove any secrets from these recordings before committing them to the repository.
439440

441+
By default, the test proxy server sanitizes several [common patterns][test_proxy_sanitizers] of secrets, but there are additional
442+
steps you can take to ensure that any other sensitive information is removed from recordings.
443+
440444
There are two primary ways to keep secrets from being written into recordings:
441445

442446
1. The `EnvironmentVariableLoader` will automatically sanitize the values of captured environment variables with the
443447
provided fake values.
444-
2. Sanitizers can be registered via `add_*_sanitizer` methods in `devtools_testutils`. For example, the general-use
448+
2. Additional sanitizers can be registered via `add_*_sanitizer` methods in `devtools_testutils`. For example, the general-use
445449
method for sanitizing recording bodies, headers, and URIs is `add_general_string_sanitizer`. Other sanitizers are
446450
available for more specific scenarios and can be found at [devtools_testutils/sanitizers.py][py_sanitizers].
447451

@@ -480,15 +484,29 @@ For more details about sanitizers and their options, please refer to [devtools_t
480484

481485
#### Special case: SAS tokens
482486

483-
Tests that use a Shared Access Signature (SAS) token to authenticate a client should use the
484-
[`AzureRecordedTestCase.generate_sas`][generate_sas] method to generate the token. This will automatically register a
485-
sanitizer to keep this token out of test recordings. An example of using this method can be found
486-
[here][generate_sas_example].
487+
In the past, it was recommended that the tests using Shared Access Signature (SAS) tokens should use the `AzureRecordedTestCase.generate_sas` method to generate the token and automatically register a sanitizer to keep this token out of test recordings. This method is now deprecated since the test proxy automatically sanitizes SAS tokens. If you have tests that use SAS tokens, you can remove the usage of the `generate_sas` method.
488+
489+
#### Opt out of specific sanitizers
490+
491+
Since, in some cases, the default sanitizers might be considered too aggressive and breaks tests during playback, you can opt out of certain sanitizers using the `remove_batch_sanitizers` function in your respective `conftest.py` files. For example:
492+
493+
```python
494+
from devtools_testutils import remove_batch_sanitizers, test_proxy
495+
496+
497+
@pytest.fixture(scope="session", autouse=True)
498+
def add_sanitizers(test_proxy):
499+
...
500+
# Remove the following body key sanitizer: AZSDK3493: $..name
501+
remove_batch_sanitizers(["AZSDK3493"])
502+
```
503+
504+
A list of sanitizers and their IDs can be found [here][test_proxy_sanitizers]. However, **please be mindful when opting out of a sanitizer, and ensure that no sensitive data is being exposed**.
487505

488-
`generate_sas` accepts any number of positional arguments: the first being the method that creates the SAS, and the
489-
remaining positional arguments being positional arguments for the SAS-generating method. Any keyword arguments given to
490-
`generate_sas` will be passed to the SAS-generating method as well. The generated token will be returned and its value
491-
will be sanitized.
506+
Some sanitizers IDs that are often opted out of are:
507+
- `AZSDK2003`: `Location` - Header regex sanitizer
508+
- `AZSDK3430`: `$..id` - Body key sanitizer
509+
- `AZSDK3493`: `$..name` - Body key sanitizer
492510

493511
## Functional vs. unit tests
494512

@@ -561,7 +579,6 @@ For information about more advanced testing scenarios, refer to the [advanced te
561579
[env_var_docs]: https://github.com/Azure/azure-sdk-for-python/tree/main/tools/azure-sdk-tools/devtools_testutils#use-the-environmentvariableloader
562580
[env_var_loader]: https://github.com/Azure/azure-sdk-for-python/blob/main/tools/azure-sdk-tools/devtools_testutils/envvariable_loader.py
563581
[generate_sas]: https://github.com/Azure/azure-sdk-for-python/blob/bf4749babb363e2dc972775f4408036e31f361b4/tools/azure-sdk-tools/devtools_testutils/azure_recorded_testcase.py#L196
564-
[generate_sas_example]: https://github.com/Azure/azure-sdk-for-python/blob/3e3fbe818eb3c80ffdf6f9f1a86affd7e879b6ce/sdk/tables/azure-data-tables/tests/test_table_entity.py#L1691
565582
[get_credential]: https://github.com/Azure/azure-sdk-for-python/blob/20cf5b0bd9b87f90bd5ad4fd36358d3b257f95c5/tools/azure-sdk-tools/devtools_testutils/azure_recorded_testcase.py#L96
566583
[git_setup]: https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup
567584
[kv_test_resources]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/keyvault/test-resources.json
@@ -576,6 +593,7 @@ For information about more advanced testing scenarios, refer to the [advanced te
576593
[pytest_logging]: https://docs.pytest.org/en/stable/logging.html
577594
[python-dotenv_readme]: https://github.com/theskumar/python-dotenv
578595
[recording_move]: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/recording_migration_guide.md
596+
[test_proxy_sanitizers]: https://github.com/Azure/azure-sdk-tools/blob/57382d5dc00b10a2f9cfd597293eeee0c2dbd8fd/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/SanitizerDictionary.cs#L65
579597
[test_proxy_startup]: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/test_proxy_migration_guide.md#start-the-proxy-server
580598
[test_resources]: https://github.com/Azure/azure-sdk-for-python/tree/main/eng/common/TestResources#readme
581599
[troubleshooting_guide]: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/test_proxy_troubleshooting.md

0 commit comments

Comments
 (0)