1import * as AWS from "@/AWS";
2import { DBClusterParameterGroup } from "@/AWS/Neptune";
3import * as Test from "@/Test/Alchemy";
4import * as neptune from "@distilled.cloud/aws/neptune";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import * as Schedule from "effect/Schedule";
8import * as Stream from "effect/Stream";
9
10const { test } = Test.make({ providers: AWS.providers() });
11
12const assertGone = (name: string) =>
13 neptune
14 .describeDBClusterParameterGroups({ DBClusterParameterGroupName: name })
15 .pipe(
16 Effect.flatMap(() =>
17 Effect.fail(new Error(`parameter group '${name}' still exists`)),
18 ),
19 Effect.catchTag("DBParameterGroupNotFoundFault", () => Effect.void),
20 Effect.retry({
21 schedule: Schedule.max([
22 Schedule.fixed("2 seconds"),
23 Schedule.recurs(10),
24 ]),
25 }),
26 );
27
28const readUserParameters = (name: string) =>
29 neptune.describeDBClusterParameters
30 .pages({ DBClusterParameterGroupName: name, Source: "user" })
31 .pipe(
32 Stream.runCollect,
33 Effect.map((chunk) =>
34 Array.from(chunk).flatMap((page) => page.Parameters ?? []),
35 ),
36 );
37
38test.provider(
39 "create, modify parameters, reset, delete a Neptune cluster parameter group",
40 (stack) =>
41 Effect.gen(function* () {
42 yield* stack.destroy();
43
44 const { group } = yield* stack.deploy(
45 Effect.gen(function* () {
46 const group = yield* DBClusterParameterGroup("Params", {
47 family: "neptune1.4",
48 description: "alchemy neptune cluster params",
49 parameters: { neptune_query_timeout: "180000" },
50 tags: { fixture: "neptune-cluster-params" },
51 });
52 return { group };
53 }),
54 );
55
56 expect(group.dbClusterParameterGroupName).toBeDefined();
57 expect(group.dbClusterParameterGroupArn).toContain(":cluster-pg:");
58 expect(group.family).toBe("neptune1.4");
59 expect(group.parameters).toEqual({ neptune_query_timeout: "180000" });
60
61 // Out-of-band verification: the override is recorded as a user param.
62 const userParams = yield* readUserParameters(
63 group.dbClusterParameterGroupName,
64 );
65 expect(
66 userParams.find((p) => p.ParameterName === "neptune_query_timeout")
67 ?.ParameterValue,
68 ).toBe("180000");
69
70 // Update the parameter value in place.
71 const { group: updated } = yield* stack.deploy(
72 Effect.gen(function* () {
73 const group = yield* DBClusterParameterGroup("Params", {
74 family: "neptune1.4",
75 description: "alchemy neptune cluster params",
76 parameters: { neptune_query_timeout: "60000" },
77 tags: { fixture: "neptune-cluster-params" },
78 });
79 return { group };
80 }),
81 );
82 expect(updated.dbClusterParameterGroupName).toBe(
83 group.dbClusterParameterGroupName,
84 );
85 const updatedParams = yield* readUserParameters(
86 group.dbClusterParameterGroupName,
87 );
88 expect(
89 updatedParams.find((p) => p.ParameterName === "neptune_query_timeout")
90 ?.ParameterValue,
91 ).toBe("60000");
92
93 // Remove the override — the provider resets it to the engine default.
94 yield* stack.deploy(
95 Effect.gen(function* () {
96 const group = yield* DBClusterParameterGroup("Params", {
97 family: "neptune1.4",
98 description: "alchemy neptune cluster params",
99 tags: { fixture: "neptune-cluster-params" },
100 });
101 return { group };
102 }),
103 );
104 const resetParams = yield* readUserParameters(
105 group.dbClusterParameterGroupName,
106 );
107 expect(
108 resetParams.find((p) => p.ParameterName === "neptune_query_timeout"),
109 ).toBeUndefined();
110
111 yield* stack.destroy();
112 yield* assertGone(group.dbClusterParameterGroupName);
113 }),
114 { tags: ["provider:aws", "provider:aws:neptune", "live"], timeout: 240_000 },
115);