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";
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 waitUntilGone = (license: string) =>
18 GcpEnvironment.current.pipe(
19 Effect.flatMap(({ project }) =>
20 compute.getLicenses({ project, license }).pipe(
21 Effect.as("found" as const),
22 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
23 Effect.repeat({
24 schedule: Schedule.spaced("1 second"),
25 until: (status) => status === "gone",
26 times: 10,
27 }),
28 ),
29 ),
30 );
31
32test.provider(
33 "getLicenses on a missing license fails with NotFound",
34 (stack) =>
35 Effect.gen(function* () {
36 const { project } = yield* GcpEnvironment.current;
37 yield* stack.destroy();
38
39 const error = yield* Effect.flip(
40 compute.getLicenses({
41 project,
42 license: "alchemy-missing-license",
43 }),
44 );
45 expect(error._tag).toBe("NotFound");
46
47 yield* stack.destroy();
48 }).pipe(logLevel),
49 { tags: ["provider:gcp", "provider:gcp:compute", "live"], timeout: 90_000 },
50);
51
52test.provider(
53 "create, update, and delete a license",
54 (stack) =>
55 Effect.gen(function* () {
56 yield* stack.destroy();
57
58 const created = yield* stack.deploy(
59 Effect.gen(function* () {
60 return yield* GCP.Compute.License("ImageLicense", {
61 description: "marketplace os",
62 transferable: true,
63 });
64 }),
65 );
66
67 expect(created.licenseName).toEqual(expect.any(String));
68 expect(created.description).toEqual("marketplace os");
69 expect(created.transferable).toEqual(true);
70 expect(created.selfLink).toEqual(expect.any(String));
71
72 const fetched = yield* compute.getLicenses({
73 project: created.project,
74 license: created.licenseName,
75 });
76 expect(fetched.name).toEqual(created.licenseName);
77 expect(fetched.description).toContain("[alchemy ");
78 expect(fetched.description).toContain("marketplace os");
79
80 const updated = yield* stack.deploy(
81 Effect.gen(function* () {
82 return yield* GCP.Compute.License("ImageLicense", {
83 licenseName: created.licenseName,
84 description: "marketplace os",
85 transferable: true,
86 appendableToDisk: true,
87 });
88 }),
89 );
90
91 expect(updated.licenseName).toEqual(created.licenseName);
92 expect(updated.description).toEqual("marketplace os");
93 expect(updated.appendableToDisk).toEqual(true);
94
95 const refetched = yield* compute.getLicenses({
96 project: updated.project,
97 license: updated.licenseName,
98 });
99 expect(refetched.appendableToDisk).toEqual(true);
100
101 yield* stack.destroy();
102
103 const gone = yield* waitUntilGone(created.licenseName);
104 expect(gone).toEqual("gone");
105 }).pipe(logLevel),
106 { tags: ["provider:gcp", "provider:gcp:compute", "live"], timeout: 90_000 },
107);