Skip to content

test(cloudflare): Enable multi-worker tests for CF integration tests#19938

Merged
JPeer264 merged 3 commits intodevelopfrom
jp/multi-worker-tests
Mar 24, 2026
Merged

test(cloudflare): Enable multi-worker tests for CF integration tests#19938
JPeer264 merged 3 commits intodevelopfrom
jp/multi-worker-tests

Conversation

@JPeer264
Copy link
Member

This adds tests for multi worker in integration tests by adding a wrangler-sub-worker.jsonc into it. Everything else is then according the official Service Binding docs.

So in the worker-service-bindings folder there is now a test which connects "Worker A" with "Worker B". This is enabled by having "Worker B" running as wrangler-sub-worker.jsonc and "Worker A" is referencing to "Worker B" inside the normal "wrangler.jsonc". Inside "Worker A" you can then use env.ANOTHER_WORKER to have an RPC between two workers.

This will be important for the tests for #16898

@JPeer264 JPeer264 requested review from nicohrubec and s1gr1d March 23, 2026 15:37
@JPeer264 JPeer264 self-assigned this Mar 23, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 23, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Deps

  • Bump mongodb-memory-server-global from 10.1.4 to 11.0.1 by dependabot in #19888
  • Bump stacktrace-parser from 0.1.10 to 0.1.11 by dependabot in #19887

Bug Fixes 🐛

Cloudflare

  • Send correct events in local development by JPeer264 in #19900
  • Forward ctx argument to Workflow.do user callback by Lms24 in #19891

Core

  • Preserve .withResponse() on Anthropic instrumentation by nicohrubec in #19935
  • Truncate content array format in Vercel by nicohrubec in #19911
  • Send internal_error as span status for Vercel error spans by nicohrubec in #19921
  • Do not overwrite user provided conversation id in Vercel by nicohrubec in #19903
  • Return same value from startSpan as callback returns by s1gr1d in #19300

Deps

  • Update lockfile to resolve h3@1.15.10 by chargome in #19933
  • Bump fast-xml-parser to 5.5.8 in @azure/core-xml chain by chargome in #19918
  • Bump next to 15.5.14 in nextjs-15 and nextjs-15-intl E2E test apps by chargome in #19917
  • Bump socket.io-parser to 4.2.6 to fix CVE-2026-33151 by chargome in #19880

Other

  • (craft) Add missing mainDocsUrl for @sentry/effect SDK by bc-sentry in #19860
  • (nestjs) Add node to nest metadata by chargome in #19875
  • (serverless) Add node to metadata by nicohrubec in #19878

Internal Changes 🔧

Deps Dev

  • Bump effect from 3.19.19 to 3.20.0 by dependabot in #19926
  • Bump qunit-dom from 3.2.1 to 3.5.0 by dependabot in #19546
  • Bump @react-router/node from 7.13.0 to 7.13.1 by dependabot in #19544

Nuxt

  • Extract core logic for storage/database to prepare for Nuxt v5 by s1gr1d in #19920
  • Extract handler patching to extra plugin for Nitro v2/v3 by s1gr1d in #19915

Other

  • (astro) Re-enable server island tracing e2e test in Astro 6 by Lms24 in #19872
  • (ci) Fix "Gatbsy" typo in issue package label workflow by chargome in #19905
  • (claude) Enable Claude Code Intelligence (LSP) by s1gr1d in #19930
  • (cloudflare) Enable multi-worker tests for CF integration tests by JPeer264 in #19938
  • (lint) Resolve oxlint warnings by isaacs in #19893
  • (node-integration-tests) Remove unnecessary file-type dependency by Lms24 in #19824
  • (remix) Replace glob with native recursive fs walk by roli-lpci in #19531
  • (sveltekit) Replace recast + @babel/parser with acorn by roli-lpci in #19533
  • Add external contributor to CHANGELOG.md by javascript-sdk-gitflow in #19925
  • Add external contributor to CHANGELOG.md by javascript-sdk-gitflow in #19909

🤖 This preview updates automatically when you update the PR.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

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.

Create PR

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.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 23, 2026

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 25.69 kB +0.2% +49 B 🔺
@sentry/browser - with treeshaking flags 24.17 kB +0.14% +33 B 🔺
@sentry/browser (incl. Tracing) 42.67 kB +0.13% +54 B 🔺
@sentry/browser (incl. Tracing, Profiling) 47.33 kB +0.12% +55 B 🔺
@sentry/browser (incl. Tracing, Replay) 81.48 kB +0.08% +57 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 71.06 kB +0.1% +69 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 86.17 kB +0.06% +50 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 98.41 kB +0.04% +36 B 🔺
@sentry/browser (incl. Feedback) 42.48 kB +0.08% +30 B 🔺
@sentry/browser (incl. sendFeedback) 30.35 kB +0.15% +43 B 🔺
@sentry/browser (incl. FeedbackAsync) 35.4 kB +0.12% +39 B 🔺
@sentry/browser (incl. Metrics) 26.96 kB +0.15% +38 B 🔺
@sentry/browser (incl. Logs) 27.1 kB +0.12% +32 B 🔺
@sentry/browser (incl. Metrics & Logs) 27.78 kB +0.15% +39 B 🔺
@sentry/react 27.45 kB +0.22% +58 B 🔺
@sentry/react (incl. Tracing) 45.01 kB +0.14% +60 B 🔺
@sentry/vue 30.13 kB +0.16% +46 B 🔺
@sentry/vue (incl. Tracing) 44.52 kB +0.09% +39 B 🔺
@sentry/svelte 25.7 kB +0.16% +40 B 🔺
CDN Bundle 28.35 kB +0.27% +75 B 🔺
CDN Bundle (incl. Tracing) 43.57 kB +0.15% +62 B 🔺
CDN Bundle (incl. Logs, Metrics) 29.22 kB +0.27% +77 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 44.43 kB +0.17% +75 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 68.29 kB +0.13% +85 B 🔺
CDN Bundle (incl. Tracing, Replay) 80.41 kB +0.1% +73 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81.31 kB +0.1% +76 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 85.97 kB +0.12% +103 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 86.86 kB +0.1% +86 B 🔺
CDN Bundle - uncompressed 82.7 kB +0.1% +77 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 128.62 kB +0.05% +64 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 85.57 kB +0.1% +77 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 131.49 kB +0.05% +64 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 209.22 kB +0.05% +102 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 245.5 kB +0.04% +89 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 248.35 kB +0.04% +89 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 258.41 kB +0.04% +89 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 261.26 kB +0.04% +89 B 🔺
@sentry/nextjs (client) 47.4 kB +0.08% +37 B 🔺
@sentry/sveltekit (client) 43.12 kB +0.12% +51 B 🔺
@sentry/node-core 56.42 kB +0.13% +73 B 🔺
@sentry/node 173.53 kB +0.22% +368 B 🔺
@sentry/node - without tracing 96.43 kB +0.1% +87 B 🔺
@sentry/aws-serverless 113.44 kB +0.1% +103 B 🔺

View base workflow run

@JPeer264 JPeer264 force-pushed the jp/multi-worker-tests branch from 22e96a0 to 25e2557 Compare March 24, 2026 07:43
@@ -0,0 +1,15 @@
{
"name": "cloudflare-durable-objects",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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 }) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I actually had the correct implementation already working and outsourced this PR. Will remove.

@JPeer264 JPeer264 force-pushed the jp/multi-worker-tests branch from d9527f4 to b472de2 Compare March 24, 2026 18:56
@JPeer264 JPeer264 enabled auto-merge (squash) March 24, 2026 18:56
@JPeer264 JPeer264 merged commit c9812ae into develop Mar 24, 2026
38 of 39 checks passed
@JPeer264 JPeer264 deleted the jp/multi-worker-tests branch March 24, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants