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 blueprintPackage,
11 runBlueprintLifecycle,
12 waitUntilGone,
13} from "./common.ts";
14
15const { test } = Test.make({ providers: GCP.providers() });
16
17test.provider(
18 "getProjectsLocationsUnitOperations on a missing unit operation fails with a typed tag",
19 (stack) =>
20 Effect.gen(function* () {
21 const project = yield* currentProject;
22 yield* stack.destroy();
23
24 const error = yield* Effect.flip(
25 saasservicemgmt.getProjectsLocationsUnitOperations({
26 name: `projects/${project}/locations/${location}/unitOperations/alchemy-missing-uop`,
27 }),
28 );
29 expect(error._tag).toEqual("NotFound");
30
31 yield* stack.destroy();
32 }).pipe(logLevel),
33 {
34 tags: ["provider:gcp", "provider:gcp:saasservicemgmt", "live"],
35 timeout: 90_000,
36 },
37);
38
39test.provider.skipIf(!runBlueprintLifecycle)(
40 "create, update, and delete a unit operation",
41 (stack) =>
42 Effect.gen(function* () {
43 const blueprint = blueprintPackage ?? "";
44 yield* stack.destroy();
45
46 const created = yield* stack.deploy(
47 Effect.gen(function* () {
48 const product = yield* GCP.SaasServiceManagement.Saa("Inventory", {
49 location,
50 locations: [{ name: location }],
51 });
52 const tenant = yield* GCP.SaasServiceManagement.Tenant("Acme", {
53 location,
54 saas: product.name,
55 });
56 const kind = yield* GCP.SaasServiceManagement.UnitKind("Store", {
57 location,
58 saas: product.name,
59 });
60 const release = yield* GCP.SaasServiceManagement.Release("V1", {
61 location,
62 unitKind: kind.name,
63 blueprint: { package: blueprint },
64 });
65 const unit = yield* GCP.SaasServiceManagement.Unit("Store1", {
66 location,
67 unitKind: kind.name,
68 tenant: tenant.name,
69 managementMode: "MANAGEMENT_MODE_USER",
70 });
71 const operation = yield* GCP.SaasServiceManagement.UnitOperation(
72 "Provision",
73 {
74 location,
75 unit: unit.name,
76 provision: { release: release.name },
77 labels: { env: "test" },
78 },
79 );
80 return { product, tenant, kind, release, unit, operation };
81 }),
82 );
83
84 expect(created.operation.name).toContain("/unitOperations/");
85 expect(created.operation.unitId).toEqual(created.unit.unitId);
86 expect(created.operation.labels).toMatchObject({ env: "test" });
87
88 const fetched = yield* saasservicemgmt.getProjectsLocationsUnitOperations(
89 {
90 name: created.operation.name,
91 },
92 );
93 expect(fetched.name).toEqual(created.operation.name);
94 expect(
95 Object.keys(fetched.labels ?? {}).some((key) =>
96 key.startsWith("alchemy-"),
97 ),
98 ).toEqual(true);
99
100 const updated = yield* stack.deploy(
101 Effect.gen(function* () {
102 const product = yield* GCP.SaasServiceManagement.Saa("Inventory", {
103 saasId: created.product.saasId,
104 location,
105 locations: [{ name: location }],
106 });
107 const tenant = yield* GCP.SaasServiceManagement.Tenant("Acme", {
108 tenantId: created.tenant.tenantId,
109 location,
110 saas: product.name,
111 });
112 const kind = yield* GCP.SaasServiceManagement.UnitKind("Store", {
113 unitKindId: created.kind.unitKindId,
114 location,
115 saas: product.name,
116 });
117 const release = yield* GCP.SaasServiceManagement.Release("V1", {
118 releaseId: created.release.releaseId,
119 location,
120 unitKind: kind.name,
121 blueprint: { package: blueprint },
122 });
123 const unit = yield* GCP.SaasServiceManagement.Unit("Store1", {
124 unitId: created.unit.unitId,
125 location,
126 unitKind: kind.name,
127 tenant: tenant.name,
128 managementMode: "MANAGEMENT_MODE_USER",
129 });
130 const operation = yield* GCP.SaasServiceManagement.UnitOperation(
131 "Provision",
132 {
133 unitOperationId: created.operation.unitOperationId,
134 location,
135 unit: unit.name,
136 provision: { release: release.name },
137 labels: { env: "prod" },
138 },
139 );
140 return { product, tenant, kind, release, unit, operation };
141 }),
142 );
143
144 expect(updated.operation.name).toEqual(created.operation.name);
145 expect(updated.operation.labels).toMatchObject({ env: "prod" });
146
147 yield* stack.destroy();
148 const gone = yield* waitUntilGone(
149 saasservicemgmt.getProjectsLocationsUnitOperations({
150 name: created.operation.name,
151 }),
152 );
153 expect(gone).toEqual("gone");
154 }).pipe(logLevel),
155 {
156 tags: ["provider:gcp", "provider:gcp:saasservicemgmt", "live"],
157 timeout: 90_000,
158 },
159);