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 = (
17 project: string,
18 region: string,
19 targetHttpProxyName: string,
20) =>
21 compute
22 .getRegionTargetHttpProxies({
23 project,
24 region,
25 targetHttpProxy: targetHttpProxyName,
26 })
27 .pipe(
28 Effect.as("found" as const),
29 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
30 Effect.repeat({
31 schedule: Schedule.spaced("1 second"),
32 until: (status) => status === "gone",
33 times: 10,
34 }),
35 );
36
37const resourceTail = (value: string | undefined): string => {
38 if (value === undefined || value.length === 0) return "";
39 const parts = value.split("/").filter((part) => part.length > 0);
40 return parts[parts.length - 1] ?? "";
41};
42
43test.provider(
44 "create, update, and delete a regional target http proxy",
45 (stack) =>
46 Effect.gen(function* () {
47 yield* stack.destroy();
48
49 const created = yield* stack.deploy(
50 Effect.gen(function* () {
51 const map = yield* GCP.Compute.RegionUrlMap("Web", {
52 region: "us-central1",
53 description: "https redirect",
54 defaultUrlRedirect: {
55 httpsRedirect: true,
56 hostRedirect: "example.com",
57 stripQuery: false,
58 },
59 });
60 return yield* GCP.Compute.RegionTargetHttpProxy("Proxy", {
61 region: "us-central1",
62 description: "http frontend",
63 urlMap: map.urlMapName,
64 });
65 }),
66 );
67
68 expect(created.targetHttpProxyName).toEqual(expect.any(String));
69 expect(created.region).toEqual("us-central1");
70 expect(created.description).toEqual("http frontend");
71 expect(resourceTail(created.urlMap).length).toBeGreaterThan(0);
72
73 const fetched = yield* compute.getRegionTargetHttpProxies({
74 project: created.project,
75 region: created.region,
76 targetHttpProxy: created.targetHttpProxyName,
77 });
78 expect(fetched.name).toEqual(created.targetHttpProxyName);
79 expect(resourceTail(fetched.urlMap)).toEqual(
80 resourceTail(created.urlMap),
81 );
82 expect(fetched.description).toContain("[alchemy ");
83 expect(fetched.description).toContain("http frontend");
84
85 const updated = yield* stack.deploy(
86 Effect.gen(function* () {
87 yield* GCP.Compute.RegionUrlMap("Web", {
88 region: "us-central1",
89 description: "https redirect",
90 defaultUrlRedirect: {
91 httpsRedirect: true,
92 hostRedirect: "example.com",
93 stripQuery: false,
94 },
95 });
96 const other = yield* GCP.Compute.RegionUrlMap("Other", {
97 region: "us-central1",
98 description: "alt redirect",
99 defaultUrlRedirect: {
100 httpsRedirect: true,
101 hostRedirect: "example.org",
102 stripQuery: true,
103 },
104 });
105 return yield* GCP.Compute.RegionTargetHttpProxy("Proxy", {
106 targetHttpProxyName: created.targetHttpProxyName,
107 region: "us-central1",
108 description: "http frontend",
109 urlMap: other.urlMapName,
110 });
111 }),
112 );
113
114 expect(updated.targetHttpProxyName).toEqual(created.targetHttpProxyName);
115 expect(updated.region).toEqual("us-central1");
116 expect(resourceTail(updated.urlMap)).toEqual(expect.any(String));
117
118 const refetched = yield* compute.getRegionTargetHttpProxies({
119 project: updated.project,
120 region: updated.region,
121 targetHttpProxy: updated.targetHttpProxyName,
122 });
123 expect(resourceTail(refetched.urlMap)).toEqual(
124 resourceTail(updated.urlMap),
125 );
126 expect(resourceTail(refetched.urlMap)).not.toEqual(
127 resourceTail(created.urlMap),
128 );
129
130 yield* stack.destroy();
131
132 const gone = yield* waitUntilGone(
133 created.project,
134 created.region,
135 created.targetHttpProxyName,
136 );
137 expect(gone).toEqual("gone");
138 }).pipe(logLevel),
139 { tags: ["provider:gcp", "provider:gcp:compute", "live"], timeout: 90_000 },
140);