Uh oh!
There was an error while loading. Please reload this page.
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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
size-limit report 📦
|
22e96a0 to
25e2557Compare| @@ -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
b472de2CompareUh oh!
There was an error while loading. Please reload this page.


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