1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as saasservicemgmt from "@distilled.cloud/gcp/saasservicemgmt_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import {
7 location,
8 logLevel,
9 currentProject,
10 runLifecycle,
11 waitUntilGone,
12} from "./common.ts";
13
14const { test } = Test.make({ providers: GCP.providers() });
15
16test.provider(
17 "getProjectsLocationsRolloutKinds on a missing rollout kind fails with a typed tag",
18 (stack) =>
19 Effect.gen(function* () {
20 const project = yield* currentProject;
21 yield* stack.destroy();
22
23 const error = yield* Effect.flip(
24 saasservicemgmt.getProjectsLocationsRolloutKinds({
25 name: `projects/${project}/locations/${location}/rolloutKinds/alchemy-missing-rk`,
26 }),
27 );
28 expect(error._tag).toEqual("NotFound");
29
30 yield* stack.destroy();
31 }).pipe(logLevel),
32 {
33 tags: ["provider:gcp", "provider:gcp:saasservicemgmt", "live"],
34 timeout: 90_000,
35 },
36);
37
38test.provider.skipIf(!runLifecycle)(
39 "create, update, and delete a rollout kind",
40 (stack) =>
41 Effect.gen(function* () {
42 yield* stack.destroy();
43
44 const created = yield* stack.deploy(
45 Effect.gen(function* () {
46 const product = yield* GCP.SaasServiceManagement.Saa("Inventory", {
47 location,
48 locations: [{ name: location }],
49 });
50 const kind = yield* GCP.SaasServiceManagement.UnitKind("Store", {
51 location,
52 saas: product.name,
53 });
54 const rolloutKind = yield* GCP.SaasServiceManagement.RolloutKind(
55 "Wave",
56 {
57 location,
58 unitKind: kind.name,
59 rolloutOrchestrationStrategy: "Google.Cloud.Simple.AllAtOnce",
60 labels: { env: "test" },
61 },
62 );
63 return { product, kind, rolloutKind };
64 }),
65 );
66
67 expect(created.rolloutKind.name).toContain("/rolloutKinds/");
68 expect(created.rolloutKind.unitKindId).toEqual(created.kind.unitKindId);
69 expect(created.rolloutKind.labels).toMatchObject({ env: "test" });
70
71 const fetched = yield* saasservicemgmt.getProjectsLocationsRolloutKinds({
72 name: created.rolloutKind.name,
73 });
74 expect(fetched.name).toEqual(created.rolloutKind.name);
75 expect(fetched.labels?.env).toEqual("test");
76 expect(
77 Object.keys(fetched.labels ?? {}).some((key) =>
78 key.startsWith("alchemy-"),
79 ),
80 ).toEqual(true);
81
82 const updated = yield* stack.deploy(
83 Effect.gen(function* () {
84 const product = yield* GCP.SaasServiceManagement.Saa("Inventory", {
85 saasId: created.product.saasId,
86 location,
87 locations: [{ name: location }],
88 });
89 const kind = yield* GCP.SaasServiceManagement.UnitKind("Store", {
90 unitKindId: created.kind.unitKindId,
91 location,
92 saas: product.name,
93 });
94 const rolloutKind = yield* GCP.SaasServiceManagement.RolloutKind(
95 "Wave",
96 {
97 rolloutKindId: created.rolloutKind.rolloutKindId,
98 location,
99 unitKind: kind.name,
100 rolloutOrchestrationStrategy: "Google.Cloud.Simple.AllAtOnce",
101 errorBudget: { allowedCount: 1, allowedPercentage: 10 },
102 labels: { env: "prod" },
103 },
104 );
105 return { product, kind, rolloutKind };
106 }),
107 );
108
109 expect(updated.rolloutKind.name).toEqual(created.rolloutKind.name);
110 expect(updated.rolloutKind.labels).toMatchObject({ env: "prod" });
111 expect(updated.rolloutKind.errorBudget?.allowedCount).toEqual(1);
112
113 yield* stack.destroy();
114 const gone = yield* waitUntilGone(
115 saasservicemgmt.getProjectsLocationsRolloutKinds({
116 name: created.rolloutKind.name,
117 }),
118 );
119 expect(gone).toEqual("gone");
120 }).pipe(logLevel),
121 {
122 tags: ["provider:gcp", "provider:gcp:saasservicemgmt", "live"],
123 timeout: 90_000,
124 },
125);