Skip to content

Commit 61f2919

Browse files
committed
refactor: separate recording and replay into distinct CLI tools
- Split bin/server.ts (replay-only) and bin/record.ts (recording-only) - Update startServer() to remove mode parameter, always replays - Created tests for replay and recording - Update tests to use new API signatures - Add debug configurations for both tools
1 parent 5fa4516 commit 61f2919

File tree

8 files changed

+104
-30
lines changed

8 files changed

+104
-30
lines changed

resources/mock-server/.gitignore

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,4 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
3434
.DS_Store
3535

3636

37-
.tmp/
38-
39-
# Test recordings
40-
recordings-test/
41-
!recordings-test/.gitkeep
37+
.tmp/

resources/mock-server/.vscode/launch.json

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,28 @@
77
{
88
"type": "bun",
99
"request": "launch",
10-
"name": "Debug Server with Recording",
10+
"name": "Debug Replay Server",
1111
"program": "${workspaceFolder}/bin/server.ts",
12-
"args": ["algod", "record-new"],
12+
"args": ["algod"], // Change to: algod, indexer, or kmd
1313
"cwd": "${workspaceFolder}",
1414
"stopOnEntry": false,
1515
"watchMode": false,
1616
"env": {
1717
"NODE_ENV": "development",
18-
"LOG_LEVEL": "debug",
19-
"PORT": "8000"
18+
"LOG_LEVEL": "debug"
19+
}
20+
},
21+
{
22+
"type": "bun",
23+
"request": "launch",
24+
"name": "Debug Record",
25+
"program": "${workspaceFolder}/bin/record.ts",
26+
"args": ["algod", "record-new"], // Change client: algod, indexer, kmd | mode: record-new, record-overwrite
27+
"cwd": "${workspaceFolder}",
28+
"stopOnEntry": false,
29+
"watchMode": false,
30+
"env": {
31+
"NODE_ENV": "development"
2032
}
2133
}
2234
]
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { describe, it, expect, afterEach } from "vitest";
2+
import { record } from "../src/index";
3+
import { Algodv2 } from "algosdk";
4+
import fs from "fs";
5+
import path from "path";
6+
7+
const TEST_RECORDINGS_DIR = path.resolve(__dirname, "../recordings-test");
8+
const LOCALNET_ALGOD_URL = "http://localhost";
9+
const LOCALNET_ALGOD_PORT = 4001;
10+
11+
describe("Recording Tests", () => {
12+
afterEach(async () => {
13+
// Clean up test recordings directory completely
14+
if (fs.existsSync(TEST_RECORDINGS_DIR)) {
15+
fs.rmSync(TEST_RECORDINGS_DIR, { recursive: true, force: true });
16+
}
17+
});
18+
19+
it("should record in record-new mode", async () => {
20+
// Create test recordings directory
21+
fs.mkdirSync(TEST_RECORDINGS_DIR, { recursive: true });
22+
23+
// Create recording with record-new
24+
await record(
25+
"algod",
26+
async () => {
27+
const client = new Algodv2(
28+
"a".repeat(64),
29+
LOCALNET_ALGOD_URL,
30+
LOCALNET_ALGOD_PORT
31+
);
32+
await client.status().do();
33+
},
34+
"record-new",
35+
TEST_RECORDINGS_DIR
36+
);
37+
38+
// Verify HAR file was created
39+
const harFiles = fs.readdirSync(TEST_RECORDINGS_DIR, { recursive: true });
40+
const harFileName = harFiles.find((f) =>
41+
f.toString().endsWith("recording.har")
42+
);
43+
expect(harFileName).toBeDefined();
44+
45+
const harPath = path.join(TEST_RECORDINGS_DIR, harFileName!.toString());
46+
expect(fs.existsSync(harPath)).toBe(true);
47+
48+
// Verify HAR file has entries
49+
const content = fs.readFileSync(harPath, "utf-8");
50+
const har = JSON.parse(content);
51+
expect(har.log.entries.length).toBeGreaterThan(0);
52+
});
53+
});

resources/mock-server/__test__/replay.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe("Algod Mock Server", () => {
1010
let algodClient: Algodv2;
1111

1212
beforeAll(async () => {
13-
algodServer = await startServer("algod", "replay");
13+
algodServer = await startServer("algod");
1414
algodClient = new Algodv2(
1515
"a".repeat(64),
1616
"http://localhost",
@@ -60,7 +60,7 @@ describe("Indexer Mock Server", () => {
6060
let indexerClient: Indexer;
6161

6262
beforeAll(async () => {
63-
indexerServer = await startServer("indexer", "replay");
63+
indexerServer = await startServer("indexer");
6464
indexerClient = new Indexer(
6565
"a".repeat(64),
6666
"http://localhost",
@@ -110,7 +110,7 @@ describe("KMD Mock Server", () => {
110110
let kmdClient: Kmd;
111111

112112
beforeAll(async () => {
113-
kmdServer = await startServer("kmd", "replay");
113+
kmdServer = await startServer("kmd");
114114
kmdClient = new Kmd("a".repeat(64), "http://localhost", kmdServer.port);
115115
});
116116

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { Client } from "../src/index.ts";
2+
import { recordAlgosdkRequests } from "../src/record.ts";
3+
4+
const client = process.argv[2] as Client;
5+
const mode = process.argv[3] as "record-new" | "record-overwrite";
6+
const recordingsDir = process.argv[4];
7+
8+
console.log(`Recording ${client} requests in ${mode} mode...`);
9+
if (recordingsDir) {
10+
console.log(`Recordings directory: ${recordingsDir}`);
11+
}
12+
13+
await recordAlgosdkRequests(client, mode, recordingsDir);
14+
15+
console.log(`✓ Recording complete for ${client}`);
Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import type { Client } from "../src/index.ts";
22
import { startServer } from "../src/server.ts";
33

4-
const client = process.argv[2];
5-
const mode = process.argv[3];
6-
const server = await startServer(
7-
client as Client,
8-
mode as "record-new" | "record-overwrite" | "replay"
9-
);
10-
11-
await server.listen;
4+
const client = process.argv[2] as Client;
5+
const recordingsDir = process.argv[3];
6+
7+
console.log(`Starting ${client} mock server in replay mode...`);
8+
if (recordingsDir) {
9+
console.log(`Recordings directory: ${recordingsDir}`);
10+
}
11+
12+
const server = await startServer(client, recordingsDir);
13+
14+
console.log(`✓ Server listening on port ${server.port}`);

resources/mock-server/src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ export async function record(
7676

7777
export async function replay<T>(
7878
client: Client,
79-
makeRequests: () => Promise<T>
79+
makeRequests: () => Promise<T>,
80+
recordingsDir?: string
8081
): Promise<T> {
81-
const polly = getPolly(client, { mode: "replay" });
82+
const polly = getPolly(client, { mode: "replay", recordingsDir });
8283

8384
try {
8485
return await makeRequests();

resources/mock-server/src/server.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { HeadersInit } from "bun";
22
import Fastify from "fastify";
33
import { replay, type Client } from "./index";
4-
import { recordAlgosdkRequests } from "./record";
54

65
export type ServerInstance = {
76
port: number;
@@ -23,14 +22,8 @@ const DEFAULT_PORTS = {
2322

2423
export async function startServer(
2524
client: Client,
26-
mode: "record-new" | "record-overwrite" | "replay" = "replay",
2725
recordingsDir?: string
2826
): Promise<ServerInstance> {
29-
// Only record if not in replay mode
30-
if (mode !== "replay") {
31-
await recordAlgosdkRequests(client, mode, recordingsDir);
32-
}
33-
3427
const fastify = Fastify({
3528
logger: {
3629
level: process.env.LOG_LEVEL || "info",
@@ -87,7 +80,8 @@ export async function startServer(
8780
request.method !== "GET" && request.method !== "HEAD"
8881
? JSON.stringify(request.body)
8982
: undefined
90-
})
83+
}),
84+
recordingsDir
9185
);
9286
} catch (e) {
9387
reply.status(500).send(JSON.stringify(e));

0 commit comments

Comments
 (0)