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 { logLevel, currentProject, waitUntilGone } from "./common.ts";
7
8const { test } = Test.make({ providers: GCP.providers() });
9
10test.provider(
11 "getProjectsLocationsImageImports on a missing import fails with a typed tag",
12 (stack) =>
13 Effect.gen(function* () {
14 const project = yield* currentProject;
15 yield* stack.destroy();
16
17 const error = yield* Effect.flip(
18 vmmigration.getProjectsLocationsImageImports({
19 name: `projects/${project}/locations/us-central1/imageImports/alchemy-missing-import`,
20 }),
21 );
22 expect(error._tag).toEqual("NotFound");
23
24 yield* stack.destroy();
25 }).pipe(logLevel),
26 {
27 tags: ["provider:gcp", "provider:gcp:vmmigration", "live"],
28 timeout: 90_000,
29 },
30);
31
32// An image import validates its source object up front (NotFound: Resource
33// "gs://.../disk.vmdk" was not found), and a project holds a single target
34// project. Set GCP_TEST_VMMIGRATION_IMAGE_URI to a gs:// VMDK to run it.
35const imageUri = process.env.GCP_TEST_VMMIGRATION_IMAGE_URI;
36
37test.provider.skipIf(!imageUri)(
38 "create, update, and delete a vm migration image import",
39 (stack) =>
40 Effect.gen(function* () {
41 const project = yield* currentProject;
42 yield* stack.destroy();
43
44 const created = yield* stack.deploy(
45 Effect.gen(function* () {
46 const target = yield* GCP.VMMigration.Target("ImportLanding");
47 return yield* GCP.VMMigration.ImageImport("Disk", {
48 location: "us-central1",
49 cloudStorageUri: imageUri!,
50 diskImageTargetDefaults: {
51 imageName: "alchemy-imported-disk",
52 targetProject: target.name,
53 description: "imported disk",
54 labels: { env: "test" },
55 },
56 });
57 }),
58 );
59
60 expect(created.imageImportId).toEqual(expect.any(String));
61 expect(created.name).toEqual(
62 `projects/${project}/locations/us-central1/imageImports/${created.imageImportId}`,
63 );
64 expect(created.location).toEqual("us-central1");
65 expect(created.cloudStorageUri).toContain("gs://");
66 expect(created.diskImageTargetDefaults?.imageName).toEqual(
67 "alchemy-imported-disk",
68 );
69 expect(created.diskImageTargetDefaults?.labels).toMatchObject({
70 env: "test",
71 });
72
73 const fetched = yield* vmmigration.getProjectsLocationsImageImports({
74 name: created.name,
75 });
76 expect(fetched.name).toEqual(created.name);
77 expect(fetched.diskImageTargetDefaults?.labels?.env).toEqual("test");
78 expect(fetched.diskImageTargetDefaults?.description).toContain(
79 "alchemy-id=",
80 );
81
82 yield* stack.destroy();
83 const gone = yield* waitUntilGone(
84 vmmigration.getProjectsLocationsImageImports({ name: created.name }),
85 );
86 expect(gone).toEqual("gone");
87 }).pipe(logLevel),
88 {
89 tags: ["provider:gcp", "provider:gcp:vmmigration", "live"],
90 timeout: 120_000,
91 },
92);