1import * as AWS from "@/AWS";
2import { WorkGroup } from "@/AWS/Athena/WorkGroup.ts";
3import * as Provider from "@/Provider";
4import * as Test from "@/Test/Alchemy";
5import * as athena from "@distilled.cloud/aws/athena";
6import { expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8
9const { test } = Test.make({ providers: AWS.providers() });
10
11const wgName = "alchemy-test-athena-wg-lifecycle";
12
13const getWorkGroup = athena.getWorkGroup({ WorkGroup: wgName }).pipe(
14 Effect.map((res) => res.WorkGroup),
15 Effect.catchTag("WorkGroupNotFound", () => Effect.succeed(undefined)),
16);
17
18test.provider(
19 "lifecycle: create with result config, update settings, destroy",
20 (stack) =>
21 Effect.gen(function* () {
22 yield* stack.destroy();
23
24 // Create — enforced result location + a bytes-scanned guardrail.
25 const deployed = yield* stack.deploy(
26 Effect.gen(function* () {
27 return yield* WorkGroup("LifecycleWG", {
28 workGroupName: wgName,
29 outputLocation: "s3://alchemy-athena-wg-test-results/prefix/",
30 enforceWorkGroupConfiguration: true,
31 bytesScannedCutoffPerQuery: 10_000_000,
32 tags: { env: "test" },
33 });
34 }),
35 );
36 expect(deployed.workGroupArn).toContain(`workgroup/${wgName}`);
37 expect(deployed.state).toBe("ENABLED");
38
39 // Out-of-band verification via distilled.
40 const created = yield* getWorkGroup;
41 expect(created?.Name).toBe(wgName);
42 expect(created?.State).toBe("ENABLED");
43 expect(created?.Configuration?.ResultConfiguration?.OutputLocation).toBe(
44 "s3://alchemy-athena-wg-test-results/prefix/",
45 );
46 expect(created?.Configuration?.EnforceWorkGroupConfiguration).toBe(true);
47 expect(created?.Configuration?.BytesScannedCutoffPerQuery).toBe(
48 10_000_000,
49 );
50
51 // Tags applied.
52 const tags = yield* athena.listTagsForResource({
53 ResourceARN: deployed.workGroupArn,
54 });
55 expect(
56 tags.Tags?.some((t) => t.Key === "env" && t.Value === "test"),
57 ).toBe(true);
58
59 // Canonical list() coverage.
60 const provider = yield* Provider.findProvider(WorkGroup);
61 const all = yield* provider.list();
62 expect(all.some((wg) => wg.workGroupName === wgName)).toBe(true);
63
64 // Update — remove the cutoff, disable, retag (in-place, no replacement).
65 yield* stack.deploy(
66 Effect.gen(function* () {
67 return yield* WorkGroup("LifecycleWG", {
68 workGroupName: wgName,
69 outputLocation: "s3://alchemy-athena-wg-test-results/prefix/",
70 enforceWorkGroupConfiguration: true,
71 state: "DISABLED",
72 tags: { env: "prod" },
73 });
74 }),
75 );
76 const updated = yield* getWorkGroup;
77 expect(updated?.State).toBe("DISABLED");
78 expect(
79 updated?.Configuration?.BytesScannedCutoffPerQuery,
80 ).toBeUndefined();
81 const updatedTags = yield* athena.listTagsForResource({
82 ResourceARN: deployed.workGroupArn,
83 });
84 expect(
85 updatedTags.Tags?.some((t) => t.Key === "env" && t.Value === "prod"),
86 ).toBe(true);
87
88 // Destroy — provider recursively deletes and it's gone.
89 yield* stack.destroy();
90 const after = yield* getWorkGroup;
91 expect(after).toBeUndefined();
92 }),
93 { tags: ["provider:aws", "provider:aws:athena", "live"], timeout: 180_000 },
94);