1import * as AWS from "@/AWS";
2import { ParameterGroup } from "@/AWS/MemoryDB";
3import * as Test from "@/Test/Alchemy";
4import * as memorydb from "@distilled.cloud/aws/memorydb";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import * as Schedule from "effect/Schedule";
8
9const { test } = Test.make({ providers: AWS.providers() });
10
11// Ungated typed-error probe: proves the distilled error union carries the
12// not-found tag this provider's read/delete paths depend on.
13test.provider(
14 "describeParameterGroups on a nonexistent group fails with ParameterGroupNotFoundFault",
15 () =>
16 Effect.gen(function* () {
17 const error = yield* Effect.flip(
18 memorydb.describeParameterGroups({
19 ParameterGroupName: "alchemy-nonexistent-memorydb-params-probe",
20 }),
21 );
22 expect(error._tag).toBe("ParameterGroupNotFoundFault");
23 }),
24 { tags: ["provider:aws", "provider:aws:memorydb", "live"] },
25);
26
27const readParameterValue = (name: string, parameter: string) =>
28 Effect.gen(function* () {
29 const page = yield* memorydb.describeParameters({
30 ParameterGroupName: name,
31 });
32 return page.Parameters?.find((p) => p.Name === parameter)?.Value;
33 });
34
35// Deleting can transiently reject while the group settles after an update.
36const assertGroupGone = (name: string) =>
37 memorydb.describeParameterGroups({ ParameterGroupName: name }).pipe(
38 Effect.flatMap(() =>
39 Effect.fail(new Error(`parameter group '${name}' still exists`)),
40 ),
41 Effect.catchTag("ParameterGroupNotFoundFault", () => Effect.void),
42 Effect.retry({
43 schedule: Schedule.max([
44 Schedule.fixed("5 seconds"),
45 Schedule.recurs(12),
46 ]),
47 }),
48 );
49
50test.provider(
51 "create parameter group, update a parameter, reset it, destroy",
52 (stack) =>
53 Effect.gen(function* () {
54 yield* stack.destroy();
55
56 // 1. Create with one override.
57 const created = yield* stack
58 .deploy(
59 Effect.gen(function* () {
60 const group = yield* ParameterGroup("Params", {
61 family: "memorydb_valkey7",
62 description: "alchemy memorydb parameter group fixture",
63 parameters: { "maxmemory-policy": "allkeys-lru" },
64 tags: { fixture: "memorydb-parameter-group" },
65 });
66 return { group };
67 }),
68 )
69 .pipe(Effect.map(({ group }) => group));
70
71 expect(created.parameterGroupName).toBeDefined();
72 expect(created.parameterGroupArn).toContain(":parametergroup/");
73 expect(created.family).toBe("memorydb_valkey7");
74
75 // Out-of-band: the override was applied.
76 const applied = yield* readParameterValue(
77 created.parameterGroupName,
78 "maxmemory-policy",
79 );
80 expect(applied).toBe("allkeys-lru");
81
82 // 2. Update the override value.
83 yield* stack.deploy(
84 Effect.gen(function* () {
85 const group = yield* ParameterGroup("Params", {
86 family: "memorydb_valkey7",
87 description: "alchemy memorydb parameter group fixture",
88 parameters: { "maxmemory-policy": "volatile-lru" },
89 tags: { fixture: "memorydb-parameter-group" },
90 });
91 return { group };
92 }),
93 );
94 const updated = yield* readParameterValue(
95 created.parameterGroupName,
96 "maxmemory-policy",
97 );
98 expect(updated).toBe("volatile-lru");
99
100 // 3. Remove the override — it resets to the engine default.
101 yield* stack.deploy(
102 Effect.gen(function* () {
103 const group = yield* ParameterGroup("Params", {
104 family: "memorydb_valkey7",
105 description: "alchemy memorydb parameter group fixture",
106 tags: { fixture: "memorydb-parameter-group" },
107 });
108 return { group };
109 }),
110 );
111 const reset = yield* readParameterValue(
112 created.parameterGroupName,
113 "maxmemory-policy",
114 );
115 expect(reset).toBe("noeviction");
116
117 // 4. Destroy and verify out-of-band it is gone.
118 yield* stack.destroy();
119 yield* assertGroupGone(created.parameterGroupName);
120 }),
121 { tags: ["provider:aws", "provider:aws:memorydb", "live"], timeout: 300_000 },
122);