test(cloudflare): Enable multi-worker tests for CF integration tests#19938
test(cloudflare): Enable multi-worker tests for CF integration tests#19938
Conversation
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Deps
Bug Fixes 🐛Cloudflare
Core
Deps
Other
Internal Changes 🔧Deps Dev
Nuxt
Other
🤖 This preview updates automatically when you update the PR. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix prepared fixes for all 3 issues found in the latest run.
- ✅ Fixed: Sub-worker config references non-existent DurableObject class
- Removed the unnecessary migrations section with non-existent MyServiceBinding class from wrangler-sub-worker.jsonc since the sub-worker has no DurableObject.
- ✅ Fixed: Unused DurableObject code copy-pasted into service binding worker
- Removed unused DurableObject imports, classes, and bindings from index.ts and fixed worker name from 'cloudflare-durable-objects' to 'cloudflare-service-binding-worker' in wrangler.jsonc.
- ✅ Fixed: Test doesn't verify shared trace_id for propagation
- Added trace_id extraction and assertion to verify both transactions share the same trace_id, and implemented manual trace header propagation for service bindings since they bypass the global fetch instrumentation.
Or push these changes by commenting:
@cursor push 0d8ab29a0b
Preview (0d8ab29a0b)
diff --git a/dev-packages/cloudflare-integration-tests/runner.ts b/dev-packages/cloudflare-integration-tests/runner.ts
--- a/dev-packages/cloudflare-integration-tests/runner.ts
+++ b/dev-packages/cloudflare-integration-tests/runner.ts
@@ -188,10 +188,7 @@
reject(e);
};
- function onChildMessage(
- message: string,
- onReady?: (port: number) => void,
- ): void {
+ function onChildMessage(message: string, onReady?: (port: number) => void): void {
const msg = JSON.parse(message) as { event: string; port?: number };
if (msg.event === 'DEV_SERVER_READY' && typeof msg.port === 'number') {
if (process.env.DEBUG) log('worker ready on port', msg.port);
@@ -220,9 +217,7 @@
// Wait for the sub-worker to be ready before starting the main worker
await new Promise<void>((resolveSubWorker, rejectSubWorker) => {
- childSubWorker!.on('message', (msg: string) =>
- onChildMessage(msg, () => resolveSubWorker()),
- );
+ childSubWorker!.on('message', (msg: string) => onChildMessage(msg, () => resolveSubWorker()));
childSubWorker!.on('error', rejectSubWorker);
childSubWorker!.on('exit', code => {
rejectSubWorker(new Error(`Sub-worker exited with code ${code}`));
diff --git a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/index.ts b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/index.ts
--- a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/index.ts
+++ b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/index.ts
@@ -1,34 +1,27 @@
import * as Sentry from '@sentry/cloudflare';
-import { DurableObject } from 'cloudflare:workers';
interface Env {
SENTRY_DSN: string;
- MY_DURABLE_OBJECT: DurableObjectNamespace;
ANOTHER_WORKER: Fetcher;
}
-class MyDurableObjectBase extends DurableObject<Env> {
- async fetch(request: Request) {
- return new Response('DO is fine');
- }
-}
-
-export const MyDurableObject = Sentry.instrumentDurableObjectWithSentry(
- (env: Env) => ({
- dsn: env.SENTRY_DSN,
- tracesSampleRate: 1.0,
- }),
- MyDurableObjectBase,
-);
-
export default Sentry.withSentry(
(env: Env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
+ tracePropagationTargets: [/.*/],
}),
{
async fetch(request, env) {
- const response = await env.ANOTHER_WORKER.fetch(new Request('http://fake-host/hello'));
+ const traceData = Sentry.getTraceData();
+ const headers: Record<string, string> = {};
+ if (traceData['sentry-trace']) {
+ headers['sentry-trace'] = traceData['sentry-trace'];
+ }
+ if (traceData.baggage) {
+ headers['baggage'] = traceData.baggage;
+ }
+ const response = await env.ANOTHER_WORKER.fetch(new Request('http://fake-host/hello', { headers }));
const text = await response.text();
return new Response(text);
},
diff --git a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/test.ts b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/test.ts
--- a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/test.ts
+++ b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/test.ts
@@ -3,6 +3,8 @@
import { createRunner } from '../../../runner';
it('propagates trace from worker to worker via service binding', async ({ signal }) => {
+ const traceIds: string[] = [];
+
const runner = createRunner(__dirname)
.expect(envelope => {
const transactionEvent = envelope[1]?.[0]?.[1] as Event;
@@ -20,6 +22,7 @@
transaction: 'GET /',
}),
);
+ traceIds.push(transactionEvent.contexts?.trace?.trace_id || '');
})
.expect(envelope => {
const transactionEvent = envelope[1]?.[0]?.[1] as Event;
@@ -37,9 +40,13 @@
transaction: 'GET /hello',
}),
);
+ traceIds.push(transactionEvent.contexts?.trace?.trace_id || '');
})
.unordered()
.start(signal);
await runner.makeRequest('get', '/');
await runner.completed();
+
+ expect(traceIds).toHaveLength(2);
+ expect(traceIds[0]).toBe(traceIds[1]);
});
diff --git a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler-sub-worker.jsonc b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler-sub-worker.jsonc
--- a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler-sub-worker.jsonc
+++ b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler-sub-worker.jsonc
@@ -3,12 +3,6 @@
"main": "index-sub-worker.ts",
"compatibility_date": "2025-06-17",
"compatibility_flags": ["nodejs_als"],
- "migrations": [
- {
- "new_sqlite_classes": ["MyServiceBinding"],
- "tag": "v1",
- },
- ],
"vars": {
"SENTRY_DSN": "https://932e620ee3921c3b4a61c72558ad88ce@o447951.ingest.us.sentry.io/4509553159831552",
},
diff --git a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler.jsonc b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler.jsonc
--- a/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler.jsonc
+++ b/dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler.jsonc
@@ -1,5 +1,5 @@
{
- "name": "cloudflare-durable-objects",
+ "name": "cloudflare-service-binding-worker",
"main": "index.ts",
"compatibility_date": "2025-06-17",
"compatibility_flags": ["nodejs_als"],This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
...cloudflare-integration-tests/suites/tracing/worker-service-binding/wrangler-sub-worker.jsonc
Outdated
Show resolved
Hide resolved
dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/index.ts
Outdated
Show resolved
Hide resolved
dev-packages/cloudflare-integration-tests/suites/tracing/worker-service-binding/test.ts
Show resolved
Hide resolved
size-limit report 📦
|
22e96a0 to
25e2557
Compare
| @@ -0,0 +1,15 @@ | |||
| { | |||
| "name": "cloudflare-durable-objects", | |||
There was a problem hiding this comment.
| "name": "cloudflare-durable-objects", | |
| "name": "cloudflare-worker-service-binding", |
| import type { Event } from '@sentry/core'; | ||
| import { createRunner } from '../../../runner'; | ||
|
|
||
| it('propagates trace from worker to worker via service binding', async ({ signal }) => { |
There was a problem hiding this comment.
m: this checks that we get one span for each service, should we also check that they share a trace id to test that trace propagation works correctly? else the test name should probably be updated
There was a problem hiding this comment.
True, I actually had the correct implementation already working and outsourced this PR. Will remove.
d9527f4 to
b472de2
Compare


This adds tests for multi worker in integration tests by adding a
wrangler-sub-worker.jsoncinto it. Everything else is then according the official Service Binding docs.So in the
worker-service-bindingsfolder there is now a test which connects "Worker A" with "Worker B". This is enabled by having "Worker B" running aswrangler-sub-worker.jsoncand "Worker A" is referencing to "Worker B" inside the normal "wrangler.jsonc". Inside "Worker A" you can then useenv.ANOTHER_WORKERto have an RPC between two workers.This will be important for the tests for #16898