Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Recorder] [Test Proxy] [Asset Sync] Updates to the docs #25350

Merged
merged 14 commits into from
Mar 28, 2023
Merged
19 changes: 11 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Rush provides many benefits:
Not every library in the repository is managed by Rush yet, only those listed in the `projects` property in [rush.json](https://github.com/Azure/azure-sdk-for-js/blob/main/rush.json). Packages not managed by Rush can still be managed using `npm`.

Check out our [wiki page on using rush](https://github.com/Azure/azure-sdk-for-js/wiki/Rush) for more information on

- running `rush update` command
- How to update to a newer version of Rush or PNPM.

Expand All @@ -78,11 +79,13 @@ If you prefer to setup your own environment instead, make sure you have these pr
- Git
- Any of the [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule)
- A C++ compiler toolchain and Python (for compiling machine-code modules):

- Windows: Install the [Visual Studio Build Tools][buildtools] from Microsoft and [Python 3.9][python39windows] from the Microsoft Store.
- macOS: Install Xcode or the "Command Line Tools for XCode" (much smaller) from [Apple's developer downloads page](https://developer.apple.com/download/all/).
- Linux: Install Python and GCC/G++ (part of the `build-essential` package on Ubuntu-based distributions) using your distribution's package manager.

**On Linux, development headers for `libsecret` are also required.** Typically, these are available in a package called `libsecret-1-dev` (Debian/Ubuntu) or `libsecret-devel` (Fedora/Red Hat).

- Rush 5.x
- Install / update Rush globally via `npm install -g @microsoft/rush`.
- Rush will automatically manage the specific version needed by this repo as long as you have any v5 version installed.
Expand Down Expand Up @@ -150,13 +153,11 @@ By default, these npm scripts run previously recorded tests. The recordings have

Most of the tests in our projects run in playback mode by default, i.e they make no network requests to the real services. For HTTP requests made in each test case, there is a recorded response that reproduces the service behavior. The readme file in the `test` folder of each package will indicate whether the package uses recorded tests or not.

At the moment, tests in our repo depend on one of the two different versions of the recorder tool (`@azure-tools/test-recorder`) - `1.a.b` and `2.x.y`.
Currently, version `2.x.y` is maintained in the repository which is built as part of a cross-language unification effort in terms of the tests and recordings.
Eventually, all the tests will be migrated to depend on the `2.x.y` version of the recorder that depends on the language-agnostic [test proxy server].
At the moment, tests in our repo depend on one of the two different versions of the recorder tool (`@azure-tools/test-recorder`) - `1.a.b` and `3.m.n`.
Currently, version `3.m.n` is maintained in the repository which is built as part of a cross-language unification effort in terms of the tests and recordings.
Eventually, all the tests will be migrated to depend on the `3.m.n` version of the recorder that depends on the language-agnostic [test proxy server].

To record and playback the tests that depend on version `2.x.y` of `@azure-tools/test-recorder`, [docker] is required, as the [test proxy server] is run in a container during testing. When running the tests, ensure the Docker daemon is running and you have permission to use it. For WSL 2, running `sudo service docker start` and `sudo usermod -aG docker $USER` should be sufficient.

Refer to the [Migration Guide](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/test-utils/recorder/MIGRATION.md) for more information on migrating the tests from recorder v1 to v2.
Refer to the [Migration Guide](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/test-utils/recorder/MIGRATION.md) for more information on migrating the tests from recorder v1 to v3.

#### Live tests

Expand All @@ -180,6 +181,8 @@ Regenerating the recordings has the same requirements as running the live tests.

For more information the recorder, please visit the [test-recorder's readme](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/test-utils/recorder/README.md).

Here are a few [Useful Commands](https://github.com/Azure/azure-sdk-for-js/wiki/Golden-Testing-Commands) that can be handy while testing your SDKs.

### Other NPM scripts

Most package scripts are exposed as Rush commands. Use `rushx <scriptname>` in place of `npm run <scriptname>` to run the package script in all projects. Navigate to a project's directory and substitute `rushx` for `rush` to run the script for just the current project. Run `rush <scriptname> --help` for more information about each script.
Expand Down Expand Up @@ -340,8 +343,8 @@ Samples may take the following categories of dependencies:

- **Commercial**: Commercial offerings that enable readers to learn from our content without unnecessary extra costs. Typically, the offering has some form of a community edition, or a free trial sufficient for its use in content. A commercial license may be a form of dual-license, or tiered license. Links to commercial components should be to the commercial site for the software, even if the source software is hosted publicly on GitHub (or similar).

- **Dual licensed**: Commercial offerings that enable readers to choose either license based on their needs. For example, if the offering has an OSS and commercial license, readers can choose between them. [MySql](https://github.com/mysql/mysql-server) is an example of this license type.
- **Dual licensed**: Commercial offerings that enable readers to choose either license based on their needs. For example, if the offering has an OSS and commercial license, readers can choose between them. [MySql](https://github.com/mysql/mysql-server) is an example of this license type.

- **Tiered licensed**: Offerings that enable readers to use the license tier that corresponds to their characteristics. For example, tiers may be available for students, hobbyists, or companies with defined revenue thresholds. For offerings with tiered licenses, strive to limit our use in tutorials to the features available in the lowest tier. This policy enables the widest audience for the article. [Docker](https://www.docker.com/), [IdentityServer](https://duendesoftware.com/products/identityserver), [ImageSharp](https://sixlabors.com/products/imagesharp/), and [Visual Studio](https://visualstudio.com) are examples of this license type.
- **Tiered licensed**: Offerings that enable readers to use the license tier that corresponds to their characteristics. For example, tiers may be available for students, hobbyists, or companies with defined revenue thresholds. For offerings with tiered licenses, strive to limit our use in tutorials to the features available in the lowest tier. This policy enables the widest audience for the article. [Docker](https://www.docker.com/), [IdentityServer](https://duendesoftware.com/products/identityserver), [ImageSharp](https://sixlabors.com/products/imagesharp/), and [Visual Studio](https://visualstudio.com) are examples of this license type.

In general, we prefer taking dependencies on licensed components in the order of the listed categories. In cases where the category may not be well known, we'll document the category so that readers understand the choice that they're making by using that dependency.
1 change: 1 addition & 0 deletions common/tools/dev-tool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ It provides a place to centralize scripts, resources, and processes for developm
- `run` (execute a sample or all samples within a directory)
- `check-node-versions` (execute samples with different node versions, typically in preparation for release)
- `test-proxy`
- `init` (initializes `assets.json` in your package folder)
- `push` (pushes the assets, referenced by assets.json, into git)
- `reset` (reset the assets, referenced by assets.json, from git to their original files referenced by the tag. Will prompt if there's pending changes)
- `restore` (restore the assets, referenced by assets.json, from git)
Expand Down
16 changes: 16 additions & 0 deletions common/tools/dev-tool/src/commands/test-proxy/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { leafCommand, makeCommandInfo } from "../../framework/command";
import { createAssetsJson } from "../../util/testProxyUtils";

export const commandInfo = makeCommandInfo(
"test-proxy",
"initialize the assets.json file required for the assets-sync mechanism to store recordings",
{}
);

export default leafCommand(commandInfo, async () => {
await createAssetsJson();
return true;
});
7 changes: 5 additions & 2 deletions common/tools/dev-tool/src/util/testProxyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ export async function runTestProxyCommand(argv: string[]): Promise<void> {
return runCommand(await getTestProxyExecutable(), argv, { stdio: "inherit" }).result;
}

export function createAssetsJson(): Promise<void> {
return runMigrationScript(false);
}

export async function runMigrationScript(initialPush: boolean): Promise<void> {
const migrationScriptLocation = path.join(
await resolveRoot(),
Expand Down Expand Up @@ -210,8 +214,7 @@ export async function isProxyToolActive(): Promise<boolean> {
await axios.get(`http://localhost:${process.env.TEST_PROXY_HTTP_PORT ?? 5000}/info/available`);

log.info(
`Proxy tool seems to be active at http://localhost:${
process.env.TEST_PROXY_HTTP_PORT ?? 5000
`Proxy tool seems to be active at http://localhost:${process.env.TEST_PROXY_HTTP_PORT ?? 5000
}\n`
);
return true;
Expand Down
118 changes: 93 additions & 25 deletions sdk/test-utils/recorder/ASSET_SYNC_MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,77 @@ Recordings take up a large amount of space in our repository and generate a lot

## Performing the migration

The package you are migrating needs to be using the new version of the recorder that uses the test proxy (`@azure-tools/test-recorder@^2.0.0`). Most packages are using the new recorder already; if yours is not you should migrate as soon as possible. More detail on migrating to the new recorder can be found in the [recorder 2.0 migration guide]. To run the migration script, you will need both [Powershell] and [`dev-tool`] installed. If you haven't installed `dev-tool` yet, you can install it as follows:
### Prerequisites

```bash
$ cd common/tools/dev-tool # (from your azure-sdk-for-js repo root)
$ npm install -g
```
To be able to leverage the asset-sync workflow, you will need

- [Powershell] installed
- `dev-tool` among your `devDependencies` in the `package.json`.

_If you are working on a new package and don't have any recorded tests, skip to [New Package - No Recorded Tests](#new-package---no-recorded-tests)._

The package you are migrating needs to be using the new version of the recorder that uses the test proxy (`@azure-tools/test-recorder@^3.0.0`). If you're on an older version, follow [recorder 3.0 migration guide] first.

### Migration

Run the following command to migrate the recordings.

```bash
$ npx dev-tool test-proxy migrate --initial-push
```

_Note: If you [install `dev-tool` globally], you don't need `npx` prefix in the above command_

Once this is done, validate that your recorded tests still pass, and create a PR with the changes. That's it!

The above `migrate` command produces an `assets.json`, with a tag pointing to your recordings in the `Azure/azure-sdk-assets` repository.

Example `assets.json` from "keyvault-certificates" SDK.

```json
{
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "js",
"TagPrefix": "js/keyvault/keyvault-certificates",
"Tag": "js/keyvault/keyvault-certificates_43821e21b3"
}
```

And the recordings are located at https://github.com/Azure/azure-sdk-assets/tree/js/keyvault/keyvault-certificates_43821e21b3

### New Package - No Recorded Tests

_If you already have an `assets.json` file, skip to [Workflow with asset sync enabled](#workflow-with-asset-sync-enabled)._

This section assumes that your package is new to the JS repo and that you're trying to onboard your tests with recorder, and the asset-sync workflow.

From the root of the repo, navigate to your package

```
cd sdk/<service-folder>/<package-name>
```

Generate an `sdk/<service-folder>/<package-name>/assets.json` file by running the following command.

```
npx dev-tool test-proxy init
```

This command would generate an `assets.json` file with an empty tag.

## Workflow with asset sync enabled

At this point, you should have an `assets.json` file under your SDK.
`sdk/<service-folder>/<package-name>/assets.json`.

Run your tests using the usual [package.json scripts].

`rushx integration-test:node`, for example.

With asset sync enabled, there is one extra step that must be taken before you create a PR with changes to recorded tests: you must push the new recordings to the assets repo. This is done with the following command:

```bash
$ npx dev-tool test-proxy push
npx dev-tool test-proxy push
```

This command will:
Expand All @@ -34,27 +86,43 @@ This command will:

You should stage and commit the `assets.json` update as part of your PR. If you don't run the `push` command before creating a PR, the CI (and anyone else who tries to run your recorded tests) will use the old recordings, which will cause failures.

This diagram describes the new workflow (new steps highlighted):
After onboarding your new package or after migrating your package to the asset-sync workflow, the following diagram describes the new workflow (new steps highlighted):

```mermaid
graph TD
record[Record tests<pre>TEST_MODE=record rushx test</pre>] -->
playback[Inspect recordings and test in playback<pre>TEST_MODE=playback rushx test</pre>]

playback -- Tests don't work, re-record --> record
playback -- Tests pass in playback\nand are properly sanitized --> push

subgraph New steps
push[Push recordings to asset sync repo<pre>npx dev-tool test-proxy push</pre>] -->
assets[Commit <code>assets.json</code> change]
end

assets --> pr[Push branch and\ncreate PR]
subgraph p3 [New steps]
subgraph p4 [Push recordings to asset sync repo]
push[npx dev-tool test-proxy push]
end
p4-->assets[Commit <code>assets.json</code> change]
end

assets --> pr[Push branch and\ncreate PR]

subgraph p2 [Inspect recordings and test in playback]
playback[TEST_MODE=playback rushx test]
end

subgraph p1 [Record tests]
record[TEST_MODE=record rushx test]
end

p1 --> p2
p2 -- Tests don't work re-record --> p1
p2 -- Tests pass in playback\nand are properly sanitized --> p4


classDef green fill:#548235,stroke:#333,stroke-width:2px
classDef orange fill:#C65911,stroke:#333,stroke-width:2px
classDef blue fill:#305496,stroke:#333,stroke-width:2px
class p1 orange
class p2 green
class p3 blue
```

### Inspecting recordings with asset sync enabled

Often, when re-recording tests, you will want to inspect the recordings that have been made, either to debug something or to make sure secrets have been sanitized properly. With asset sync enabled, the recordings are no longer stored in the same place as your SDK. You'll need to follow the following process to find them:
Often, when re-recording tests, you will want to inspect the recordings that have been made, either to debug something or to make sure secrets have been sanitized properly. With asset sync workflow enabled, the recordings are no longer stored in the same place as your SDK. You'll need to follow the following process to find them:

1. Navigate to the root of the `azure-sdk-for-js` repo.
1. Go into the `.assets` directory. This will contain a file called `.breadcrumb`; open it and find the entry that matches your SDK. This will give you the name of the directory within `.assets` that your recordings are located in.
Expand All @@ -73,16 +141,16 @@ A few commands have been added to `dev-tool` to facilitate pushing and fetching
- `dev-tool test-proxy reset`: if you've made any changes to the recordings locally, you can use this to revert those local changes and reset to what is currently checked in to the assets repo. This is a destructive operation and if you have local changes it will prompt you before removing your work.
- `dev-tool test-proxy migrate`: used for migrating existing recordings to the assets repo as described above.

**Refer to [testing-commands](https://github.com/Azure/azure-sdk-for-js/wiki/Golden-Testing-Commands) guide if you need help on the commands to run during testing.**

### Working offline

Offline work is supported out-of-the-box. Of course, however, you won't be able to push or pull from the assets repo while offline. You can fetch recordings from the assets repo by running `npx dev-tool test-proxy restore`. This will download the recordings (and the test proxy executable, if you haven't got that already), making them ready for you to run tests with.

## Further reading

- [Asset Sync reference in azure-sdk-tools][asset-sync-reference]
- [Recorder 2.0 migration guide]

[recorder 2.0 migration guide]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/test-utils/recorder/MIGRATION.md
[recorder 3.0 migration guide]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/test-utils/recorder/MIGRATION.md
[asset-sync-reference]: https://github.com/Azure/azure-sdk-tools/tree/main/tools/test-proxy/documentation/asset-sync
[powershell]: https://github.com/PowerShell/PowerShell
[`dev-tool`]: https://github.com/Azure/azure-sdk-for-js/tree/main/common/tools/dev-tool#installation
[install `dev-tool` globally]: https://github.com/Azure/azure-sdk-for-js/tree/main/common/tools/dev-tool#installation
[package.json scripts]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/test-utils/recorder/README.md#packagejson-scripts
Loading