From 1abe6465e7d0311b4c2a9475c7f2a29e5ee4b65e Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Tue, 8 Apr 2025 18:29:45 -0700 Subject: [PATCH] chore: update tests to be able to ran concurrently --- docs/concepts/testing.mdx | 16 ++--- examples/chat-room/tests/chat-room.test.ts | 34 ++++++----- examples/counter/tests/counter.test.ts | 17 +++--- packages/actor-core/package.json | 1 - packages/actor-core/src/test/mod.ts | 60 +++++++++++++++++-- packages/actor-core/tests/basic.test.ts | 5 +- packages/actor-core/tests/vars.test.ts | 20 +++---- packages/actor-core/vitest.config.ts | 7 +-- .../drivers/redis/tests/driver-tests.test.ts | 2 +- packages/misc/driver-test-suite/package.json | 1 - packages/misc/driver-test-suite/src/mod.ts | 2 +- .../src/tests/actor-driver.ts | 13 ++-- .../src/tests/manager-driver.ts | 38 +++++++----- packages/misc/driver-test-suite/src/utils.ts | 8 ++- .../misc/driver-test-suite/vitest.config.ts | 19 +++--- .../platforms/cloudflare-workers/package.json | 1 - .../tests/driver-tests.test.ts | 19 +++--- .../cloudflare-workers/vitest.config.ts | 7 +-- vitest.base.ts | 12 ++++ yarn.lock | 13 ++-- 20 files changed, 180 insertions(+), 115 deletions(-) create mode 100644 vitest.base.ts diff --git a/docs/concepts/testing.mdx b/docs/concepts/testing.mdx index f55e775ff..5f749afec 100644 --- a/docs/concepts/testing.mdx +++ b/docs/concepts/testing.mdx @@ -27,8 +27,8 @@ import { test, expect } from "vitest"; import { setupTest } from "actor-core/test"; import { app } from "../src/index"; -test("my actor test", async () => { - const { client } = await setupTest(app); +test("my actor test", async (test) => { + const { client } = await setupTest(test, app); // Now you can interact with your actor through the client const myActor = await client.myActor.get(); @@ -76,8 +76,8 @@ import { test, expect } from "vitest"; import { setupTest } from "actor-core/test"; import { app } from "../src/index"; -test("actor should persist state", async () => { - const { client } = await setupTest(app); +test("actor should persist state", async (test) => { + const { client } = await setupTest(test, app); const counter = await client.counter.get(); // Initial state @@ -126,8 +126,8 @@ import { test, expect, vi } from "vitest"; import { setupTest } from "actor-core/test"; import { app } from "../src/index"; -test("actor should emit events", async () => { - const { client } = await setupTest(app); +test("actor should emit events", async (test) => { + const { client } = await setupTest(test, app); const chatRoom = await client.chatRoom.get(); // Set up event handler with a mock function @@ -182,9 +182,9 @@ import { test, expect, vi } from "vitest"; import { setupTest } from "actor-core/test"; import { app } from "../src/index"; -test("scheduled tasks should execute", async () => { +test("scheduled tasks should execute", async (test) => { // setupTest automatically configures vi.useFakeTimers() - const { client } = await setupTest(app); + const { client } = await setupTest(test, app); const scheduler = await client.scheduler.get(); // Set up a scheduled task diff --git a/examples/chat-room/tests/chat-room.test.ts b/examples/chat-room/tests/chat-room.test.ts index ed848a314..696fdaf38 100644 --- a/examples/chat-room/tests/chat-room.test.ts +++ b/examples/chat-room/tests/chat-room.test.ts @@ -2,16 +2,16 @@ import { test, expect } from "vitest"; import { setupTest } from "actor-core/test"; import { app } from "../actors/app"; -test("chat room should handle messages", async () => { - const { client } = await setupTest(app); - +test("chat room should handle messages", async (test) => { + const { client } = await setupTest(test, app); + // Connect to chat room const chatRoom = await client.chatRoom.get(); - + // Initial history should be empty const initialMessages = await chatRoom.getHistory(); expect(initialMessages).toEqual([]); - + // Test event emission let receivedUsername = ""; let receivedMessage = ""; @@ -19,38 +19,42 @@ test("chat room should handle messages", async () => { receivedUsername = username; receivedMessage = message; }); - + // Send a message const testUser = "william"; const testMessage = "All the world's a stage."; await chatRoom.sendMessage(testUser, testMessage); - + // Verify event was emitted with correct data expect(receivedUsername).toBe(testUser); expect(receivedMessage).toBe(testMessage); - + // Verify message was stored in history const updatedMessages = await chatRoom.getHistory(); expect(updatedMessages).toEqual([ - { username: testUser, message: testMessage } + { username: testUser, message: testMessage }, ]); - + // Send multiple messages and verify const users = ["romeo", "juliet", "othello"]; - const messages = ["Wherefore art thou?", "Here I am!", "The green-eyed monster."]; - + const messages = [ + "Wherefore art thou?", + "Here I am!", + "The green-eyed monster.", + ]; + for (let i = 0; i < users.length; i++) { await chatRoom.sendMessage(users[i], messages[i]); - + // Verify event emission expect(receivedUsername).toBe(users[i]); expect(receivedMessage).toBe(messages[i]); } - + // Verify all messages are in history in correct order const finalHistory = await chatRoom.getHistory(); expect(finalHistory).toEqual([ { username: testUser, message: testMessage }, - ...users.map((username, i) => ({ username, message: messages[i] })) + ...users.map((username, i) => ({ username, message: messages[i] })), ]); }); diff --git a/examples/counter/tests/counter.test.ts b/examples/counter/tests/counter.test.ts index 4c628f420..0262c3fdc 100644 --- a/examples/counter/tests/counter.test.ts +++ b/examples/counter/tests/counter.test.ts @@ -2,35 +2,34 @@ import { test, expect } from "vitest"; import { setupTest } from "actor-core/test"; import { app } from "../actors/app"; -test("it should count", async () => { - const { client } = await setupTest(app); +test("it should count", async (test) => { + const { client } = await setupTest(test, app); const counter = await client.counter.get(); - + // Test initial count expect(await counter.getCount()).toBe(0); - + // Test event emission let eventCount = -1; counter.on("newCount", (count: number) => { eventCount = count; }); - + // Test increment const incrementAmount = 5; const result = await counter.increment(incrementAmount); expect(result).toBe(incrementAmount); - + // Verify event was emitted with correct count expect(eventCount).toBe(incrementAmount); - + // Test multiple increments for (let i = 1; i <= 3; i++) { const newCount = await counter.increment(incrementAmount); expect(newCount).toBe(incrementAmount * (i + 1)); expect(eventCount).toBe(incrementAmount * (i + 1)); } - + // Verify final count expect(await counter.getCount()).toBe(incrementAmount * 4); }); - diff --git a/packages/actor-core/package.json b/packages/actor-core/package.json index b9a6e7792..2b769ef87 100644 --- a/packages/actor-core/package.json +++ b/packages/actor-core/package.json @@ -175,7 +175,6 @@ "@types/node": "^22.13.1", "@types/ws": "^8", "eventsource": "^3.0.5", - "get-port": "^7.1.0", "tsup": "^8.4.0", "typescript": "^5.7.3", "vitest": "^3.1.1", diff --git a/packages/actor-core/src/test/mod.ts b/packages/actor-core/src/test/mod.ts index c254040ce..8e9a1d0e7 100644 --- a/packages/actor-core/src/test/mod.ts +++ b/packages/actor-core/src/test/mod.ts @@ -11,9 +11,9 @@ import { TestActorDriver, } from "./driver/mod"; import { type InputConfig, ConfigSchema } from "./config"; -import { onTestFinished, vi } from "vitest"; -import getPort from "get-port"; +import { type TestContext, vi } from "vitest"; import { type Client, createClient } from "@/client/mod"; +import { createServer } from "node:net"; function createRouter( app: ActorCoreApp, @@ -93,7 +93,9 @@ export interface SetupTestResult> { }; } +// Must use `TestContext` since global hooks do not work when running concurrently export async function setupTest>( + c: TestContext, app: A, ): Promise> { vi.useFakeTimers(); @@ -109,13 +111,13 @@ export async function setupTest>( // Start server with a random port const port = await getPort(); const server = serve(app, { port }); - onTestFinished( + c.onTestFinished( async () => await new Promise((resolve) => server.close(() => resolve())), ); // Create client const client = createClient(`http://127.0.0.1:${port}`); - onTestFinished(async () => await client.dispose()); + c.onTestFinished(async () => await client.dispose()); return { client, @@ -126,3 +128,53 @@ export async function setupTest>( }, }; } + +export async function getPort(): Promise { + // Pick random port between 10000 and 65535 (avoiding well-known and registered ports) + const MIN_PORT = 10000; + const MAX_PORT = 65535; + const getRandomPort = () => + Math.floor(Math.random() * (MAX_PORT - MIN_PORT + 1)) + MIN_PORT; + + let port = getRandomPort(); + let maxAttempts = 10; + + while (maxAttempts > 0) { + try { + // Try to create a server on the port to check if it's available + const server = await new Promise((resolve, reject) => { + const server = createServer(); + + server.once("error", (err: Error & { code?: string }) => { + if (err.code === "EADDRINUSE") { + reject(new Error(`Port ${port} is in use`)); + } else { + reject(err); + } + }); + + server.once("listening", () => { + resolve(server); + }); + + server.listen(port); + }); + + // Close the server since we're just checking availability + await new Promise((resolve) => { + server.close(() => resolve()); + }); + + return port; + } catch (err) { + // If port is in use, try a different one + maxAttempts--; + if (maxAttempts <= 0) { + break; + } + port = getRandomPort(); + } + } + + throw new Error("Could not find an available port after multiple attempts"); +} diff --git a/packages/actor-core/tests/basic.test.ts b/packages/actor-core/tests/basic.test.ts index 52b8e1c8c..c390217a7 100644 --- a/packages/actor-core/tests/basic.test.ts +++ b/packages/actor-core/tests/basic.test.ts @@ -2,7 +2,7 @@ import { actor, setup } from "@/mod"; import { test } from "vitest"; import { setupTest } from "@/test/mod"; -test("basic actor setup", async () => { +test("basic actor setup", async (c) => { const counter = actor({ state: { count: 0 }, actions: { @@ -18,9 +18,8 @@ test("basic actor setup", async () => { actors: { counter }, }); - const { client } = await setupTest(app); + const { client } = await setupTest(c, app); const counterInstance = await client.counter.get(); await counterInstance.increment(1); }); - diff --git a/packages/actor-core/tests/vars.test.ts b/packages/actor-core/tests/vars.test.ts index e9f597621..f2125824b 100644 --- a/packages/actor-core/tests/vars.test.ts +++ b/packages/actor-core/tests/vars.test.ts @@ -4,7 +4,7 @@ import { setupTest } from "@/test/mod"; describe("Actor Vars", () => { describe("Static vars", () => { - test("should provide access to static vars", async () => { + test("should provide access to static vars", async (c) => { // Define actor with static vars const varActor = actor({ state: { value: 0 }, @@ -24,7 +24,7 @@ describe("Actor Vars", () => { actors: { varActor }, }); - const { client } = await setupTest(app); + const { client } = await setupTest(c, app); const instance = await client.varActor.get(); // Test accessing vars @@ -38,7 +38,7 @@ describe("Actor Vars", () => { }); describe("Deep cloning of static vars", () => { - test("should deep clone static vars between actor instances", async () => { + test("should deep clone static vars between actor instances", async (c) => { // Define actor with nested object in vars const nestedVarActor = actor({ state: { value: 0 }, @@ -69,7 +69,7 @@ describe("Actor Vars", () => { actors: { nestedVarActor }, }); - const { client } = await setupTest(app); + const { client } = await setupTest(c, app); // Create two separate instances const instance1 = await client.nestedVarActor.get({ @@ -94,7 +94,7 @@ describe("Actor Vars", () => { }); describe("createVars", () => { - test("should support dynamic vars creation", async () => { + test("should support dynamic vars creation", async (c) => { // Define actor with createVars function const dynamicVarActor = actor({ state: { value: 0 }, @@ -116,7 +116,7 @@ describe("Actor Vars", () => { actors: { dynamicVarActor }, }); - const { client } = await setupTest(app); + const { client } = await setupTest(c, app); // Create an instance const instance = await client.dynamicVarActor.get(); @@ -130,7 +130,7 @@ describe("Actor Vars", () => { expect(vars.computed).toMatch(/^Actor-\d+$/); }); - test("should create different vars for different instances", async () => { + test("should create different vars for different instances", async (c) => { // Define actor with createVars function that generates unique values const uniqueVarActor = actor({ state: { value: 0 }, @@ -151,7 +151,7 @@ describe("Actor Vars", () => { actors: { uniqueVarActor }, }); - const { client } = await setupTest(app); + const { client } = await setupTest(c, app); // Create two separate instances const instance1 = await client.uniqueVarActor.get({ @@ -171,7 +171,7 @@ describe("Actor Vars", () => { }); describe("Driver Context", () => { - test("should provide access to driver context", async () => { + test("should provide access to driver context", async (c) => { // Reset timers to avoid test timeouts vi.useRealTimers(); @@ -201,7 +201,7 @@ describe("Actor Vars", () => { }); // Set up the test - const { client } = await setupTest(app); + const { client } = await setupTest(c, app); // Create an instance const instance = await client.driverCtxActor.get(); diff --git a/packages/actor-core/vitest.config.ts b/packages/actor-core/vitest.config.ts index 64b735a2e..807e9fd0e 100644 --- a/packages/actor-core/vitest.config.ts +++ b/packages/actor-core/vitest.config.ts @@ -1,15 +1,12 @@ +import defaultConfig from "../../vitest.base.ts"; import { defineConfig } from "vitest/config"; import { resolve } from "path"; export default defineConfig({ - test: { - globals: true, - environment: "node", - }, + ...defaultConfig, resolve: { alias: { "@": resolve(__dirname, "./src"), }, }, }); - diff --git a/packages/drivers/redis/tests/driver-tests.test.ts b/packages/drivers/redis/tests/driver-tests.test.ts index e3c052abb..3a464ede0 100644 --- a/packages/drivers/redis/tests/driver-tests.test.ts +++ b/packages/drivers/redis/tests/driver-tests.test.ts @@ -8,7 +8,7 @@ import Redis from "ioredis"; import { promisify } from "node:util"; import { exec as execCallback } from "node:child_process"; import { expect, test } from "vitest"; -import getPort from "get-port"; +import { getPort } from "actor-core/test"; const exec = promisify(execCallback); diff --git a/packages/misc/driver-test-suite/package.json b/packages/misc/driver-test-suite/package.json index e42a17967..ccaf4075a 100644 --- a/packages/misc/driver-test-suite/package.json +++ b/packages/misc/driver-test-suite/package.json @@ -35,7 +35,6 @@ "@types/node": "^22.13.1", "actor-core": "workspace:*", "bundle-require": "^5.1.0", - "get-port": "^7.0.0", "vitest": "^3.1.1" } } diff --git a/packages/misc/driver-test-suite/src/mod.ts b/packages/misc/driver-test-suite/src/mod.ts index cdcdc565d..8a971da22 100644 --- a/packages/misc/driver-test-suite/src/mod.ts +++ b/packages/misc/driver-test-suite/src/mod.ts @@ -15,8 +15,8 @@ import { } from "actor-core"; import { createNodeWebSocket, type NodeWebSocket } from "@hono/node-ws"; import invariant from "invariant"; -import getPort from "get-port"; import { bundleRequire } from "bundle-require"; +import { getPort } from "actor-core/test"; export interface DriverTestConfig { /** Deploys an app and returns the connection endpoint. */ diff --git a/packages/misc/driver-test-suite/src/tests/actor-driver.ts b/packages/misc/driver-test-suite/src/tests/actor-driver.ts index aad3a03fe..65a800bd2 100644 --- a/packages/misc/driver-test-suite/src/tests/actor-driver.ts +++ b/packages/misc/driver-test-suite/src/tests/actor-driver.ts @@ -23,8 +23,9 @@ export async function waitFor( export function runActorDriverTests(driverTestConfig: DriverTestConfig) { describe("Actor Driver Tests", () => { describe("State Persistence", () => { - test("persists state between actor instances", async () => { + test("persists state between actor instances", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -40,8 +41,9 @@ export function runActorDriverTests(driverTestConfig: DriverTestConfig) { expect(persistedCount).toBe(8); // 5 + 3 = 8 }); - test("maintains separate state between different actor IDs", async () => { + test("maintains separate state between different actor IDs", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -75,8 +77,9 @@ export function runActorDriverTests(driverTestConfig: DriverTestConfig) { }); describe("Actor Scheduling", () => { - test("schedules and executes tasks", async () => { + test("schedules and executes tasks", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/scheduled.ts"), ); @@ -100,8 +103,8 @@ export function runActorDriverTests(driverTestConfig: DriverTestConfig) { }); // TODO: https://github.com/rivet-gg/actor-core/issues/877 - //test("schedules multiple tasks correctly", async () => { - // const { client } = await setupDriverTest( + //test("schedules multiple tasks correctly", async (c) => { + // const { client } = await setupDriverTest(c, // driverTestConfig, // resolve(__dirname, "../fixtures/apps/scheduled.ts"), // ); diff --git a/packages/misc/driver-test-suite/src/tests/manager-driver.ts b/packages/misc/driver-test-suite/src/tests/manager-driver.ts index 2966ac988..d216583ac 100644 --- a/packages/misc/driver-test-suite/src/tests/manager-driver.ts +++ b/packages/misc/driver-test-suite/src/tests/manager-driver.ts @@ -7,8 +7,9 @@ import type { App as CounterApp } from "../../fixtures/apps/counter"; export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { describe("Manager Driver Tests", () => { describe("Client Connection Methods", () => { - test("get() - finds or creates an actor", async () => { + test("get() - finds or creates an actor", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -32,8 +33,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { expect(countB).toBe(10); }); - test("create() - always creates a new actor", async () => { + test("create() - always creates a new actor", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -82,8 +84,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { }); describe("Connection Options", () => { - test("noCreate option prevents actor creation", async () => { + test("noCreate option prevents actor creation", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -123,8 +126,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { expect(count).toBe(3); }); - test("connection params are passed to actors", async () => { + test("connection params are passed to actors", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -148,8 +152,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { }); describe("Actor Creation & Retrieval", () => { - test("creates and retrieves actors by ID", async () => { + test("creates and retrieves actors by ID", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -172,8 +177,8 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { }); // TODO: Correctly test region for each provider - //test("creates and retrieves actors with region", async () => { - // const { client } = await setupDriverTest( + //test("creates and retrieves actors with region", async (c) => { + // const { client } = await setupDriverTest(c, // driverTestConfig, // resolve(__dirname, "../fixtures/apps/counter.ts"), // ); @@ -201,8 +206,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { }); describe("Tag Matching", () => { - test("finds actors with equal or superset of specified tags", async () => { + test("finds actors with equal or superset of specified tags", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -235,8 +241,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { expect(singleTagCount).toBe(10); }); - test("no tags match actors with tags", async () => { + test("no tags match actors with tags", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -255,8 +262,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { expect(count).toBe(15); }); - test("actors with tags match actors with no tags", async () => { + test("actors with tags match actors with no tags", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -275,8 +283,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { expect(taggedCount).toBe(0); }); - test("specifying different tags for get and create results in the expected tags", async () => { + test("specifying different tags for get and create results in the expected tags", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); @@ -322,8 +331,8 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { describe("Multiple Actor Instances", () => { // TODO: This test is flakey https://github.com/rivet-gg/actor-core/issues/873 - //test("creates multiple actor instances of the same type", async () => { - // const { client } = await setupDriverTest( + //test("creates multiple actor instances of the same type", async (c) => { + // const { client } = await setupDriverTest(c, // driverTestConfig, // resolve(__dirname, "../fixtures/apps/counter.ts"), // ); @@ -361,8 +370,9 @@ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) { // expect(await retrieved3.increment(0)).toBe(3); //}); - test("handles default instance with no explicit ID", async () => { + test("handles default instance with no explicit ID", async (c) => { const { client } = await setupDriverTest( + c, driverTestConfig, resolve(__dirname, "../fixtures/apps/counter.ts"), ); diff --git a/packages/misc/driver-test-suite/src/utils.ts b/packages/misc/driver-test-suite/src/utils.ts index 3ebd78a2d..671837138 100644 --- a/packages/misc/driver-test-suite/src/utils.ts +++ b/packages/misc/driver-test-suite/src/utils.ts @@ -1,9 +1,11 @@ import type { ActorCoreApp } from "actor-core"; -import { onTestFinished, vi } from "vitest"; +import { type TestContext, vi } from "vitest"; import { createClient, type Client } from "actor-core/client"; import type { DriverTestConfig } from "./mod"; +// Must use `TestContext` since global hooks do not work when running concurrently export async function setupDriverTest>( + c: TestContext, driverTestConfig: DriverTestConfig, appPath: string, ): Promise<{ @@ -15,12 +17,12 @@ export async function setupDriverTest>( // Build drivers const { endpoint, cleanup } = await driverTestConfig.start(appPath); - onTestFinished(async () => cleanup()); + c.onTestFinished(cleanup); // Create client const client = createClient(endpoint); if (!driverTestConfig.HACK_skipCleanupNet) { - onTestFinished(async () => await client.dispose()); + c.onTestFinished(async () => await client.dispose()); } return { diff --git a/packages/misc/driver-test-suite/vitest.config.ts b/packages/misc/driver-test-suite/vitest.config.ts index c5c926c2b..3e3d05481 100644 --- a/packages/misc/driver-test-suite/vitest.config.ts +++ b/packages/misc/driver-test-suite/vitest.config.ts @@ -1,14 +1,13 @@ +import defaultConfig from "../../../vitest.base.ts"; import { defineConfig } from "vitest/config"; import { resolve } from "path"; export default defineConfig({ - test: { - globals: true, - environment: "node", - }, - resolve: { - alias: { - "@": resolve(__dirname, "./src"), - }, - }, -}); \ No newline at end of file + ...defaultConfig, + resolve: { + alias: { + "@": resolve(__dirname, "./src"), + }, + }, +}); + diff --git a/packages/platforms/cloudflare-workers/package.json b/packages/platforms/cloudflare-workers/package.json index f7aa94461..548370222 100644 --- a/packages/platforms/cloudflare-workers/package.json +++ b/packages/platforms/cloudflare-workers/package.json @@ -34,7 +34,6 @@ "@cloudflare/workers-types": "^4.20250129.0", "@types/invariant": "^2", "actor-core": "workspace:*", - "get-port": "^7.0.0", "tsup": "^8.4.0", "typescript": "^5.5.2", "vitest": "^3.1.1", diff --git a/packages/platforms/cloudflare-workers/tests/driver-tests.test.ts b/packages/platforms/cloudflare-workers/tests/driver-tests.test.ts index 2df028275..93b718933 100644 --- a/packages/platforms/cloudflare-workers/tests/driver-tests.test.ts +++ b/packages/platforms/cloudflare-workers/tests/driver-tests.test.ts @@ -4,18 +4,19 @@ import path from "node:path"; import os from "node:os"; import { spawn, exec } from "node:child_process"; import crypto from "node:crypto"; -import getPort from "get-port"; import { promisify } from "node:util"; +import { getPort } from "actor-core/test"; const execPromise = promisify(exec); // Bypass createTestRuntime by providing an endpoint directly runDriverTests({ - useRealTimers: true, + useRealTimers: true, HACK_skipCleanupNet: true, async start(appPath: string) { // Get an available port const port = await getPort(); + const inspectorPort = await getPort(); // Create a temporary directory for the test const uuid = crypto.randomUUID(); @@ -29,7 +30,7 @@ runDriverTests({ version: "1.0.0", type: "module", scripts: { - start: `wrangler@4.8.0 dev --port ${port} --local`, + start: `wrangler dev --port ${port} --inspector-port ${inspectorPort} --local`, }, dependencies: { wrangler: "4.8.0", @@ -110,14 +111,10 @@ export { handler as default, ActorHandler }; await fs.writeFile(path.join(srcDir, "index.ts"), indexContent); // Start wrangler dev - const wranglerProcess = spawn( - "npx", - ["wrangler@4.8.0", "dev", "--port", port.toString(), "--local"], - { - cwd: tmpDir, - stdio: "pipe", - }, - ); + const wranglerProcess = spawn("yarn", ["start"], { + cwd: tmpDir, + stdio: "pipe", + }); // Wait for wrangler to start await new Promise((resolve, reject) => { diff --git a/packages/platforms/cloudflare-workers/vitest.config.ts b/packages/platforms/cloudflare-workers/vitest.config.ts index 88747caae..92b6c6fa9 100644 --- a/packages/platforms/cloudflare-workers/vitest.config.ts +++ b/packages/platforms/cloudflare-workers/vitest.config.ts @@ -1,7 +1,4 @@ +import defaultConfig from "../../../vitest.base.ts"; import { defineConfig } from "vitest/config"; -export default defineConfig({ - test: { - testTimeout: 30_000, - }, -}); +export default defineConfig(defaultConfig); diff --git a/vitest.base.ts b/vitest.base.ts new file mode 100644 index 000000000..9f2d84120 --- /dev/null +++ b/vitest.base.ts @@ -0,0 +1,12 @@ +import { type ViteUserConfig } from "vitest/config"; + +export default { + test: { + // Enable parallelism + sequence: { + concurrent: true, + }, + // Increase timeout + testTimeout: 30_000, + }, +} satisfies ViteUserConfig; diff --git a/yarn.lock b/yarn.lock index 8d296b7fa..3e085f9ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -77,7 +77,6 @@ __metadata: "@cloudflare/workers-types": "npm:^4.20250129.0" "@types/invariant": "npm:^2" actor-core: "workspace:*" - get-port: "npm:^7.0.0" hono: "npm:^4.7.2" invariant: "npm:^2.2.4" tsup: "npm:^8.4.0" @@ -99,7 +98,6 @@ __metadata: "@types/node": "npm:^22.13.1" actor-core: "workspace:*" bundle-require: "npm:^5.1.0" - get-port: "npm:^7.0.0" tsup: "npm:^8.4.0" typescript: "npm:^5.7.3" vitest: "npm:^3.1.1" @@ -240,7 +238,7 @@ __metadata: esbuild: "npm:^0.25.1" lefthook: "npm:^1.6.12" turbo: "npm:^2.0.1" - vitest: "npm:^3.0.9" + vitest: "npm:^3.1.1" zx: "npm:^8.3.2" languageName: unknown linkType: soft @@ -2846,7 +2844,6 @@ __metadata: "@types/ws": "npm:^8" cbor-x: "npm:^1.6.0" eventsource: "npm:^3.0.5" - get-port: "npm:^7.1.0" hono: "npm:^4.7.0" invariant: "npm:^2.2.4" on-change: "npm:^5.0.1" @@ -3409,7 +3406,7 @@ __metadata: prompts: "npm:^2.4.2" tsx: "npm:^3.12.7" typescript: "npm:^5.5.2" - vitest: "npm:^3.0.9" + vitest: "npm:^3.1.1" languageName: unknown linkType: soft @@ -3680,7 +3677,7 @@ __metadata: actor-core: "workspace:*" tsx: "npm:^3.12.7" typescript: "npm:^5.7.3" - vitest: "npm:^3.0.9" + vitest: "npm:^3.1.1" languageName: unknown linkType: soft @@ -4572,7 +4569,7 @@ __metadata: languageName: node linkType: hard -"get-port@npm:^7.0.0, get-port@npm:^7.1.0": +"get-port@npm:^7.1.0": version: 7.1.0 resolution: "get-port@npm:7.1.0" checksum: 10c0/896051fea0fd3df58c050566754ab91f46406e898ce0c708414739d908a5ac03ffef3eca7a494ea9cc1914439e8caccd2218010d1eeabdde914b9ff920fa28fc @@ -7882,7 +7879,7 @@ __metadata: languageName: node linkType: hard -"vitest@npm:^3.0.9, vitest@npm:^3.1.1": +"vitest@npm:^3.1.1": version: 3.1.1 resolution: "vitest@npm:3.1.1" dependencies: