Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 130 additions & 70 deletions packages/wrangler/e2e/provision.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from "node:assert";
import dedent from "ts-dedent";
import { fetch } from "undici";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { afterAll, beforeEach, describe, expect, it, vi } from "vitest";
import { CLOUDFLARE_ACCOUNT_ID } from "./helpers/account-id";
import { WranglerE2ETestHelper } from "./helpers/e2e-wrangler-test";
import { fetchText } from "./helpers/fetch-text";
Expand Down Expand Up @@ -38,22 +38,26 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
expect(text).toMatchInlineSnapshot(`"Hello World!"`);
});

beforeAll(async () => {
beforeEach(async () => {
await helper.seed({
"wrangler.toml": dedent`
name = "${workerName}"
main = "src/index.ts"
compatibility_date = "2023-01-01"
name = "${workerName}"
main = "src/index.ts"
compatibility_date = "2023-01-01"

[[kv_namespaces]]
binding = "KV"
[[kv_namespaces]]
binding = "KV"

[[r2_buckets]]
binding = "R2"
[[r2_buckets]]
binding = "R2"

[[d1_databases]]
binding = "D1"
`,
[[r2_buckets]]
binding = "R2_WITH_NAME"
bucket_name = "does-not-exist"

[[d1_databases]]
binding = "D1"
`,
"src/index.ts": dedent`
export default {
fetch(request) {
Expand All @@ -75,32 +79,33 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
await worker.exitCode;
const output = await worker.output;
expect(normalize(output)).toMatchInlineSnapshot(`
"Total Upload: xx KiB / gzip: xx KiB
The following bindings need to be provisioned:
Binding Resource
env.KV KV Namespace
env.D1 D1 Database
env.R2 R2 Bucket
Provisioning KV (KV Namespace)...
🌀 Creating new KV Namespace "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-kv"...
✨ KV provisioned 🎉
Provisioning D1 (D1 Database)...
🌀 Creating new D1 Database "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-d1"...
✨ D1 provisioned 🎉
Provisioning R2 (R2 Bucket)...
🌀 Creating new R2 Bucket "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-r2"...
✨ R2 provisioned 🎉
🎉 All resources provisioned, continuing with deployment...
Your Worker has access to the following bindings:
Binding Resource
env.KV (00000000000000000000000000000000) KV Namespace
env.D1 (00000000-0000-0000-0000-000000000000) D1 Database
env.R2 (tmp-e2e-worker-00000000-0000-0000-0000-000000000000-r2) R2 Bucket
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
Current Version ID: 00000000-0000-0000-0000-000000000000"
`);
"Total Upload: xx KiB / gzip: xx KiB
The following bindings need to be provisioned:
Binding Resource
env.KV KV Namespace
env.D1 D1 Database
env.R2 R2 Bucket
Provisioning KV (KV Namespace)...
🌀 Creating new KV Namespace "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-kv"...
✨ KV provisioned 🎉
Provisioning D1 (D1 Database)...
🌀 Creating new D1 Database "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-d1"...
✨ D1 provisioned 🎉
Provisioning R2 (R2 Bucket)...
🌀 Creating new R2 Bucket "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-r2"...
✨ R2 provisioned 🎉
🎉 All resources provisioned, continuing with deployment...
Your Worker has access to the following bindings:
Binding Resource
env.KV (00000000000000000000000000000000) KV Namespace
env.D1 (00000000-0000-0000-0000-000000000000) D1 Database
env.R2 (tmp-e2e-worker-00000000-0000-0000-0000-000000000000-r2) R2 Bucket
env.R2_WITH_NAME (does-not-exist) R2 Bucket
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
Current Version ID: 00000000-0000-0000-0000-000000000000"
`);
const urlMatch = output.match(
/(?<url>https:\/\/tmp-e2e-.+?\..+?\.workers\.dev)/
);
Expand Down Expand Up @@ -129,25 +134,78 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
await worker.exitCode;
const output = await worker.output;
expect(normalize(output)).toMatchInlineSnapshot(`
"Total Upload: xx KiB / gzip: xx KiB
Your Worker has access to the following bindings:
Binding Resource
env.KV (inherited) KV Namespace
env.D1 (inherited) D1 Database
env.R2 (inherited) R2 Bucket
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
Current Version ID: 00000000-0000-0000-0000-000000000000"
`);
"Total Upload: xx KiB / gzip: xx KiB
Your Worker has access to the following bindings:
Binding Resource
env.KV (inherited) KV Namespace
env.D1 (inherited) D1 Database
env.R2 (inherited) R2 Bucket
env.R2_WITH_NAME (does-not-exist) R2 Bucket
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
Current Version ID: 00000000-0000-0000-0000-000000000000"
`);

const response = await retry(
(resp) => !resp.ok,
async () => await fetch(deployedUrl)
);
await expect(response.text()).resolves.toEqual("Hello World!");
});
it("can inspect current bindings", async () => {
const versionsRaw = await helper.run(
`wrangler versions list --json --x-provision`
);

const versions = JSON.parse(versionsRaw.stdout) as unknown[];

const latest = versions.at(-1) as { id: string };

const versionView = await helper.run(
`wrangler versions view ${latest.id} --x-provision`
);

expect(normalizeOutput(versionView.output)).toMatchInlineSnapshot(`
"Version ID: 00000000-0000-0000-0000-000000000000
Created: TIMESTAMP
Author:
Source: Unknown (version_upload)
Tag: -
Message: -
Handlers: fetch
Compatibility Date: 2023-01-01
[
{
"database_id": "00000000-0000-0000-0000-000000000000",
"id": "00000000-0000-0000-0000-000000000000",
"name": "D1",
"type": "d1"
},
{
"name": "KV",
"namespace_id": "00000000000000000000000000000000",
"type": "kv_namespace"
},
{
"bucket_name": "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-r2",
"name": "R2",
"type": "r2_bucket"
},
{
"bucket_name": "does-not-exist",
"name": "R2_WITH_NAME",
"type": "r2_bucket"
}
]
Your Worker has access to the following bindings:
Binding Resource
env.KV (00000000000000000000000000000000) KV Namespace
env.D1 (00000000-0000-0000-0000-000000000000) D1 Database
env.R2 (tmp-e2e-worker-00000000-0000-0000-0000-000000000000-r2) R2 Bucket
env.R2_WITH_NAME (does-not-exist) R2 Bucket"
`);
});
it("can inherit and provision resources on version upload", async () => {
await helper.seed({
"wrangler.toml": dedent`
Expand All @@ -167,27 +225,29 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
);
await worker.exitCode;
const output = await worker.output;
expect(normalize(output)).toMatchInlineSnapshot(`
"Total Upload: xx KiB / gzip: xx KiB
The following bindings need to be provisioned:
Binding Resource
env.KV2 KV Namespace
Provisioning KV2 (KV Namespace)...
🌀 Creating new KV Namespace "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-kv2"...
✨ KV2 provisioned 🎉
🎉 All resources provisioned, continuing with deployment...
Worker Startup Time: (TIMINGS)
Your Worker has access to the following bindings:
Binding Resource
env.KV2 (00000000000000000000000000000000) KV Namespace
env.R2 (inherited) R2 Bucket
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
Worker Version ID: 00000000-0000-0000-0000-000000000000
Version Preview URL: https://tmp-e2e-worker-PREVIEW-URL.SUBDOMAIN.workers.dev
To deploy this version to production traffic use the command wrangler versions deploy
Changes to non-versioned settings (config properties 'logpush' or 'tail_consumers') take effect after your next deployment using the command wrangler versions deploy
Changes to triggers (routes, custom domains, cron schedules, etc) must be applied with the command wrangler triggers deploy"
`);
expect(normalize(output)).toMatchInlineSnapshot(
`
"Total Upload: xx KiB / gzip: xx KiB
The following bindings need to be provisioned:
Binding Resource
env.KV2 KV Namespace
Provisioning KV2 (KV Namespace)...
🌀 Creating new KV Namespace "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-kv2"...
✨ KV2 provisioned 🎉
🎉 All resources provisioned, continuing with deployment...
Worker Startup Time: (TIMINGS)
Your Worker has access to the following bindings:
Binding Resource
env.KV2 (00000000000000000000000000000000) KV Namespace
env.R2 (inherited) R2 Bucket
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
Worker Version ID: 00000000-0000-0000-0000-000000000000
Version Preview URL: https://tmp-e2e-worker-PREVIEW-URL.SUBDOMAIN.workers.dev
To deploy this version to production traffic use the command wrangler versions deploy
Changes to non-versioned settings (config properties 'logpush' or 'tail_consumers') take effect after your next deployment using the command wrangler versions deploy
Changes to triggers (routes, custom domains, cron schedules, etc) must be applied with the command wrangler triggers deploy"
`
);
const kvMatch = output.match(/env.KV2 \((?<kv>[0-9a-f]{32})/);
assert(kvMatch?.groups);
kvId2 = kvMatch.groups.kv;
Expand Down
28 changes: 28 additions & 0 deletions packages/wrangler/src/__tests__/provision.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { readFile } from "node:fs/promises";
import { http, HttpResponse } from "msw";
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
import { mockConsoleMethods } from "./helpers/mock-console";
Expand Down Expand Up @@ -191,6 +192,7 @@ describe("--x-provision", () => {
Provisioning R2 (R2 Bucket)...
✨ R2 provisioned 🎉

Your Worker was deployed with provisioned resources. We've written the IDs of these resources to your config file, which you can choose to save or discard—either way future deploys will continue to work.
🎉 All resources provisioned, continuing with deployment...

Worker Startup Time: 100 ms
Expand Down Expand Up @@ -308,6 +310,7 @@ describe("--x-provision", () => {
Provisioning R2 (R2 Bucket)...
✨ R2 provisioned 🎉

Your Worker was deployed with provisioned resources. We've written the IDs of these resources to your config file, which you can choose to save or discard—either way future deploys will continue to work.
🎉 All resources provisioned, continuing with deployment...

Worker Startup Time: 100 ms
Expand Down Expand Up @@ -438,6 +441,7 @@ describe("--x-provision", () => {
🌀 Creating new R2 Bucket \\"new-r2\\"...
✨ R2 provisioned 🎉

Your Worker was deployed with provisioned resources. We've written the IDs of these resources to your config file, which you can choose to save or discard—either way future deploys will continue to work.
🎉 All resources provisioned, continuing with deployment...

Worker Startup Time: 100 ms
Expand All @@ -454,6 +458,26 @@ describe("--x-provision", () => {
`);
expect(std.err).toMatchInlineSnapshot(`""`);
expect(std.warn).toMatchInlineSnapshot(`""`);

// IDs should be written back to the config file
expect(await readFile("wrangler.toml", "utf-8")).toMatchInlineSnapshot(`
"compatibility_date = \\"2022-01-12\\"
name = \\"test-name\\"
main = \\"index.js\\"

[[kv_namespaces]]
binding = \\"KV\\"
id = \\"new-kv-id\\"

[[r2_buckets]]
binding = \\"R2\\"
bucket_name = \\"new-r2\\"

[[d1_databases]]
binding = \\"D1\\"
database_id = \\"new-d1-id\\"
"
`);
});

it("can prefill d1 database name from config file if provided", async () => {
Expand Down Expand Up @@ -507,6 +531,7 @@ describe("--x-provision", () => {
🌀 Creating new D1 Database \\"prefilled-d1-name\\"...
✨ D1 provisioned 🎉

Your Worker was deployed with provisioned resources. We've written the IDs of these resources to your config file, which you can choose to save or discard—either way future deploys will continue to work.
🎉 All resources provisioned, continuing with deployment...

Worker Startup Time: 100 ms
Expand Down Expand Up @@ -629,6 +654,7 @@ describe("--x-provision", () => {
🌀 Creating new D1 Database \\"new-d1-name\\"...
✨ D1 provisioned 🎉

Your Worker was deployed with provisioned resources. We've written the IDs of these resources to your config file, which you can choose to save or discard—either way future deploys will continue to work.
🎉 All resources provisioned, continuing with deployment...

Worker Startup Time: 100 ms
Expand Down Expand Up @@ -704,6 +730,7 @@ describe("--x-provision", () => {
🌀 Creating new R2 Bucket \\"prefilled-r2-name\\"...
✨ BUCKET provisioned 🎉

Your Worker was deployed with provisioned resources. We've written the IDs of these resources to your config file, which you can choose to save or discard—either way future deploys will continue to work.
🎉 All resources provisioned, continuing with deployment...

Worker Startup Time: 100 ms
Expand Down Expand Up @@ -890,6 +917,7 @@ describe("--x-provision", () => {
🌀 Creating new R2 Bucket \\"existing-bucket-name\\"...
✨ BUCKET provisioned 🎉

Your Worker was deployed with provisioned resources. We've written the IDs of these resources to your config file, which you can choose to save or discard—either way future deploys will continue to work.
🎉 All resources provisioned, continuing with deployment...

Worker Startup Time: 100 ms
Expand Down
Loading
Loading