1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as vmwareengine from "@distilled.cloud/gcp/vmwareengine_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { MinimumLogLevel } from "effect/References";
7import * as Schedule from "effect/Schedule";
8import { GcpEnvironment } from "@/GCP/Environment";
9
10const { test } = Test.make({ providers: GCP.providers() });
11
12const logLevel = Effect.provideService(
13 MinimumLogLevel,
14 process.env.DEBUG ? "Debug" : "Info",
15);
16
17const privateCloud = process.env.GCP_TEST_VMWAREENGINE_PRIVATE_CLOUD ?? "";
18const vpcNetworkOf = (project: string) =>
19 process.env.GCP_TEST_VMWAREENGINE_VPC_NETWORK ??
20 `projects/${project}/global/networks/default`;
21
22const runLifecycle =
23 !!process.env.GCP_TEST_VMWAREENGINE &&
24 privateCloud.length > 0 &&
25 !process.env.FAST;
26
27const waitUntilGone = (name: string) =>
28 vmwareengine
29 .getProjectsLocationsPrivateCloudsManagementDnsZoneBindings({ name })
30 .pipe(
31 Effect.as("found" as const),
32 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
33 Effect.repeat({
34 schedule: Schedule.spaced("2 seconds"),
35 until: (status) => status === "gone",
36 times: 10,
37 }),
38 );
39
40test.provider(
41 "getProjectsLocationsPrivateCloudsManagementDnsZoneBindings on a missing binding fails with a typed tag",
42 (stack) =>
43 Effect.gen(function* () {
44 const { project } = yield* GcpEnvironment.current;
45
46 yield* stack.destroy();
47
48 const error = yield* Effect.flip(
49 vmwareengine.getProjectsLocationsPrivateCloudsManagementDnsZoneBindings(
50 {
51 name: `projects/${project}/locations/us-central1-a/privateClouds/alchemy-pc-missing/managementDnsZoneBindings/alchemy-dns-missing`,
52 },
53 ),
54 );
55 expect(error._tag).toEqual("NotFound");
56
57 yield* stack.destroy();
58 }).pipe(logLevel),
59 {
60 tags: ["provider:gcp", "provider:gcp:vmwareengine", "live"],
61 timeout: 90_000,
62 },
63);
64
65test.provider.skipIf(!runLifecycle)(
66 "create, update, and delete a management dns zone binding",
67 (stack) =>
68 Effect.gen(function* () {
69 const { project } = yield* GcpEnvironment.current;
70
71 yield* stack.destroy();
72
73 const created = yield* stack.deploy(
74 Effect.gen(function* () {
75 return yield* GCP.VMwareEngine.PrivateCloudsManagementDnsZoneBinding(
76 "VpcDns",
77 {
78 privateCloud,
79 vpcNetwork: vpcNetworkOf(project),
80 description: "alchemy-test-dns",
81 },
82 );
83 }),
84 );
85
86 expect(created.name).toContain("/managementDnsZoneBindings/");
87 expect(created.privateCloud).toEqual(privateCloud.replace(/\/+$/, ""));
88 expect(created.description).toEqual("alchemy-test-dns");
89 expect(created.createTime).toEqual(expect.any(String));
90
91 const fetched =
92 yield* vmwareengine.getProjectsLocationsPrivateCloudsManagementDnsZoneBindings(
93 {
94 name: created.name,
95 },
96 );
97 expect(fetched.name).toEqual(created.name);
98 expect(fetched.description).toContain("alchemy-id=");
99 expect(fetched.description).toContain("alchemy-test-dns");
100
101 const updated = yield* stack.deploy(
102 Effect.gen(function* () {
103 return yield* GCP.VMwareEngine.PrivateCloudsManagementDnsZoneBinding(
104 "VpcDns",
105 {
106 privateCloud,
107 managementDnsZoneBindingId: created.managementDnsZoneBindingId,
108 vpcNetwork: vpcNetworkOf(project),
109 description: "alchemy-prod-dns",
110 },
111 );
112 }),
113 );
114
115 expect(updated.name).toEqual(created.name);
116 expect(updated.description).toEqual("alchemy-prod-dns");
117
118 const refetched =
119 yield* vmwareengine.getProjectsLocationsPrivateCloudsManagementDnsZoneBindings(
120 {
121 name: created.name,
122 },
123 );
124 expect(refetched.description).toContain("alchemy-prod-dns");
125 expect(refetched.description).toContain("alchemy-id=");
126
127 yield* stack.destroy();
128
129 const gone = yield* waitUntilGone(created.name);
130 expect(gone).toEqual("gone");
131 }).pipe(logLevel),
132 {
133 tags: ["provider:gcp", "provider:gcp:vmwareengine", "live"],
134 timeout: 120_000,
135 },
136);