Skip to content
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

Merged
merged 71 commits into from
Feb 16, 2024

Commits on Feb 16, 2024

  1. [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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ebaac19 View commit details
    Browse the repository at this point in the history
  2. [miniflare] Return Response from fetch() if socket upgrade failed

    Previously, 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    74e5e04 View commit details
    Browse the repository at this point in the history
  3. 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
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    f34e1f6 View commit details
    Browse the repository at this point in the history
  4. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    af38049 View commit details
    Browse the repository at this point in the history
  5. 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
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    1c17102 View commit details
    Browse the repository at this point in the history
  6. 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
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    c1bc6e6 View commit details
    Browse the repository at this point in the history
  7. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ceeb5d6 View commit details
    Browse the repository at this point in the history
  8. 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
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    11e2f7e View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    d2eacd6 View commit details
    Browse the repository at this point in the history
  10. [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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ab0bdfe View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    82896f2 View commit details
    Browse the repository at this point in the history
  12. Bump to stable vitest@1.0.1

    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    2e0282c View commit details
    Browse the repository at this point in the history
  13. Configuration menu
    Copy the full SHA
    4b1a8bd View commit details
    Browse the repository at this point in the history
  14. Add support for fake timers

    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ebb9d7a View commit details
    Browse the repository at this point in the history
  15. Configuration menu
    Copy the full SHA
    559ca97 View commit details
    Browse the repository at this point in the history
  16. [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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    0b5ba10 View commit details
    Browse the repository at this point in the history
  17. [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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    62647be View commit details
    Browse the repository at this point in the history
  18. [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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    2e83fd3 View commit details
    Browse the repository at this point in the history
  19. [miniflare] Bind this to Miniflare instance in custom services

    We'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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ff69268 View commit details
    Browse the repository at this point in the history
  20. 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
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    1b7d66d View commit details
    Browse the repository at this point in the history
  21. [miniflare] Use z.input() for user facing options types

    Previously, 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    797c523 View commit details
    Browse the repository at this point in the history
  22. Configuration menu
    Copy the full SHA
    a13d17e View commit details
    Browse the repository at this point in the history
  23. Configuration menu
    Copy the full SHA
    3e5c75f View commit details
    Browse the repository at this point in the history
  24. Configuration menu
    Copy the full SHA
    ff0b43a View commit details
    Browse the repository at this point in the history
  25. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    bc5406b View commit details
    Browse the repository at this point in the history
  26. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    4f63534 View commit details
    Browse the repository at this point in the history
  27. Add argument validation to cloudflare:test Durable Object helpers

    While 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    2a20d92 View commit details
    Browse the repository at this point in the history
  28. [miniflare] Add support for rootPaths

    Previously, 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`.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ea280dd View commit details
    Browse the repository at this point in the history
  29. Configuration menu
    Copy the full SHA
    cfd3f12 View commit details
    Browse the repository at this point in the history
  30. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    e6bf2fd View commit details
    Browse the repository at this point in the history
  31. 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).
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    6d159de View commit details
    Browse the repository at this point in the history
  32. 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).
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    13d5460 View commit details
    Browse the repository at this point in the history
  33. [miniflare] Fix DurableObjectStub detection

    Enabling 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    450ef62 View commit details
    Browse the repository at this point in the history
  34. Bump to vitest@1.1.3

    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    28889ee View commit details
    Browse the repository at this point in the history
  35. Support calling fetch/scheduled/queue handlers directly

    This 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
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    6929920 View commit details
    Browse the repository at this point in the history
  36. Block custom environments

    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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    0758f9d View commit details
    Browse the repository at this point in the history
  37. 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`.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    243ac4c View commit details
    Browse the repository at this point in the history
  38. Configuration menu
    Copy the full SHA
    a1d9218 View commit details
    Browse the repository at this point in the history
  39. Configuration menu
    Copy the full SHA
    ba87434 View commit details
    Browse the repository at this point in the history
  40. Configuration menu
    Copy the full SHA
    228b70c View commit details
    Browse the repository at this point in the history
  41. Configuration menu
    Copy the full SHA
    b532339 View commit details
    Browse the repository at this point in the history
  42. Configuration menu
    Copy the full SHA
    9ce0a04 View commit details
    Browse the repository at this point in the history
  43. [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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    fd16b06 View commit details
    Browse the repository at this point in the history
  44. [pre] Manually construct __dirnames

    `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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    b6ab9ae View commit details
    Browse the repository at this point in the history
  45. Configuration menu
    Copy the full SHA
    34d2a2f View commit details
    Browse the repository at this point in the history
  46. [pre] Include cloudflare:test types in package

    These can be referenced by adding `@cloudflare/vitest-pool-workers` to
    the `types` array in `tsconfig.json`.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    e0a120f View commit details
    Browse the repository at this point in the history
  47. Configuration menu
    Copy the full SHA
    70c3382 View commit details
    Browse the repository at this point in the history
  48. Configuration menu
    Copy the full SHA
    8aa5da1 View commit details
    Browse the repository at this point in the history
  49. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ff47980 View commit details
    Browse the repository at this point in the history
  50. Configuration menu
    Copy the full SHA
    195f15a View commit details
    Browse the repository at this point in the history
  51. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    432c521 View commit details
    Browse the repository at this point in the history
  52. fixup! [miniflare] Bind this to Miniflare instance in custom serv…

    …ices
    
    Switch to passing `Miniflare` instance as parameter instead of `this`
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    1620c22 View commit details
    Browse the repository at this point in the history
  53. Configuration menu
    Copy the full SHA
    1b65e8b View commit details
    Browse the repository at this point in the history
  54. Configuration menu
    Copy the full SHA
    66d4637 View commit details
    Browse the repository at this point in the history
  55. Configuration menu
    Copy the full SHA
    868d014 View commit details
    Browse the repository at this point in the history
  56. Configuration menu
    Copy the full SHA
    00f23e1 View commit details
    Browse the repository at this point in the history
  57. fixup! Support seeding data in config and reset storage between runs

    Rename abort-all helper worker
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    282b2ac View commit details
    Browse the repository at this point in the history
  58. Configuration menu
    Copy the full SHA
    be29c99 View commit details
    Browse the repository at this point in the history
  59. fixup! Tidy up Node and package polyfills

    Update not-implemented messages
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    f01d851 View commit details
    Browse the repository at this point in the history
  60. Configuration menu
    Copy the full SHA
    f155d58 View commit details
    Browse the repository at this point in the history
  61. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    4a19ba7 View commit details
    Browse the repository at this point in the history
  62. [miniflare] Allow URLs to be passed in hyperdrives option

    Importantly, 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    cc9c654 View commit details
    Browse the repository at this point in the history
  63. Configuration menu
    Copy the full SHA
    9103c04 View commit details
    Browse the repository at this point in the history
  64. Add SELF export to cloudflare:test module

    Exposing `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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    912ac78 View commit details
    Browse the repository at this point in the history
  65. Replace getWaitUntil with waitOnExecutionContext and void return

    This 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    6206736 View commit details
    Browse the repository at this point in the history
  66. Remove redundant isolateDurableObjectBindings serialised option

    `durableObjectBindingDesignators` includes the same and more
    information, so there's no need to pass this.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    ec70aa3 View commit details
    Browse the repository at this point in the history
  67. 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.
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    9891774 View commit details
    Browse the repository at this point in the history
  68. Configuration menu
    Copy the full SHA
    0a65911 View commit details
    Browse the repository at this point in the history
  69. fixup! Add support for isolated storage

    Clarify `StackedStorageState` is per `Miniflare`-instance
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    71e6169 View commit details
    Browse the repository at this point in the history
  70. fixup! Add SELF export to cloudflare:test module

    Update docs in `config.ts`
    mrbbot committed Feb 16, 2024
    Configuration menu
    Copy the full SHA
    40384a8 View commit details
    Browse the repository at this point in the history
  71. Configuration menu
    Copy the full SHA
    d8be18e View commit details
    Browse the repository at this point in the history