1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as vmmigration from "@distilled.cloud/gcp/vmmigration_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import {
7 dummyAws,
8 logLevel,
9 currentProject,
10 runSourceLifecycle,
11 waitUntilGone,
12} from "./common.ts";
13
14const { test } = Test.make({ providers: GCP.providers() });
15
16test.provider(
17 "getProjectsLocationsSourcesDiskMigrationJobs on a missing job 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 vmmigration.getProjectsLocationsSourcesDiskMigrationJobs({
25 name: `projects/${project}/locations/us-central1/sources/alchemy-missing-source/diskMigrationJobs/alchemy-missing-job`,
26 }),
27 );
28 expect(error._tag).toEqual("NotFound");
29
30 yield* stack.destroy();
31 }).pipe(logLevel),
32 {
33 tags: ["provider:gcp", "provider:gcp:vmmigration", "live"],
34 timeout: 90_000,
35 },
36);
37
38test.provider.skipIf(!runSourceLifecycle)(
39 "create, update, and delete a vm migration disk migration job",
40 (stack) =>
41 Effect.gen(function* () {
42 const project = yield* currentProject;
43 yield* stack.destroy();
44
45 const created = yield* stack.deploy(
46 Effect.gen(function* () {
47 const source = yield* GCP.VMMigration.Source("DiskSource", {
48 aws: dummyAws,
49 });
50 const target = yield* GCP.VMMigration.Target("DiskLanding");
51 return yield* GCP.VMMigration.SourcesDiskMigrationJob("Boot", {
52 source: source.name,
53 awsSourceDiskDetails: { volumeId: "vol-0123456789abcdef0" },
54 targetDetails: {
55 targetProject: target.name,
56 targetDisk: {
57 zone: `projects/${project}/locations/us-central1-a`,
58 diskType: "COMPUTE_ENGINE_DISK_TYPE_STANDARD",
59 diskId: "alchemy-imported-boot",
60 },
61 labels: { env: "test" },
62 },
63 });
64 }),
65 );
66
67 expect(created.diskMigrationJobId).toEqual(expect.any(String));
68 expect(created.name).toContain("/diskMigrationJobs/");
69 expect(created.awsSourceDiskDetails?.volumeId).toEqual(
70 "vol-0123456789abcdef0",
71 );
72 expect(created.targetDetails?.labels).toMatchObject({ env: "test" });
73
74 const fetched =
75 yield* vmmigration.getProjectsLocationsSourcesDiskMigrationJobs({
76 name: created.name,
77 });
78 expect(fetched.name).toEqual(created.name);
79 expect(fetched.targetDetails?.labels?.env).toEqual("test");
80
81 const updated = yield* stack.deploy(
82 Effect.gen(function* () {
83 const source = yield* GCP.VMMigration.Source("DiskSource", {
84 aws: dummyAws,
85 });
86 const target = yield* GCP.VMMigration.Target("DiskLanding");
87 return yield* GCP.VMMigration.SourcesDiskMigrationJob("Boot", {
88 source: source.name,
89 diskMigrationJobId: created.diskMigrationJobId,
90 awsSourceDiskDetails: { volumeId: "vol-0123456789abcdef0" },
91 targetDetails: {
92 targetProject: target.name,
93 targetDisk: {
94 zone: `projects/${project}/locations/us-central1-a`,
95 diskType: "COMPUTE_ENGINE_DISK_TYPE_SSD",
96 diskId: "alchemy-imported-boot",
97 },
98 labels: { env: "prod" },
99 },
100 });
101 }),
102 );
103
104 expect(updated.name).toEqual(created.name);
105 expect(updated.targetDetails?.labels).toMatchObject({ env: "prod" });
106
107 yield* stack.destroy();
108 const gone = yield* waitUntilGone(
109 vmmigration.getProjectsLocationsSourcesDiskMigrationJobs({
110 name: created.name,
111 }),
112 );
113 expect(gone).toEqual("gone");
114 }).pipe(logLevel),
115 {
116 tags: ["provider:gcp", "provider:gcp:vmmigration", "live"],
117 timeout: 120_000,
118 },
119);