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, zone: string, disk: string) =>
17 compute.getDisks({ project, zone, disk }).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, and delete a disk",
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.Compute.Disk("Data", {
36 zone: "us-central1-a",
37 type: "pd-standard",
38 sizeGb: 10,
39 labels: { env: "test" },
40 });
41 }),
42 );
43
44 expect(created.diskName).toEqual(expect.any(String));
45 expect(created.zone).toEqual("us-central1-a");
46 expect(created.type).toEqual("pd-standard");
47 expect(created.sizeGb).toEqual(10);
48 expect(created.status).toEqual("READY");
49 expect(created.labels).toMatchObject({ env: "test" });
50
51 const fetched = yield* compute.getDisks({
52 project: created.project,
53 zone: created.zone,
54 disk: created.diskName,
55 });
56 expect(fetched.name).toEqual(created.diskName);
57 expect(fetched.labels?.env).toEqual("test");
58 expect(fetched.sizeGb).toEqual("10");
59
60 const updated = yield* stack.deploy(
61 Effect.gen(function* () {
62 return yield* GCP.Compute.Disk("Data", {
63 diskName: created.diskName,
64 zone: "us-central1-a",
65 type: "pd-standard",
66 sizeGb: 11,
67 labels: { env: "prod", role: "data" },
68 });
69 }),
70 );
71
72 expect(updated.diskName).toEqual(created.diskName);
73 expect(updated.sizeGb).toEqual(11);
74 expect(updated.labels).toMatchObject({ env: "prod", role: "data" });
75
76 const fetchedUpdated = yield* compute.getDisks({
77 project: updated.project,
78 zone: updated.zone,
79 disk: updated.diskName,
80 });
81 expect(fetchedUpdated.sizeGb).toEqual("11");
82 expect(fetchedUpdated.labels?.env).toEqual("prod");
83 expect(fetchedUpdated.labels?.role).toEqual("data");
84
85 yield* stack.destroy();
86
87 const gone = yield* waitUntilGone(
88 created.project,
89 created.zone,
90 created.diskName,
91 );
92 expect(gone).toEqual("gone");
93 }).pipe(logLevel),
94 { tags: ["provider:gcp", "provider:gcp:compute", "live"], timeout: 90_000 },
95);