Skip to content

Test Proxy Migration

Bill Wert edited this page Feb 27, 2023 · 36 revisions

Test Proxy Server

It is common practice in many of our SDKs to test service client code by recording HTTP requests and responses during a test run against a live endpoint and then playing back the matching responses to requests in subsequent runs.

The basic idea is to have a test server that sits between the client being tested and the live endpoint. Instead of mocking out the communication with the server, the communication can be redirected to a test server.

Major benefits

  1. Repo size - Our repos are getting big and the biggest contributor to this issue are recordings. Consolidating on a single solution and recording format makes it easier to have the storage for recordings moved outside of the main repo.
  2. Share Code - reusing/centralizing the general code for recording and playback. eg: test server is hard-wired for sanitization/redirection defaults
  3. Performance testing - eliminate server-side bottlenecks from a benchmark so instead of contacting the live service, a test service can respond with recorded/cached responses.

Roll-out strategy

The roll-out strategy can be split into below phases:

  1. Record test recordings with the test-proxy integration
  2. Migrate updated recordings to assets repo
  3. Using test proxy going forward

1) Record test recordings with the test-proxy integration

Each SDK needs to re-record its test recordings using the test-proxy integration to ensure a consolidated recording format with serialized/sanitized requests and their matching responses.

Steps:

  1. Delete old recordings from under src/test/resources/session-records. (In theory it will overwrite them but it's a good idea to just be explicit.)

  2. To use the proxy, test classes should extend from TestProxyTestBase instead of TestBase

    public abstract class DocumentAnalysisClientTestBase extends TestProxyTestBase {}
  3. Run tests in Record mode using the test-proxy integration.

  4. Sanitize secrets:

    Default sanitizers, similar to the use of the RecordingRedactor is registered in the TestProxyUtils.

    Custom sanitizers can be registered using TestProxySanitizer for addressing specific service needs.

    For example, registering a custom sanitizer for redacting the value of json key modelId from the response body looks like the following:

    @Override
    protected void beforeTest() {
        List<TestProxySanitizer> customSanitizer = new ArrayList<>();
        // sanitize value for key: "modelId" in response json body
        customSanitizer.add(new TestProxySanitizer("$..modelId", REPLACEMENT_TEXT, TestProxySanitizerType.BODY_KEY));
        // add sanitizer to Test Proxy Policy
        interceptorManager.addRecordSanitizers(customSanitizer);
    }
  5. Check in the updated recordings to the main repo, example recording

Potential gotchas!

The test proxy is much more exact about matching recordings than the old recorder. You may get errors or strange behavior when you try to playback recording, such as output like this:

Header differences:
    <Ocp-Apim-Subscription-Key> is absent in record, value <REDACTED>
    <Authorization> is absent in request, value <Sanitized>

This indicates that there is something different about your test in playback and record modes. Look for places where you're doing something conditional and ensure it is doing the same thing in both modes. If you think that your test is doing the same thing and you're still hitting problems, please reach out.

2) Migrate updated recordings to assets repo

Migrating the test recordings to the asset repo will enable the test proxy to work against repositories and will not require them to emplace their test recordings directly alongside their test implementations.

Steps:

  1. Create an asset.json file for each SDK i.e sdk/tables/assets.json. The asset.json file basically will allow the test-proxy to restore a set of recordings to a path, then load the recording from that newly gathered data.
  2. Moving files from the main repo to the asset repo. This step will involve using the test proxy for actually pushing the recording assets over to the asset repo. Once the recordings are pushed the respective SDK asset.json in the main repo also needs to be replaced with the updated asset.json holding the new Tag information.

3) Using test proxy going forward

After moving recordings to the asset repo, live and playback testing will be the same as it was in the past.

Running tests in Playback mode

When running tests in Playback mode, the test-proxy automatically checks out the appropriate tag in each local assets repo and peforms testing.

Running tests in Record mode

  1. After running tests in record mode, the newly updated recordings no longer be in the azure-sdk-for-java repo. These updates will be reflected in a git-excluded .assets folder at the root of the repo.

  2. You can cd into the folder containing your package's recordings and use git status to view the recording updates. Verify the updates, and use the following command to push these recordings to the azure-sdk-assets repo:

    test-proxy push <path-to-assets-json>

  3. After pushing your recordings, the assets.json file for your package will be updated to point to a new Tag that contains the updates. Include this assets.json update in any pull request to update the recordings pointer in the upstream repo.

Test Proxy CLI commands.

The test proxy enables CLI interactions with the external assets repository using the sdk/<sdk-name>/asset.json file.

To locally clone or pull assets/test-recording associated with a particular asset.json file.

test-proxy restore --assets-json-path <assetsJsonPath>

To reset the local copy of the files back to the version targeted in the given assets.json file.

test-proxy reset --assets-json-path <assetsJsonPath>

To push the updated/local assets to the assets repo.

test-proxy push --assets-json-path <assetsJsonPath>

Test Proxy local assets clone repo structure

Test-Proxy maintains a separate clone for each assets.json. The recording files will be located under your repo root under the .assets folder.

    +-------------------------------+
    |  azure-sdk-for-java/        |
    |    sdk/                       |
    |      storage/                 |
    | +------assets.json            |
    | |    appconfiguration/        |
    | | +----assets.json            |
    | | |  keyvault/                |
    | | |    azure-keyvault-secrets |
    | | |      assets.json-------+  |
    | | |    azure-keyvault-keys |  |
    | | |      assets.json---+   |  |
    | | |                    |   |  |
    | | |.assets/            |   |  |
    | | +--AuN9me8zrT/       |   |  |
    | |      <sparse clone>  |   |  |
    | +----5hgHKwvMaN/       |   |  |
    |        <sparse clone>  |   |  |
    |      AuN9me8zrT--------+   |  |
    |        <sparse clone>      |  |
    |      BSdGcyN2XL------------+  |
    |        <sparse clone>         |
    +-------------------------------+
   

For more details/doubts on test-proxy workings, follow Teams channel

Clone this wiki locally