1import * as AWS from "@/AWS";
2import { EventBus } from "@/AWS/EventBridge";
3import { Discoverer } from "@/AWS/Schemas";
4import * as Test from "@/Test/Alchemy";
5import * as schemas from "@distilled.cloud/aws/schemas";
6import { describe, expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8import * as Schedule from "effect/Schedule";
9
10const { test } = Test.make({ providers: AWS.providers() });
11
12const assertDiscovererGone = (discovererId: string) =>
13 schemas.describeDiscoverer({ DiscovererId: discovererId }).pipe(
14 Effect.flatMap(() =>
15 Effect.fail(new Error(`discoverer ${discovererId} still exists`)),
16 ),
17 Effect.catchTag("NotFoundException", () => Effect.void),
18 Effect.retry({
19 while: (e) => e instanceof Error,
20 schedule: Schedule.max([
21 Schedule.fixed("2 seconds"),
22 Schedule.recurs(10),
23 ]),
24 }),
25 );
26
27describe(
28 "AWS.Schemas.Discoverer",
29 {
30 tags: [
31 "provider:aws",
32 "provider:aws:eventbridge",
33 "provider:aws:schemas",
34 "live",
35 ],
36 },
37 () => {
38 test.provider(
39 "creates a discoverer on an event bus, stops it, and deletes it",
40 (stack) =>
41 Effect.gen(function* () {
42 yield* stack.destroy();
43
44 // CREATE — discoverer on a dedicated event bus, started by default.
45 const created = yield* stack.deploy(
46 Effect.gen(function* () {
47 const bus = yield* EventBus("DiscovererBus", {});
48 const discoverer = yield* Discoverer("BusDiscoverer", {
49 sourceArn: bus.eventBusArn,
50 description: "alchemy schemas discoverer test",
51 tags: { purpose: "alchemy-test" },
52 });
53 return {
54 eventBusArn: bus.eventBusArn,
55 discovererId: discoverer.discovererId,
56 discovererArn: discoverer.discovererArn,
57 state: discoverer.state,
58 };
59 }),
60 );
61 expect(created.state).toEqual("STARTED");
62
63 // Verify out-of-band via distilled.
64 const observed = yield* schemas.describeDiscoverer({
65 DiscovererId: created.discovererId,
66 });
67 expect(observed.DiscovererArn).toEqual(created.discovererArn);
68 expect(observed.SourceArn).toEqual(created.eventBusArn);
69 expect(observed.State).toEqual("STARTED");
70 expect(observed.Description).toEqual(
71 "alchemy schemas discoverer test",
72 );
73 expect(observed.Tags?.purpose).toEqual("alchemy-test");
74 expect(observed.Tags?.["alchemy::id"]).toEqual("BusDiscoverer");
75
76 // UPDATE — stop the discoverer and change the description in place.
77 const updated = yield* stack.deploy(
78 Effect.gen(function* () {
79 const bus = yield* EventBus("DiscovererBus", {});
80 const discoverer = yield* Discoverer("BusDiscoverer", {
81 sourceArn: bus.eventBusArn,
82 description: "paused discoverer",
83 state: "STOPPED",
84 tags: { purpose: "alchemy-test" },
85 });
86 return {
87 discovererId: discoverer.discovererId,
88 state: discoverer.state,
89 };
90 }),
91 );
92 expect(updated.discovererId).toEqual(created.discovererId);
93 expect(updated.state).toEqual("STOPPED");
94
95 const afterUpdate = yield* schemas.describeDiscoverer({
96 DiscovererId: created.discovererId,
97 });
98 expect(afterUpdate.State).toEqual("STOPPED");
99 expect(afterUpdate.Description).toEqual("paused discoverer");
100
101 // DELETE
102 yield* stack.destroy();
103 yield* assertDiscovererGone(created.discovererId);
104 }),
105 { timeout: 120_000 },
106 );
107 },
108);