@sentry/roach 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +561 -2
- package/package.json +74 -3
- package/src/action.ts +81 -0
- package/src/addresses.ts +103 -0
- package/src/certificates.ts +169 -0
- package/src/cli.ts +35 -0
- package/src/client.ts +211 -0
- package/src/config.ts +141 -0
- package/src/gcs.ts +145 -0
- package/src/recorder.ts +464 -0
- package/src/recordings.ts +42 -0
- package/src/report.ts +55 -0
- package/src/request-key.ts +165 -0
- package/src/secrets.ts +66 -0
- package/src/server.ts +544 -0
- package/src/service.ts +572 -0
- package/src/store.ts +47 -0
- package/src/streams.ts +115 -0
- package/src/types.ts +130 -0
- package/src/usage.ts +120 -0
- package/src/values.ts +229 -0
- package/src/vitest-setup.ts +66 -0
- package/src/vitest.ts +108 -0
package/src/vitest.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vitest global setup of Roach (`@sentry/roach/vitest`). See "Use with
|
|
3
|
+
* vitest" in `README.md`.
|
|
4
|
+
*
|
|
5
|
+
* It starts one run with the config of `roach.json` (`config.ts`), and
|
|
6
|
+
* gives the proxy variables of the run to the test workers, which start
|
|
7
|
+
* after it. `vitest-setup.ts` opens one session for each test, so the
|
|
8
|
+
* tests of many workers record at the same time. At the end it closes the
|
|
9
|
+
* run and reports it.
|
|
10
|
+
*
|
|
11
|
+
* - `ROACH_TOKEN` is the write token. Only this file reads it, and the
|
|
12
|
+
* workers do not get it. Without it, the run can only replay.
|
|
13
|
+
* - `ROACH_URL` is the service. Default: the Roach service of Sentry.
|
|
14
|
+
* - `ROACH_MODE` sets the mode. See `runConfigOf()`. With `off`, it starts
|
|
15
|
+
* no run and does not use the service, so requests go direct.
|
|
16
|
+
*/
|
|
17
|
+
import http from "node:http";
|
|
18
|
+
import tls from "node:tls";
|
|
19
|
+
import type { TestProject } from "vitest/node";
|
|
20
|
+
import { startRemoteRun } from "./client.ts";
|
|
21
|
+
import {
|
|
22
|
+
DEFAULT_SERVICE_URL,
|
|
23
|
+
readEnv,
|
|
24
|
+
readRoachFile,
|
|
25
|
+
runConfigOf,
|
|
26
|
+
} from "./config.ts";
|
|
27
|
+
import { writeRunReport } from "./report.ts";
|
|
28
|
+
import type { RemoteRun } from "./types.ts";
|
|
29
|
+
|
|
30
|
+
declare module "vitest" {
|
|
31
|
+
export interface ProvidedContext {
|
|
32
|
+
/** The run of `@sentry/roach/vitest`, for the test workers. */
|
|
33
|
+
roach:
|
|
34
|
+
| (Pick<RemoteRun, "controlUrl" | "token"> & { noProxy: string })
|
|
35
|
+
| null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Start a Roach run for this vitest invocation. Returns the teardown,
|
|
41
|
+
* which ends the run and reports it. Call it from a global setup of your
|
|
42
|
+
* own when you have one, or use this module as a global setup.
|
|
43
|
+
*/
|
|
44
|
+
export async function startRoach(
|
|
45
|
+
project: Pick<TestProject, "provide">,
|
|
46
|
+
): Promise<() => Promise<void>> {
|
|
47
|
+
if (typeof http.setGlobalProxyFromEnv !== "function") {
|
|
48
|
+
throw new Error("Roach needs Node 24.14 or later for vitest");
|
|
49
|
+
}
|
|
50
|
+
const token = readEnv("ROACH_TOKEN");
|
|
51
|
+
delete process.env.ROACH_TOKEN;
|
|
52
|
+
const file = await readRoachFile();
|
|
53
|
+
const config = runConfigOf(file, { canWrite: token !== undefined });
|
|
54
|
+
if (config.mode === "off") {
|
|
55
|
+
project.provide("roach", null);
|
|
56
|
+
return async () => {};
|
|
57
|
+
}
|
|
58
|
+
const noProxy = file.noProxy ?? "localhost,127.0.0.1,::1";
|
|
59
|
+
const run = await startRemoteRun(
|
|
60
|
+
{ url: readEnv("ROACH_URL") ?? DEFAULT_SERVICE_URL, token },
|
|
61
|
+
config,
|
|
62
|
+
{ noProxy },
|
|
63
|
+
);
|
|
64
|
+
// The proxy URL has the run token. Keep it out of the CI log.
|
|
65
|
+
if (process.env.GITHUB_ACTIONS) {
|
|
66
|
+
process.stdout.write(`::add-mask::${run.token}\n`);
|
|
67
|
+
}
|
|
68
|
+
const previousEnv = Object.keys(run.env).map(
|
|
69
|
+
(name) => [name, process.env[name]] as const,
|
|
70
|
+
);
|
|
71
|
+
// Test workers and their child processes start later and inherit these.
|
|
72
|
+
Object.assign(process.env, run.env);
|
|
73
|
+
// This process started before them, so it reads neither the proxy nor
|
|
74
|
+
// the CA file. Set both here.
|
|
75
|
+
const previousCa = tls.getCACertificates("default");
|
|
76
|
+
tls.setDefaultCACertificates([...previousCa, run.caCert]);
|
|
77
|
+
const restoreProxy = http.setGlobalProxyFromEnv(run.env);
|
|
78
|
+
project.provide("roach", {
|
|
79
|
+
controlUrl: run.controlUrl,
|
|
80
|
+
token: run.token,
|
|
81
|
+
noProxy,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return async () => {
|
|
85
|
+
try {
|
|
86
|
+
const stats = await run.close();
|
|
87
|
+
await writeRunReport(`Roach (${config.mode})`, stats);
|
|
88
|
+
// A miss in a test fails that test. A miss outside a test, such as in
|
|
89
|
+
// a global setup, must fail the invocation too.
|
|
90
|
+
const missed = Object.values(stats.counts).some(
|
|
91
|
+
(count) => count.missed > 0,
|
|
92
|
+
);
|
|
93
|
+
if (missed) process.exitCode = 1;
|
|
94
|
+
} finally {
|
|
95
|
+
restoreProxy();
|
|
96
|
+
tls.setDefaultCACertificates(previousCa);
|
|
97
|
+
for (const [name, value] of previousEnv) {
|
|
98
|
+
if (value === undefined) delete process.env[name];
|
|
99
|
+
else process.env[name] = value;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The vitest global setup. */
|
|
106
|
+
export default function setup(project: TestProject) {
|
|
107
|
+
return startRoach(project);
|
|
108
|
+
}
|