100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import type { ComposeSpecification, Service } from "../../schema/docker.d";
|
|
import { serviceToDeployment, volumesToPvc } from "../../lib/convert";
|
|
import { getS3UiUrl } from "../../command/s3";
|
|
import {
|
|
getComposeS3Claims,
|
|
getServiceS3Claim,
|
|
isS3VolumeEntry,
|
|
} from "../../lib/storage";
|
|
|
|
describe("managed S3 claims", () => {
|
|
test("uses the same key and bucket for the short syntax", () => {
|
|
expect(
|
|
getServiceS3Claim("app", { volumes: ["s3:assets"] } as Service),
|
|
).toEqual({ service: "app", key: "assets", bucket: "assets" });
|
|
});
|
|
|
|
test("supports explicit key and bucket names", () => {
|
|
expect(
|
|
getServiceS3Claim("app", {
|
|
volumes: ["s3:app-key/shared-assets"],
|
|
} as Service),
|
|
).toEqual({ service: "app", key: "app-key", bucket: "shared-assets" });
|
|
});
|
|
|
|
test.each([
|
|
"s3:",
|
|
"s3:key/",
|
|
"s3:/bucket",
|
|
"s3:key/bucket/extra",
|
|
"s3:key:bucket",
|
|
])("rejects malformed declaration %s", (entry) => {
|
|
expect(() =>
|
|
getServiceS3Claim("app", { volumes: [entry] } as Service),
|
|
).toThrow("Use s3:<name> or s3:<key>/<bucket>");
|
|
});
|
|
|
|
test("ignores unrelated and long-form volumes", () => {
|
|
const service = {
|
|
volumes: ["cache:/cache", { type: "volume", target: "/data" }],
|
|
} as Service;
|
|
expect(getServiceS3Claim("app", service)).toBeUndefined();
|
|
expect(isS3VolumeEntry("cache:/cache")).toBe(false);
|
|
});
|
|
|
|
test("rejects multiple declarations on one service", () => {
|
|
expect(() =>
|
|
getServiceS3Claim("app", {
|
|
volumes: ["s3:one", "s3:two"],
|
|
} as Service),
|
|
).toThrow("declares multiple S3 volumes");
|
|
});
|
|
|
|
test("allows services to share the same key and bucket", () => {
|
|
const compose = {
|
|
services: {
|
|
app: { volumes: ["s3:shared/assets"] },
|
|
worker: { volumes: ["s3:shared/assets"] },
|
|
},
|
|
} as ComposeSpecification;
|
|
expect(getComposeS3Claims(compose)).toHaveLength(2);
|
|
});
|
|
|
|
test("rejects one key targeting different buckets", () => {
|
|
const compose = {
|
|
services: {
|
|
app: { volumes: ["s3:shared/one"] },
|
|
worker: { volumes: ["s3:shared/two"] },
|
|
},
|
|
} as ComposeSpecification;
|
|
expect(() => getComposeS3Claims(compose)).toThrow(
|
|
"S3 key shared is claimed for both one and two",
|
|
);
|
|
});
|
|
|
|
test("does not render S3 declarations as filesystem volumes", () => {
|
|
const service = { image: "example", volumes: ["s3:assets"] } as Service;
|
|
expect(volumesToPvc("project", service)).toEqual([]);
|
|
|
|
const deployment = serviceToDeployment(
|
|
"project",
|
|
"app",
|
|
{ services: { app: service } } as ComposeSpecification,
|
|
service,
|
|
process.cwd(),
|
|
{ AWS_ACCESS_KEY_ID: "test" },
|
|
);
|
|
expect(deployment.spec?.template.spec?.volumes).toBeUndefined();
|
|
expect(deployment.spec?.template.spec?.containers[0]?.envFrom).toEqual([
|
|
{ secretRef: { name: "app-env" } },
|
|
]);
|
|
});
|
|
|
|
test("builds a Garage UI object URL for a bucket", () => {
|
|
expect(getS3UiUrl("shared assets")).toBe(
|
|
"http://garage-ui.garage-system.svc.cluster.local/buckets/shared%20assets/objects",
|
|
);
|
|
});
|
|
});
|