From 94e04c6a96e077b718f81f2b7eda26e3062c8bf4 Mon Sep 17 00:00:00 2001 From: Taesu <166604494+bytaesu@users.noreply.github.com> Date: Thu, 20 Aug 2026 11:04:38 +0000 Subject: [PATCH] test(e2e): cover concurrent async context initialization in Workerd (#10847) --- .../test/fixtures/cloudflare/package.json | 1 + .../test/fixtures/cloudflare/src/index.ts | 59 +++++++++++++++++++ .../cloudflare/test/cold-start.test.ts | 30 ++++++++++ pnpm-lock.yaml | 3 + 4 files changed, 93 insertions(+) create mode 100644 e2e/smoke/test/fixtures/cloudflare/test/cold-start.test.ts diff --git a/e2e/smoke/test/fixtures/cloudflare/package.json b/e2e/smoke/test/fixtures/cloudflare/package.json index 84c1090007..639cd13b33 100644 --- a/e2e/smoke/test/fixtures/cloudflare/package.json +++ b/e2e/smoke/test/fixtures/cloudflare/package.json @@ -2,6 +2,7 @@ "name": "@better-auth-test/fixtures-cloudflare", "private": true, "dependencies": { + "@better-auth/core": "workspace:*", "@better-auth/sso": "workspace:*", "better-auth": "workspace:*", "drizzle-orm": "^0.45.2", diff --git a/e2e/smoke/test/fixtures/cloudflare/src/index.ts b/e2e/smoke/test/fixtures/cloudflare/src/index.ts index 68b0df39ed..0a90ce8bd9 100644 --- a/e2e/smoke/test/fixtures/cloudflare/src/index.ts +++ b/e2e/smoke/test/fixtures/cloudflare/src/index.ts @@ -1,3 +1,14 @@ +import type { AuthEndpointContext } from "@better-auth/core/context"; +import { + getCurrentAdapter, + getCurrentAuthContext, + runWithEndpointContext, + runWithTransaction, +} from "@better-auth/core/context"; +import type { + DBAdapter, + DBTransactionAdapter, +} from "@better-auth/core/db/adapter"; import { sso } from "@better-auth/sso"; import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; @@ -27,6 +38,54 @@ const app = new Hono<{ }; }>(); +// Keep this before the auth middleware to test first-time async context initialization. +app.get("/async-context/concurrency", async (c) => { + const contexts = Array.from( + { length: 32 }, + () => ({}) as AuthEndpointContext, + ); + const currentContexts = await Promise.allSettled( + contexts.map((context) => + runWithEndpointContext(context, async () => { + await Promise.resolve(); + return getCurrentAuthContext(); + }), + ), + ); + + const adapters = Array.from({ length: 32 }, () => { + const transactionAdapter = {} as DBTransactionAdapter; + const adapter = { + transaction: async ( + callback: (trx: DBTransactionAdapter) => Promise, + ) => callback(transactionAdapter), + } as DBAdapter; + return { adapter, transactionAdapter }; + }); + const currentAdapters = await Promise.allSettled( + adapters.map(({ adapter }) => + runWithTransaction(adapter, async () => { + await Promise.resolve(); + return getCurrentAdapter(adapter); + }), + ), + ); + + return c.json({ + endpointContextMatches: currentContexts.filter( + (currentContext, index) => + currentContext.status === "fulfilled" && + currentContext.value === contexts[index], + ).length, + transactionAdapterMatches: currentAdapters.filter( + (currentAdapter, index) => + currentAdapter.status === "fulfilled" && + currentAdapter.value === adapters[index]?.transactionAdapter, + ).length, + total: contexts.length, + }); +}); + app.use("*", async (c, next) => { const auth = createAuth(c.env); c.set("auth", auth); diff --git a/e2e/smoke/test/fixtures/cloudflare/test/cold-start.test.ts b/e2e/smoke/test/fixtures/cloudflare/test/cold-start.test.ts new file mode 100644 index 0000000000..147159f9c2 --- /dev/null +++ b/e2e/smoke/test/fixtures/cloudflare/test/cold-start.test.ts @@ -0,0 +1,30 @@ +import { afterAll, beforeAll, expect, it } from "vitest"; +import { createTestHarness } from "wrangler"; + +const server = createTestHarness({ + workers: [{ configPath: "./wrangler.json" }], +}); + +beforeAll(async () => { + await server.listen(); +}); + +afterAll(async () => { + await server.close(); +}); + +/** + * @see https://github.com/better-auth/better-auth/issues/10832 + */ +it("preserves async contexts across concurrent first calls in the Workers runtime", async () => { + const response = await server.fetch( + "http://localhost:8787/async-context/concurrency", + ); + expect(response.status).toBe(200); + const body: unknown = await response.json(); + expect(body).toEqual({ + endpointContextMatches: 32, + transactionAdapterMatches: 32, + total: 32, + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02b47bc6c5..c0ddb15449 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -807,6 +807,9 @@ importers: e2e/smoke/test/fixtures/cloudflare: dependencies: + '@better-auth/core': + specifier: workspace:* + version: link:../../../../../packages/core '@better-auth/sso': specifier: workspace:* version: link:../../../../../packages/sso