-
Notifications
You must be signed in to change notification settings - Fork 702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Vitest testing environment for Miniflare 3 #4795
Commits on Feb 16, 2024
-
[miniflare] Add support for module fallback service
Adds a `unsafeUseModuleFallbackService` worker option and a `unsafeModuleFallbackService` shared option for using `workerd`'s module fallback service. Note `workerd` only accepts an address for fallback service configuration. This means if we wanted per-worker fallback service configuration, we'd need to start a new HTTP server for each worker that enabled it. To avoid starting additional servers, we reuse Miniflare's existing loopback server, and allow each worker to enable/disable the fallback service instead.
Configuration menu - View commit details
-
Copy full SHA for ebaac19 - Browse repository at this point
Copy the full SHA ebaac19View commit details -
[miniflare] Return
Response
fromfetch()
if socket upgrade failedPreviously, Miniflare would throw an error if the `Upgrade: websocket` header was set, but a non-WebSocket response was returned. This change ensures the response is returned, just without `webSocket` set. This allows the caller to handle the error case/response themselves.
Configuration menu - View commit details
-
Copy full SHA for 74e5e04 - Browse repository at this point
Copy the full SHA 74e5e04View commit details -
MVP for
@cloudflare/vitest-pool-workers
Implements a basic Vitest pool that runs tests inside `workerd`, using the module fallback service and a test runner Durable Object. Provides access to bindings via `env` from the `cloudflare:test` module. Closes DEVX-1052 and DEVX-1053
Configuration menu - View commit details
-
Copy full SHA for f34e1f6 - Browse repository at this point
Copy the full SHA f34e1f6View commit details -
Implement workspace/test file worker isolation
Adds a `singleWorker` option for running all a project's test files serially in the same worker. This can speed up execution if the project contains lots of small test files, as Vitest only needs to be initialised once.
Configuration menu - View commit details
-
Copy full SHA for af38049 - Browse repository at this point
Copy the full SHA af38049View commit details -
Add Durable Object test helpers and support for self-service bindings
Adds a `runInDurableObject()` test helper for running arbitrary code inside a Durable Object's I/O context, and a `runDurableObjectAlarm()` helper for running a Durable Object's scheduled alarms. These require the new `main` option to be set to the worker's entrypoint, so the Vitest pool can create instances of the user's Durable Objects. The `main` option also allows service bindings to be declared to the worker running the tests. Events dispatched to these service bindings will use the handler exported by the `main` worker. Closes DEVX-1056, DEVX-1057 and DEVX-1058
Configuration menu - View commit details
-
Copy full SHA for 1c17102 - Browse repository at this point
Copy the full SHA 1c17102View commit details -
Add support for fetch mocking with
undici
MockAgent
Adds `fetchMock` to the `cloudflare:test` module. This is an instance of `undici`'s `MockAgent`, and can be used to mock global `fetch()` requests in the test worker. This works by bundling just the `undici` `MockAgent` code, with a customisable `Dispatcher` that is set to the original workers `fetch()` function in the pool. Closes DEVX-1059
Configuration menu - View commit details
-
Copy full SHA for c1bc6e6 - Browse repository at this point
Copy the full SHA c1bc6e6View commit details -
Use custom test runner and reset fetch mock at the start of each file
A custom test runner allows us to hook into test execution. Specifically, this allows us to run code before and after files/suites/tests are executed. We'll need this for isolated storage.
Configuration menu - View commit details
-
Copy full SHA for ceeb5d6 - Browse repository at this point
Copy the full SHA ceeb5d6View commit details -
Add (inline) snapshot support and fix source maps
By default, Vitest uses the `node:fs` module for reading/writing snapshots. This isn't available in workers, so this change implements a custom snapshot client using service bindings. Closes DEVX-1054
Configuration menu - View commit details
-
Copy full SHA for 11e2f7e - Browse repository at this point
Copy the full SHA 11e2f7eView commit details -
Configuration menu - View commit details
-
Copy full SHA for d2eacd6 - Browse repository at this point
Copy the full SHA d2eacd6View commit details -
[miniflare] Export
formatZodError
We'd like to use Zod for validating the pool's options. Miniflare has a `formatZodError` function that makes pretty error messages from Zod validation errors.
Configuration menu - View commit details
-
Copy full SHA for ab0bdfe - Browse repository at this point
Copy the full SHA ab0bdfeView commit details -
Configuration menu - View commit details
-
Copy full SHA for 82896f2 - Browse repository at this point
Copy the full SHA 82896f2View commit details -
Configuration menu - View commit details
-
Copy full SHA for 2e0282c - Browse repository at this point
Copy the full SHA 2e0282cView commit details -
Configuration menu - View commit details
-
Copy full SHA for 4b1a8bd - Browse repository at this point
Copy the full SHA 4b1a8bdView commit details -
Configuration menu - View commit details
-
Copy full SHA for ebb9d7a - Browse repository at this point
Copy the full SHA ebb9d7aView commit details -
Configuration menu - View commit details
-
Copy full SHA for 559ca97 - Browse repository at this point
Copy the full SHA 559ca97View commit details -
[miniflare] Add support for "sticky blobs" that aren't deleted
For isolated per-test storage, we'll be pushing/popping databases to a "stack". After pushing a database stack frame, we may delete a record in a test. We'd like to avoid deleting the associated blob here so when we pop the frame, the record still links up with it. This change adds an `unsafeStickyBlobs` option that disables garbage blob cleanup if enabled.
Configuration menu - View commit details
-
Copy full SHA for 0b5ba10 - Browse repository at this point
Copy the full SHA 0b5ba10View commit details -
[miniflare] Add support for getting persistence paths
Isolated storage will need access to SQLite database files. This change adds a `unsafeGetPersistPaths()` function for getting the persistence paths used by a `Miniflare` instance. This is unsafe as the layout of persistence directories is not a public interface.
Configuration menu - View commit details
-
Copy full SHA for 62647be - Browse repository at this point
Copy the full SHA 62647beView commit details -
[miniflare] Add support for colo-local ephemeral "Durable" Objects
For isolated storage, we'd like the runner object not to persist any state to disk, so we don't have to worry about excluding it when managing the storage stack. We currently have an `unsafeEphemeralDurableObjects` option that makes _all_ Durable Objects in a worker use in-memory state. This isn't suitable for our Vitest pool, as user objects will run in the same worker as the runner object. This change adds support for `workerd` "colo-local" actors. These are like Durable Objects, but don't provide any durable storage (i.e. no `state.storage` API), and have a slightly different namespace binding API.
Configuration menu - View commit details
-
Copy full SHA for 2e83fd3 - Browse repository at this point
Copy the full SHA 2e83fd3View commit details -
[miniflare] Bind
this
toMiniflare
instance in custom servicesWe'd like to extend our Vitest pool's custom loopback service with endpoints for managing isolated storage stacks. To do this, we need to know the persistence paths of the `Miniflare` instance we're currently running in. A previous commit added an `unsafeGetPersistPaths()` function. If we wanted to access these paths in the pool's loopback service, we'd need to capture the paths/`Miniflare` instance in a closure used as the service binding function. Unfortunately, we use `util.deepStrictEqual()` on Miniflare options to determine if we should restart the `Miniflare` instance. This would always return `true` if we created a new bound/arrow function on each test run. This change binds `this` to the current `Miniflare` instance when calling custom service functions, meaning we can reuse the same function when building options.
Configuration menu - View commit details
-
Copy full SHA for ff69268 - Browse repository at this point
Copy the full SHA ff69268View commit details -
Add support for isolated storage
This change adds an `isolatedStorage` pool option. If enabled, each test gets its own isolated storage environment. Storage writes in a test are automatically undone at the end of the test. The storage environment is copied from the parent suite, ensuring writes from `beforeAll()`s show up in tests. This is implemented with an on-disk stack of `.sqlite` files. Before a suite/test attempt begins, the current storage state is "pushed". When the suite/test attempt completes/fails, the state is "popped", undoing all changes. Sticky blobs are used to ensure deleting records in a test keeps the corresponding blobs around, so they can be used when the state is "popped". Closes DEVX-1055
Configuration menu - View commit details
-
Copy full SHA for 1b7d66d - Browse repository at this point
Copy the full SHA 1b7d66dView commit details -
[miniflare] Use
z.input()
for user facing options typesPreviously, we were using `z.infer()` on our option schemas to derive `WorkerOptions` and `SharedOptions` types. This gave the _output_ types for schemas, rather than the user _input_ types. Usually, these were the same. However, if a schema was `.transform()`ed, they could be different. Notably, `hyperdrives` values output objects, but accept strings, leading to type errors if these were used.
Configuration menu - View commit details
-
Copy full SHA for 797c523 - Browse repository at this point
Copy the full SHA 797c523View commit details -
Configuration menu - View commit details
-
Copy full SHA for a13d17e - Browse repository at this point
Copy the full SHA a13d17eView commit details -
Configuration menu - View commit details
-
Copy full SHA for 3e5c75f - Browse repository at this point
Copy the full SHA 3e5c75fView commit details -
Configuration menu - View commit details
-
Copy full SHA for ff0b43a - Browse repository at this point
Copy the full SHA ff0b43aView commit details -
Tidy up Node and package polyfills
Tries to remove unnecessary polyfills/functions, so users are less likely to import APIs that would be unsupported in production in their tests.
Configuration menu - View commit details
-
Copy full SHA for bc5406b - Browse repository at this point
Copy the full SHA bc5406bView commit details -
Throw actual unhandled errors in pool on failed test runs
Tunnels through the error thrown when running tests fails. This is useful for debugging, as it means the startup error thrown by Vitest includes a useful message and stack.
Configuration menu - View commit details
-
Copy full SHA for 4f63534 - Browse repository at this point
Copy the full SHA 4f63534View commit details -
Add argument validation to
cloudflare:test
Durable Object helpersWhile we expect most users to write their tests in TypeScript, JavaScript tests are also supported. Since we can't guarantee correct types at runtime, this change adds type validation to test helpers, throwing errors in the same JSG-style as other `workerd` APIs.
Configuration menu - View commit details
-
Copy full SHA for 2a20d92 - Browse repository at this point
Copy the full SHA 2a20d92View commit details -
[miniflare] Add support for
rootPath
sPreviously, Miniflare would always resolve path-valued options relative to the current working directory. For the Vitest pool, we'd like to be able to resolve these relative to the project config file. This change adds back Miniflare 2's `rootPath` option for controlling the resolution directory. `rootPath` can be set as a shared or per-worker option. Path-valued options resolve relative to the closest `rootPath`.
Configuration menu - View commit details
-
Copy full SHA for ea280dd - Browse repository at this point
Copy the full SHA ea280ddView commit details -
Configuration menu - View commit details
-
Copy full SHA for cfd3f12 - Browse repository at this point
Copy the full SHA cfd3f12View commit details -
Resolve pool Miniflare options relative to
vitest.config.ts
...rather than the current working directory. This ensures paths are always resolved to the same location when `vitest` is run in different directories.
Configuration menu - View commit details
-
Copy full SHA for e6bf2fd - Browse repository at this point
Copy the full SHA e6bf2fdView commit details -
Support injecting provided values in pool options
Vitest global setup hooks provide a good place to start auxiliary servers required by tests (e.g. upstream). This change allows provided values to be injected into the Miniflare config (e.g. using port from global setup in hyperdrive local connection string).
Configuration menu - View commit details
-
Copy full SHA for 6d159de - Browse repository at this point
Copy the full SHA 6d159deView commit details -
Support seeding data in config and reset storage between runs
This change adds a `setupEnvironment(env)` function called with a bindings proxy per-`Miniflare`-instance per-test-run. This should be used for seeding data from disk (e.g. applying D1 migrations).
Configuration menu - View commit details
-
Copy full SHA for 13d5460 - Browse repository at this point
Copy the full SHA 13d5460View commit details -
[miniflare] Fix
DurableObjectStub
detectionEnabling Durable Object JS RPC changes the class name of `DurableObjectStub` from `DurableObject` to `WorkerRpc`. This was breaking `Fetcher#fetch()` detection and WebSocket-upgrading `DurableObjectStub#fetch()`es when using the magic proxy.
Configuration menu - View commit details
-
Copy full SHA for 450ef62 - Browse repository at this point
Copy the full SHA 450ef62View commit details -
Configuration menu - View commit details
-
Copy full SHA for 28889ee - Browse repository at this point
Copy the full SHA 28889eeView commit details -
Support calling
fetch
/scheduled
/queue
handlers directlyThis change adds some new test helpers useful when importing Worker source code and calling handlers directly. Namely... - `createExecutionContext()` for creating an `ExecutionContext` - `getWaitUntil()` for waiting for all `ctx.waitUntil()` callbacks - `createScheduledController()` for creating a `scheduled` handler's `ScheduledController` - `getScheduledResult()` for getting the "no-retry" state of a `ScheduledController` - `createMessageBatch()` for creating a `queue` handler's `MessageBatch` - `getQueueResult()` for getting ack/retry state of a `MessageBatch` Note `createScheduledController()`/`getScheduledResult()` and `createMessageBatch()`/`getQueueResult()` take/return the same types as `Fetcher#scheduled()` and `Fetcher#queue()` respectively. Closes DEVX-1060
Configuration menu - View commit details
-
Copy full SHA for 6929920 - Browse repository at this point
Copy the full SHA 6929920View commit details -
Our Vitest pool runs tests inside `workerd` itself. This means we don't need to use Vitest's custom environment feature to setup the correct global scope. Modifying the global scope would result in some franken-`workerd`-environment that didn't match production. With Miniflare 2's `vitest-environment-miniflare`, we _did_ require users to enable a custom environment. Considering this is a significant difference, this change adds a very helpful error message if we detect a custom `environment` is configured.
Configuration menu - View commit details
-
Copy full SHA for 0758f9d - Browse repository at this point
Copy the full SHA 0758f9dView commit details -
Assert compatible Vitest version on startup
Our Vitest pool currently depends on internal Vitest APIs that are not protected by semantic-versioning guarantees. Therefore, this change adds a runtime sanity check for a peer-dependency version constraint on `vitest`.
Configuration menu - View commit details
-
Copy full SHA for 243ac4c - Browse repository at this point
Copy the full SHA 243ac4cView commit details -
Configuration menu - View commit details
-
Copy full SHA for a1d9218 - Browse repository at this point
Copy the full SHA a1d9218View commit details -
Configuration menu - View commit details
-
Copy full SHA for ba87434 - Browse repository at this point
Copy the full SHA ba87434View commit details -
Configuration menu - View commit details
-
Copy full SHA for 228b70c - Browse repository at this point
Copy the full SHA 228b70cView commit details -
Configuration menu - View commit details
-
Copy full SHA for b532339 - Browse repository at this point
Copy the full SHA b532339View commit details -
Configuration menu - View commit details
-
Copy full SHA for 9ce0a04 - Browse repository at this point
Copy the full SHA 9ce0a04View commit details -
[pre] Use correct project path for non-workspace projects
`WorkspaceProject#path` was actually giving the path to the directory containing the Vitest config, not the config file itself, for non-workspace projects.
Configuration menu - View commit details
-
Copy full SHA for fd16b06 - Browse repository at this point
Copy the full SHA fd16b06View commit details -
[pre] Manually construct
__dirname
s`vite-node` was transforming the pool files during development, but externalising them when the pool was depended on externally. When Vite transforms files, it automatically injects `__dirname`, even though these are ES modules, which shouldn't have this by default.
Configuration menu - View commit details
-
Copy full SHA for b6ab9ae - Browse repository at this point
Copy the full SHA b6ab9aeView commit details -
Configuration menu - View commit details
-
Copy full SHA for 34d2a2f - Browse repository at this point
Copy the full SHA 34d2a2fView commit details -
[pre] Include
cloudflare:test
types in packageThese can be referenced by adding `@cloudflare/vitest-pool-workers` to the `types` array in `tsconfig.json`.
Configuration menu - View commit details
-
Copy full SHA for e0a120f - Browse repository at this point
Copy the full SHA e0a120fView commit details -
Configuration menu - View commit details
-
Copy full SHA for 70c3382 - Browse repository at this point
Copy the full SHA 70c3382View commit details -
Configuration menu - View commit details
-
Copy full SHA for 8aa5da1 - Browse repository at this point
Copy the full SHA 8aa5da1View commit details -
Allow pool restarts on config change
Vitest will dispose of the pool and recreate it when the Vitest config changes. This was causing `Miniflare` instances to be disposed, then reused when the pool was recreated. This change moves the project cache from the module-level to a "pool-level" local variable.
Configuration menu - View commit details
-
Copy full SHA for ff47980 - Browse repository at this point
Copy the full SHA ff47980View commit details -
Configuration menu - View commit details
-
Copy full SHA for 195f15a - Browse repository at this point
Copy the full SHA 195f15aView commit details -
fixup! Add support for fetch mocking with
undici
MockAgent
Our mock agent implementation depends on `undici` internals. This change ensures we pin our version, so we don't accidentally upgrade to an incompatible version.
Configuration menu - View commit details
-
Copy full SHA for 432c521 - Browse repository at this point
Copy the full SHA 432c521View commit details -
fixup! [miniflare] Bind
this
toMiniflare
instance in custom serv……ices Switch to passing `Miniflare` instance as parameter instead of `this`
Configuration menu - View commit details
-
Copy full SHA for 1620c22 - Browse repository at this point
Copy the full SHA 1620c22View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1b65e8b - Browse repository at this point
Copy the full SHA 1b65e8bView commit details -
Configuration menu - View commit details
-
Copy full SHA for 66d4637 - Browse repository at this point
Copy the full SHA 66d4637View commit details -
Configuration menu - View commit details
-
Copy full SHA for 868d014 - Browse repository at this point
Copy the full SHA 868d014View commit details -
Configuration menu - View commit details
-
Copy full SHA for 00f23e1 - Browse repository at this point
Copy the full SHA 00f23e1View commit details -
fixup! Support seeding data in config and reset storage between runs
Rename abort-all helper worker
Configuration menu - View commit details
-
Copy full SHA for 282b2ac - Browse repository at this point
Copy the full SHA 282b2acView commit details -
Configuration menu - View commit details
-
Copy full SHA for be29c99 - Browse repository at this point
Copy the full SHA be29c99View commit details -
fixup! Tidy up Node and package polyfills
Update not-implemented messages
Configuration menu - View commit details
-
Copy full SHA for f01d851 - Browse repository at this point
Copy the full SHA f01d851View commit details -
Configuration menu - View commit details
-
Copy full SHA for f155d58 - Browse repository at this point
Copy the full SHA f155d58View commit details -
Add back support for listing Durable Objects in a namespace
Adds a `listDurableObjectIds()` test helper that behaves similarly to `getMiniflareDurableObjectIds()` from Miniflare 2's test environments.
Configuration menu - View commit details
-
Copy full SHA for 4a19ba7 - Browse repository at this point
Copy the full SHA 4a19ba7View commit details -
[miniflare] Allow
URL
s to be passed inhyperdrives
optionImportantly, this change makes the Zod output type of `hyperdrives` assignable to the input type. This means we can pass the output of parsing options schemas back to the `new Miniflare()` constructor. Also adds a few more `hyperdrives` tests to verify this doesn't change behaviour.
Configuration menu - View commit details
-
Copy full SHA for cc9c654 - Browse repository at this point
Copy the full SHA cc9c654View commit details -
Configuration menu - View commit details
-
Copy full SHA for 9103c04 - Browse repository at this point
Copy the full SHA 9103c04View commit details -
Add
SELF
export tocloudflare:test
moduleExposing `kCurrentWorker` to users for integration testing wasn't very nice. This is a common use case so this change ensures it's always bound and adds it directly to the `cloudflare:test` module.
Configuration menu - View commit details
-
Copy full SHA for 912ac78 - Browse repository at this point
Copy the full SHA 912ac78View commit details -
Replace
getWaitUntil
withwaitOnExecutionContext
andvoid
returnThis function aims to allow users to wait on side-effecting `waitUntil`s, then assert on their effects. `workerd` ignores the resolved value of `Promise`s, so exposing these may make it trickier to change the implementation of this function in the future.
Configuration menu - View commit details
-
Copy full SHA for 6206736 - Browse repository at this point
Copy the full SHA 6206736View commit details -
Remove redundant
isolateDurableObjectBindings
serialised option`durableObjectBindingDesignators` includes the same and more information, so there's no need to pass this.
Configuration menu - View commit details
-
Copy full SHA for ec70aa3 - Browse repository at this point
Copy the full SHA ec70aa3View commit details -
Fail if required compatibility flags aren't set
This makes it explicit which flags we're enabling, and helps avoid behaviour differences when running `wrangler dev` or deployed code.
Configuration menu - View commit details
-
Copy full SHA for 9891774 - Browse repository at this point
Copy the full SHA 9891774View commit details -
Configuration menu - View commit details
-
Copy full SHA for 0a65911 - Browse repository at this point
Copy the full SHA 0a65911View commit details -
fixup! Add support for isolated storage
Clarify `StackedStorageState` is per `Miniflare`-instance
Configuration menu - View commit details
-
Copy full SHA for 71e6169 - Browse repository at this point
Copy the full SHA 71e6169View commit details -
fixup! Add
SELF
export tocloudflare:test
moduleUpdate docs in `config.ts`
Configuration menu - View commit details
-
Copy full SHA for 40384a8 - Browse repository at this point
Copy the full SHA 40384a8View commit details -
Configuration menu - View commit details
-
Copy full SHA for d8be18e - Browse repository at this point
Copy the full SHA d8be18eView commit details