Skip to content

Commit

Permalink
[Unified Recorder] Support "variables" in recordings with proxy-tool (#…
Browse files Browse the repository at this point in the history
…18585)

* variables

* remove console.ogs

* Add docs

* changelog

* recorder.variables

* recordings

* more docs

* Update sdk/test-utils/recorder-new/CHANGELOG.md

Co-authored-by: Will Temple <[email protected]>

* Update sdk/test-utils/recorder-new/CHANGELOG.md

Co-authored-by: Will Temple <[email protected]>

* Update sdk/test-utils/recorder-new/src/core-v2-recorder.ts

Co-authored-by: Will Temple <[email protected]>

* feedback

Co-authored-by: Will Temple <[email protected]>
  • Loading branch information
HarshaNalluru and witemple-msft authored Nov 11, 2021
1 parent 0cc6b97 commit a5d9897
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 70 deletions.
14 changes: 14 additions & 0 deletions sdk/test-utils/recorder-new/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

## 1.0.0 (Unreleased)

## 2021-11-08

- Allows storing dynamically created variables in record mode. The recorder registers the variables as part of the recording and stores their values in the recording file. Using the `variables` in playback mode produces the key-value pairs that were stored in the recording file.

Example:

```ts
if (!isPlaybackMode()) {
recorder.variables["random-1"] = `random-${Math.ceil(Math.random() * 1000 + 1000)}`;
}
```

Use `recorder.variables["random-1"]` to access the value of the variable after setting it. The variable can be accessed in all three modes -- record, playback, and live -- as long as it is set in record mode before it is accessed.

## 2021-10-15

[#17379](https://github.com/Azure/azure-sdk-for-js/pull/17379)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions sdk/test-utils/recorder-new/src/core-v2-recorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ export class TestProxyHttpClient {
private sessionFile: string | undefined = undefined;
private sanitizer: Sanitizer | undefined;

/**
* Add the dynamically created variables here in the record mode, so that the recorder registers them as part of the recording.
* Using this "variables" in playback mode would give the key-value pairs that are stored in record mode.
*
* Example:
* ```ts
* if (!isPlaybackMode()) {
* recorder.variables["random-1"] = `random-${Math.ceil(Math.random() * 1000 + 1000)}`;
* }
* ```
* Use this `recorder.variables["random-1"]` whereever you'd like to use in your test.
* (This would work in all three modes - record/playback/live just by adding the if-block above)
*
* Internals(How does it work?):
* - recorder.stop() call sends the variables to the proxy-tool (in record mode)
* - recorder.start() call loads those variables given by the proxy tool (in playback mode)
*/
public variables: Record<string, string>;

constructor(private testContext?: Test | undefined) {
this.mode = env.TEST_MODE;
if (isRecordMode() || isPlaybackMode()) {
Expand All @@ -55,6 +74,7 @@ export class TestProxyHttpClient {
}
this.sanitizer = new Sanitizer(this.mode, this.url, this.httpClient);
}
this.variables = {};
}

/**
Expand Down Expand Up @@ -151,6 +171,9 @@ export class TestProxyHttpClient {
throw new RecorderError("No recording ID returned for a successful start request.");
}
this.recordingId = id;
if (isPlaybackMode()) {
this.variables = JSON.parse(rsp.bodyAsText ?? "{}");
}
if (ensureExistence(this.sanitizer, "TestProxyHttpClient.sanitizer", this.mode)) {
// Setting the recordingId in the sanitizer,
// the sanitizers added will take the recording id and only be part of the current test
Expand Down Expand Up @@ -181,6 +204,10 @@ export class TestProxyHttpClient {
const req = this._createRecordingRequest(stopUri);
req.headers.set("x-recording-save", "true");

if (isRecordMode()) {
req.headers.set("Content-Type", "application/json");
req.body = JSON.stringify(this.variables);
}
if (ensureExistence(this.httpClient, "TestProxyHttpClient.httpClient", this.mode)) {
const rsp = await this.httpClient.sendRequest({
...req,
Expand Down
18 changes: 18 additions & 0 deletions sdk/test-utils/recorder-new/test/testProxyTests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ function getTestServerUrl() {
);
});

it("sample_response with random string in path", async () => {
await recorder.start({ envSetupForPlayback: {} });

if (!isPlaybackMode()) {
recorder.variables["random-1"] = `random-${Math.ceil(Math.random() * 1000 + 1000)}`;
recorder.variables["random-2"] = "known-string";
}

await makeRequestAndVerifyResponse(
{ path: `/sample_response/${recorder.variables["random-1"]}`, method: "GET" },
{ val: "I am the answer!" }
);
await makeRequestAndVerifyResponse(
{ path: `/sample_response/${recorder.variables["random-2"]}`, method: "GET" },
{ val: "I am the answer!" }
);
});

describe("Sanitizers", () => {
it("GeneralRegexSanitizer", async () => {
env.SECRET_INFO = "abcdef";
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a5d9897

Please sign in to comment.