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