1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as dns from "@distilled.cloud/gcp/dns_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { MinimumLogLevel } from "effect/References";
7import * as Schedule from "effect/Schedule";
8
9const { test } = Test.make({ providers: GCP.providers() });
10
11const logLevel = Effect.provideService(
12 MinimumLogLevel,
13 process.env.DEBUG ? "Debug" : "Info",
14);
15
16const waitUntilGone = (project: string, zoneName: string) =>
17 dns.getManagedZones({ project, managedZone: zoneName }).pipe(
18 Effect.as("found" as const),
19 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
20 Effect.repeat({
21 schedule: Schedule.spaced("1 second"),
22 until: (status) => status === "gone",
23 times: 10,
24 }),
25 );
26
27test.provider(
28 "create, update, replace, and delete a managed zone",
29 (stack) =>
30 Effect.gen(function* () {
31 yield* stack.destroy();
32
33 const created = yield* stack.deploy(
34 Effect.gen(function* () {
35 return yield* GCP.DNS.ManagedZone("Public", {
36 description: "alchemy test zone",
37 labels: { env: "test" },
38 forceDestroy: true,
39 });
40 }),
41 );
42
43 expect(created.zoneName).toEqual(expect.any(String));
44 expect(created.dnsName).toEqual(`${created.zoneName}.alchemy-gcp-test.`);
45 expect(created.visibility).toEqual("public");
46 expect(created.description).toEqual("alchemy test zone");
47 expect(created.labels).toMatchObject({ env: "test" });
48 expect(created.enableLogging).toEqual(false);
49 expect(created.nameServers.length).toBeGreaterThan(0);
50
51 const fetched = yield* dns.getManagedZones({
52 project: created.project,
53 managedZone: created.zoneName,
54 });
55 expect(fetched.name).toEqual(created.zoneName);
56 expect(fetched.dnsName).toEqual(created.dnsName);
57 expect(fetched.labels?.env).toEqual("test");
58 expect(fetched.description).toEqual("alchemy test zone");
59
60 const updated = yield* stack.deploy(
61 Effect.gen(function* () {
62 return yield* GCP.DNS.ManagedZone("Public", {
63 zoneName: created.zoneName,
64 dnsName: created.dnsName,
65 description: "updated alchemy test zone",
66 labels: { env: "prod", role: "dns" },
67 enableLogging: true,
68 forceDestroy: true,
69 });
70 }),
71 );
72
73 expect(updated.zoneName).toEqual(created.zoneName);
74 expect(updated.dnsName).toEqual(created.dnsName);
75 expect(updated.description).toEqual("updated alchemy test zone");
76 expect(updated.labels).toMatchObject({ env: "prod", role: "dns" });
77 expect(updated.enableLogging).toEqual(true);
78
79 const fetchedUpdate = yield* dns.getManagedZones({
80 project: created.project,
81 managedZone: created.zoneName,
82 });
83 expect(fetchedUpdate.description).toEqual("updated alchemy test zone");
84 expect(fetchedUpdate.labels?.env).toEqual("prod");
85 expect(fetchedUpdate.labels?.role).toEqual("dns");
86 expect(fetchedUpdate.cloudLoggingConfig?.enableLogging).toEqual(true);
87
88 const replacedDnsName = `${created.zoneName}.alchemy-gcp-replaced.`;
89 const replaced = yield* stack.deploy(
90 Effect.gen(function* () {
91 return yield* GCP.DNS.ManagedZone("Public", {
92 zoneName: created.zoneName,
93 dnsName: replacedDnsName,
94 description: "replaced alchemy test zone",
95 labels: { env: "prod" },
96 forceDestroy: true,
97 });
98 }),
99 );
100
101 expect(replaced.zoneName).toEqual(created.zoneName);
102 expect(replaced.dnsName).toEqual(replacedDnsName);
103 expect(replaced.description).toEqual("replaced alchemy test zone");
104
105 const fetchedReplacement = yield* dns.getManagedZones({
106 project: created.project,
107 managedZone: created.zoneName,
108 });
109 expect(fetchedReplacement.dnsName).toEqual(replacedDnsName);
110
111 yield* stack.destroy();
112
113 const gone = yield* waitUntilGone(created.project, created.zoneName);
114 expect(gone).toEqual("gone");
115 }).pipe(logLevel),
116 { tags: ["provider:gcp", "provider:gcp:dns", "live"], timeout: 90_000 },
117);