1import * as AWS from "@/AWS";
2import { ComputeEnvironment } from "@/AWS/Batch/ComputeEnvironment.ts";
3import { JobQueue } from "@/AWS/Batch/JobQueue.ts";
4import * as Test from "@/Test/Alchemy";
5import * as batch from "@distilled.cloud/aws/batch";
6import { expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8import { BatchTestNetwork } from "./TestNetwork.ts";
9
10const { test } = Test.make({ providers: AWS.providers() });
11
12const ceName = "alchemy-test-batch-jq-ce";
13const queueName = "alchemy-test-batch-jq";
14
15const describeQueue = batch
16 .describeJobQueues({ jobQueues: [queueName] })
17 .pipe(
18 Effect.map((res) => res.jobQueues?.find((q) => q.status !== "DELETED")),
19 );
20
21const describeCe = batch
22 .describeComputeEnvironments({ computeEnvironments: [ceName] })
23 .pipe(
24 Effect.map((res) =>
25 res.computeEnvironments?.find((ce) => ce.status !== "DELETED"),
26 ),
27 );
28
29const chain = (priority?: number) =>
30 Effect.gen(function* () {
31 const network = yield* BatchTestNetwork;
32 const ce = yield* ComputeEnvironment("JqCE", {
33 computeEnvironmentName: ceName,
34 subnets: network.subnetIds,
35 securityGroupIds: network.securityGroupIds,
36 });
37 return yield* JobQueue("Queue", {
38 jobQueueName: queueName,
39 computeEnvironments: [ce.computeEnvironmentArn],
40 ...(priority !== undefined ? { priority } : {}),
41 });
42 });
43
44test.provider(
45 "chain lifecycle: CE -> queue create, update priority, ordered destroy",
46 (stack) =>
47 Effect.gen(function* () {
48 yield* stack.destroy();
49
50 // Create the CE -> queue chain.
51 const deployed = yield* stack.deploy(chain());
52 expect(deployed.jobQueueArn).toContain(`job-queue/${queueName}`);
53
54 // Out-of-band verification via distilled.
55 const created = yield* describeQueue;
56 expect(created?.status).toBe("VALID");
57 expect(created?.state).toBe("ENABLED");
58 expect(created?.priority).toBe(1);
59 expect(
60 created?.computeEnvironmentOrder?.[0]?.computeEnvironment,
61 ).toContain(`compute-environment/${ceName}`);
62
63 // Update — priority syncs in place.
64 yield* stack.deploy(chain(5));
65 const updated = yield* describeQueue;
66 expect(updated?.priority).toBe(5);
67 expect(updated?.status).toBe("VALID");
68
69 // Destroy — queue must fully drain before the CE delete succeeds
70 // (exercises the DISABLED -> wait -> delete -> wait-gone path and the
71 // CE's ComputeEnvironmentInUse retry window).
72 yield* stack.destroy();
73 expect(yield* describeQueue).toBeUndefined();
74 expect(yield* describeCe).toBeUndefined();
75 }),
76 {
77 tags: ["provider:aws", "provider:aws:batch", "provider:aws:ec2", "live"],
78 timeout: 240_000,
79 },
80);