Skip to content

Commit

Permalink
test: improve tests by using testcontainers
Browse files Browse the repository at this point in the history
Before, we assume that the host/dev env
had a zerotier-one service running.

Now we can start a container and use the
zerotier-one in there, and then throw it away.
  • Loading branch information
laduke committed Apr 11, 2024
1 parent 0177c66 commit f1e7419
Showing 1 changed file with 58 additions and 40 deletions.
98 changes: 58 additions & 40 deletions test/integration.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { readFileSync } from "node:fs";
import { describe, it } from "node:test";
import { describe, it, before } from "node:test";
import assert from "node:assert";

import { GenericContainer } from "testcontainers";
import createClient from "openapi-fetch";
import { PathsWithMethod } from "openapi-typescript-helpers";
import type { paths } from "/tmp/schema.ts"; // generated by openapi-typescript
Expand All @@ -13,18 +14,16 @@ import { AnyValidateFunction } from "ajv/dist/core.js";
const Ajv = _Ajv.default;
const addFormats = _addFormats.default;

if (!process.env.AUTH_TOKEN) {
console.error("No AUTH_TOKEN env var set. Exiting.");
process.exit(1);
}
const ZT_VERSION = process.env.ZT_VERSION || "1.12.2"

const isNextApiVersion = process.env.ENABLE_UNSTABLE;
function compareVersions(a: string, b: string) {
return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' })
}

function createCreateClient() {
// AUTH_TOKEN=`cat ~/Library/Application\ Support/ZeroTier/One/authtoken.secret ` npm t
const authToken = process.env.AUTH_TOKEN;
function createCreateClient(token: string, port: number) {
const authToken = token;
const client = createClient<paths>({
baseUrl: "http://localhost:9993/",
baseUrl: `http://localhost:${port}/`,
headers: { "X-ZT1-AUTH": authToken },
});

Expand Down Expand Up @@ -59,32 +58,51 @@ function assertValid(
}
}

describe("GET endpoints", async function () {
const map: { path: PathsWithMethod<paths, "get">; id: string }[] = [
{ path: "/status", id: "NodeStatus" },
{ path: "/controller", id: "ControllerStatus" },
{ path: "/network", id: "JoinedNetworks" },
{ path: "/peer", id: "Peers" },
];
const ZEROTIER_API_SECRET = "asdf";

for (const { path, id } of map) {
it(id, async () => {
const validator = createValidator(id);
describe("API exercise", async function() {
let network_id: string;
const node_id = "1122334455";
let container;
let client: ReturnType<typeof createCreateClient>;
let apiPort: number;

before(async () => {
container = await new GenericContainer(`zerotier/zerotier:${ZT_VERSION}`)
.withExposedPorts(9993)
.withPrivilegedMode()
.withAddedCapabilities("NET_ADMIN")
.withEnvironment({ ZEROTIER_API_SECRET })
.withCopyContentToContainer([
{
content: `{ "settings": { "allowManagementFrom": ["0.0.0.0/0"] } }`,
target: "/var/lib/zerotier-one/local.conf",
},
])
.start();
apiPort = container.getMappedPort(9993);
client = createCreateClient(ZEROTIER_API_SECRET, apiPort);
});

const client = createCreateClient();
describe("GET endpoints", async function() {
const map: { path: PathsWithMethod<paths, "get">; id: string }[] = [
{ path: "/status", id: "NodeStatus" },
{ path: "/controller", id: "ControllerStatus" },
{ path: "/network", id: "JoinedNetworks" },
{ path: "/peer", id: "Peers" },
];

const { data } = await client.GET(path, {});
assert.ok(data);
for (const { path, id } of map) {
it(id, async () => {
const validator = createValidator(id);

assertValid(validator, data);
});
}
});
const { data } = await client.GET(path, {});
assert.ok(data);

describe("API exercise", async function () {
const client = createCreateClient();
let network_id: string;
const node_id = "1122334455";
assertValid(validator, data);
});
}
});

it("Creates a valid controller network", async () => {
const { data: networkData } = await client.POST("/controller/network", {
Expand Down Expand Up @@ -212,7 +230,7 @@ describe("API exercise", async function () {
});
});

describe("Unstable APIs", { skip: !isNextApiVersion }, async () => {
describe("Unstable APIs", { skip: compareVersions(ZT_VERSION, "1.12.2") !== 1 }, async () => {
it("Sets the member name", async () => {
const { data } = await client.POST(
"/controller/network/{network_id}/member/{node_id}",
Expand Down Expand Up @@ -265,12 +283,12 @@ describe("API exercise", async function () {
});
});

// it("Deletes the network by ID", async () => {
// const { data } = await client.DELETE(
// "/controller/network/{network_id}",
// { params: { path: { network_id } } },
// );
// const networkDelValidator = createValidator("ControllerNetwork");
// assertValid(networkDelValidator, data);
// });
it("Deletes the network by ID", async () => {
const { data } = await client.DELETE(
"/controller/network/{network_id}",
{ params: { path: { network_id } } },
);
const networkDelValidator = createValidator("ControllerNetwork");
assertValid(networkDelValidator, data);
});
});

0 comments on commit f1e7419

Please sign in to comment.