1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as biglake from "@distilled.cloud/gcp/biglake_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { location, logLevel, currentProject, waitUntilGone } from "./common.ts";
7
8const { test } = Test.make({ providers: GCP.providers() });
9
10test.provider(
11 "getProjectsLocationsCatalogsDatabases on a missing database 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 biglake.getProjectsLocationsCatalogsDatabases({
20 name: `projects/${project}/locations/${location}/catalogs/missing/databases/alchemy-missing`,
21 }),
22 );
23 expect(error._tag).toEqual("BigLakeResourceNotFound");
24
25 yield* stack.destroy();
26 }).pipe(logLevel),
27 { tags: ["provider:gcp", "provider:gcp:biglake", "live"], timeout: 90_000 },
28);
29
30test.provider(
31 "create, update, and delete a catalog database",
32 (stack) =>
33 Effect.gen(function* () {
34 yield* stack.destroy();
35
36 const bucket = yield* stack.deploy(
37 Effect.gen(function* () {
38 return yield* GCP.Storage.Bucket("HiveMeta", {
39 location: "US-CENTRAL1",
40 forceDestroy: true,
41 });
42 }),
43 );
44
45 const created = yield* stack.deploy(
46 Effect.gen(function* () {
47 const catalog = yield* GCP.BigLake.Catalog("Lake", { location });
48 const database = yield* GCP.BigLake.CatalogsDatabase("Warehouse", {
49 catalog: catalog.name,
50 locationUri: `gs://${bucket.bucketName}/warehouse`,
51 parameters: { owner: "analytics" },
52 });
53 return { catalog, database };
54 }),
55 );
56
57 expect(created.database.name).toContain("/databases/");
58 expect(created.database.catalog).toEqual(created.catalog.name);
59 expect(created.database.type).toEqual("HIVE");
60 expect(created.database.parameters).toMatchObject({ owner: "analytics" });
61 expect(created.database.locationUri).toEqual(
62 `gs://${bucket.bucketName}/warehouse`,
63 );
64
65 const fetched = yield* biglake.getProjectsLocationsCatalogsDatabases({
66 name: created.database.name,
67 });
68 expect(fetched.name).toEqual(created.database.name);
69 expect(fetched.type).toEqual("HIVE");
70 expect(fetched.hiveOptions?.parameters?.owner).toEqual("analytics");
71 expect(fetched.hiveOptions?.parameters?.["alchemy-id"]).toEqual(
72 expect.any(String),
73 );
74
75 const updated = yield* stack.deploy(
76 Effect.gen(function* () {
77 const catalog = yield* GCP.BigLake.Catalog("Lake", {
78 catalogId: created.catalog.catalogId,
79 location,
80 });
81 const database = yield* GCP.BigLake.CatalogsDatabase("Warehouse", {
82 catalog: catalog.name,
83 databaseId: created.database.databaseId,
84 locationUri: `gs://${bucket.bucketName}/warehouse-v2`,
85 parameters: { owner: "data", env: "prod" },
86 });
87 return { catalog, database };
88 }),
89 );
90
91 expect(updated.database.name).toEqual(created.database.name);
92 expect(updated.database.locationUri).toEqual(
93 `gs://${bucket.bucketName}/warehouse-v2`,
94 );
95 expect(updated.database.parameters).toMatchObject({
96 owner: "data",
97 env: "prod",
98 });
99
100 yield* stack.destroy();
101 const gone = yield* waitUntilGone(
102 biglake.getProjectsLocationsCatalogsDatabases({
103 name: created.database.name,
104 }),
105 );
106 expect(gone).toEqual("gone");
107 }).pipe(logLevel),
108 { tags: ["provider:gcp", "provider:gcp:biglake", "live"], timeout: 120_000 },
109);