1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as datamigration from "@distilled.cloud/gcp/datamigration_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { logLevel, currentProject, waitUntilGone } from "./common.ts";
7
8const { test } = Test.make({ providers: GCP.providers() });
9
10test.provider(
11 "getProjectsLocationsConversionWorkspacesMappingRules on a missing rule fails with a typed tag",
12 (stack) =>
13 Effect.gen(function* () {
14 const project = yield* currentProject;
15
16 yield* stack.destroy();
17
18 const error = yield* Effect.flip(
19 datamigration.getProjectsLocationsConversionWorkspacesMappingRules({
20 name: `projects/${project}/locations/us-central1/conversionWorkspaces/alchemy-missing-workspace/mappingRules/alchemy-missing-rule`,
21 }),
22 );
23 expect(error._tag).toEqual("NotFound");
24
25 yield* stack.destroy();
26 }).pipe(logLevel),
27 {
28 tags: ["provider:gcp", "provider:gcp:datamigration", "live"],
29 timeout: 90_000,
30 },
31);
32
33test.provider(
34 "create and delete a conversion workspace mapping rule",
35 (stack) =>
36 Effect.gen(function* () {
37 yield* stack.destroy();
38
39 const created = yield* stack.deploy(
40 Effect.gen(function* () {
41 const workspace = yield* GCP.DataMigration.ConversionWorkspace(
42 "OracleToPg",
43 {
44 location: "us-central1",
45 displayName: "rule-workspace",
46 source: { engine: "ORACLE", version: "11" },
47 destination: { engine: "POSTGRESQL", version: "14" },
48 },
49 );
50 const rule = yield* GCP.DataMigration.ConversionWorkspacesMappingRule(
51 "Rename",
52 {
53 conversionWorkspace: workspace.name,
54 location: "us-central1",
55 displayName: "rename-schema",
56 ruleScope: "DATABASE_ENTITY_TYPE_SCHEMA",
57 ruleOrder: "1000",
58 filter: { entities: ["src_schema"] },
59 singleEntityRename: { newName: "dst_schema" },
60 },
61 );
62 return { workspace, rule };
63 }),
64 );
65
66 expect(created.rule.mappingRuleId).toEqual(expect.any(String));
67 expect(created.rule.name).toEqual(
68 `${created.workspace.name}/mappingRules/${created.rule.mappingRuleId}`,
69 );
70 expect(created.rule.conversionWorkspace).toEqual(created.workspace.name);
71 expect(created.rule.displayName).toEqual("rename-schema");
72 expect(created.rule.ruleScope).toEqual("DATABASE_ENTITY_TYPE_SCHEMA");
73 expect(created.rule.singleEntityRename?.newName).toEqual("dst_schema");
74
75 const fetched =
76 yield* datamigration.getProjectsLocationsConversionWorkspacesMappingRules(
77 { name: created.rule.name },
78 );
79 // The API omits `name` from mapping rules; the fetch by name is the check.
80 expect(fetched.ruleScope).toEqual("DATABASE_ENTITY_TYPE_SCHEMA");
81 expect(fetched.displayName).toMatch(/^\[(alchemy|alc) /);
82 expect(fetched.singleEntityRename?.newName).toEqual("dst_schema");
83 expect(fetched.filter?.entities).toContain("src_schema");
84
85 yield* stack.destroy();
86 const gone = yield* waitUntilGone(
87 datamigration.getProjectsLocationsConversionWorkspacesMappingRules({
88 name: created.rule.name,
89 }),
90 );
91 expect(gone).toEqual("gone");
92 }).pipe(logLevel),
93 {
94 tags: ["provider:gcp", "provider:gcp:datamigration", "live"],
95 timeout: 90_000,
96 },
97);