1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as compute from "@distilled.cloud/gcp/compute_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, networkEndpointGroup: string) =>
17 compute
18 .getGlobalNetworkEndpointGroups({
19 project,
20 networkEndpointGroup,
21 })
22 .pipe(
23 Effect.as("found" as const),
24 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
25 Effect.repeat({
26 schedule: Schedule.spaced("1 second"),
27 until: (status) => status === "gone",
28 times: 10,
29 }),
30 );
31
32test.provider(
33 "create, replace, and delete a global network endpoint group",
34 (stack) =>
35 Effect.gen(function* () {
36 yield* stack.destroy();
37
38 const created = yield* stack.deploy(
39 Effect.gen(function* () {
40 return yield* GCP.Compute.GlobalNetworkEndpointGroup("Neg", {
41 networkEndpointType: "INTERNET_FQDN_PORT",
42 defaultPort: 443,
43 description: "internet neg",
44 networkEndpoints: [{ fqdn: "www.example.com", port: 443 }],
45 });
46 }),
47 );
48
49 expect(created.networkEndpointGroupName).toEqual(expect.any(String));
50 expect(created.networkEndpointType).toEqual("INTERNET_FQDN_PORT");
51 expect(created.description).toEqual("internet neg");
52 expect(created.defaultPort).toEqual(443);
53
54 const fetched = yield* compute.getGlobalNetworkEndpointGroups({
55 project: created.project,
56 networkEndpointGroup: created.networkEndpointGroupName,
57 });
58 expect(fetched.name).toEqual(created.networkEndpointGroupName);
59 expect(fetched.networkEndpointType).toEqual("INTERNET_FQDN_PORT");
60 expect(fetched.description).toContain("[alchemy ");
61 expect(fetched.description).toContain("internet neg");
62 expect(fetched.defaultPort).toEqual(443);
63 expect(fetched.size).toEqual(1);
64
65 const replaced = yield* stack.deploy(
66 Effect.gen(function* () {
67 return yield* GCP.Compute.GlobalNetworkEndpointGroup("Neg", {
68 networkEndpointGroupName: created.networkEndpointGroupName,
69 networkEndpointType: "INTERNET_FQDN_PORT",
70 defaultPort: 443,
71 description: "www backends",
72 networkEndpoints: [{ fqdn: "www.example.com", port: 443 }],
73 });
74 }),
75 );
76
77 expect(replaced.networkEndpointGroupName).toEqual(
78 created.networkEndpointGroupName,
79 );
80 expect(replaced.networkEndpointType).toEqual("INTERNET_FQDN_PORT");
81 expect(replaced.description).toEqual("www backends");
82 expect(replaced.defaultPort).toEqual(443);
83 expect(replaced.networkEndpointGroupId).not.toEqual(
84 created.networkEndpointGroupId,
85 );
86
87 const fetchedReplaced = yield* compute.getGlobalNetworkEndpointGroups({
88 project: replaced.project,
89 networkEndpointGroup: replaced.networkEndpointGroupName,
90 });
91 expect(fetchedReplaced.description).toContain("[alchemy ");
92 expect(fetchedReplaced.description).toContain("www backends");
93 expect(fetchedReplaced.defaultPort).toEqual(443);
94
95 yield* stack.destroy();
96
97 const gone = yield* waitUntilGone(
98 created.project,
99 created.networkEndpointGroupName,
100 );
101 expect(gone).toEqual("gone");
102 }).pipe(logLevel),
103 { tags: ["provider:gcp", "provider:gcp:compute", "live"], timeout: 90_000 },
104);