1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as datastream from "@distilled.cloud/gcp/datastream_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import {
7 LOCATION,
8 logLevel,
9 currentProject,
10 runSlowLifecycle,
11 waitUntilGone,
12} from "./common.ts";
13import { withNetworkSlot } from "../networkQuota.ts";
14
15const { test } = Test.make({ providers: GCP.providers() });
16
17test.provider(
18 "getProjectsLocationsPrivateConnectionsRoutes on a missing route fails with a typed tag",
19 (stack) =>
20 Effect.gen(function* () {
21 const project = yield* currentProject;
22 yield* stack.destroy();
23
24 const error = yield* Effect.flip(
25 datastream.getProjectsLocationsPrivateConnectionsRoutes({
26 name: `projects/${project}/locations/${LOCATION}/privateConnections/alchemy-missing-pconn/routes/alchemy-missing-route`,
27 }),
28 );
29 expect(error._tag).toEqual("NotFound");
30
31 yield* stack.destroy();
32 }).pipe(logLevel),
33 {
34 tags: ["provider:gcp", "provider:gcp:datastream", "live"],
35 timeout: 90_000,
36 },
37);
38
39test.provider.skipIf(!runSlowLifecycle)(
40 "create and delete a private connection route",
41 (stack) =>
42 Effect.gen(function* () {
43 yield* stack.destroy();
44
45 const created = yield* stack.deploy(
46 Effect.gen(function* () {
47 const network = yield* GCP.Compute.Network("DsRouteVpc", {
48 autoCreateSubnetworks: false,
49 });
50 const peering = yield* GCP.Datastream.PrivateConnection(
51 "DsRoutePeer",
52 {
53 location: LOCATION,
54 displayName: "ds-route-peer",
55 force: true,
56 vpcPeeringConfig: {
57 vpc: network.networkName,
58 subnet: "10.9.1.0/29",
59 },
60 },
61 );
62 const route = yield* GCP.Datastream.PrivateConnectionsRoute(
63 "DbHost",
64 {
65 privateConnection: peering.name,
66 location: LOCATION,
67 displayName: "db-host",
68 labels: { env: "test" },
69 destinationAddress: "10.0.0.8",
70 destinationPort: 3306,
71 },
72 );
73 return { network, peering, route };
74 }),
75 );
76
77 expect(created.route.routeId).toEqual(expect.any(String));
78 expect(created.route.name).toEqual(
79 `${created.peering.name}/routes/${created.route.routeId}`,
80 );
81 expect(created.route.privateConnection).toEqual(created.peering.name);
82 expect(created.route.displayName).toEqual("db-host");
83 expect(created.route.labels).toMatchObject({ env: "test" });
84 expect(created.route.destinationAddress).toEqual("10.0.0.8");
85 expect(created.route.destinationPort).toEqual(3306);
86
87 const fetched =
88 yield* datastream.getProjectsLocationsPrivateConnectionsRoutes({
89 name: created.route.name,
90 });
91 expect(fetched.name).toEqual(created.route.name);
92 expect(fetched.displayName).toEqual("db-host");
93 expect(fetched.destinationAddress).toEqual("10.0.0.8");
94 expect(fetched.labels?.env).toEqual("test");
95
96 yield* stack.destroy();
97 const gone = yield* waitUntilGone(
98 datastream.getProjectsLocationsPrivateConnectionsRoutes({
99 name: created.route.name,
100 }),
101 );
102 expect(gone).toEqual("gone");
103 }).pipe(logLevel, withNetworkSlot),
104 {
105 tags: ["provider:gcp", "provider:gcp:datastream", "live"],
106 timeout: 900_000,
107 },
108);