Files
MikrotikManager/backend/src/services/containers-state.test.ts
T

41 lines
4.5 KiB
TypeScript

import assert from "node:assert/strict"
import { readContainerServerState, collectContainersState } from "./containers-state.js"
import { MikrotikError } from "./mikrotik.js"
import { containersStateSchema } from "@mmapp/contracts/containers"
const server = { id: 1, name: "Router" } as Parameters<typeof readContainerServerState>[0]
const row = { ".id": "*A", name: "nginx", "remote-image": "nginx:alpine", interface: "veth1", envlist: "e", mounts: "m", status: "running", "start-on-boot": "yes", cpu: "0", "memory-current": "0", "memory-high": "52428800" }
const read = async (path: string): Promise<unknown> => path === "/container" ? [row] : path === "/container/envs" ? [{name:"e",key:"A",value:"B"}] : [{name:"m",src:"/disk",dst:"/data"}]
const good = await readContainerServerState(server, read)
assert.equal(good.availability, "available"); assert.equal(good.containers[0].status,"running")
assert.equal(good.containers[0].cpu,0);assert.equal(good.containers[0].memMb,0);assert.equal(good.containers[0].startOnBoot,true)
assert.deepEqual(good.containers[0].envs,[{key:"A",value:"B"}]);assert.deepEqual(good.containers[0].mounts,[{src:"/disk",dst:"/data"}])
const unknown = await readContainerServerState(server, async path => path === "/container" ? [{".id":"*B",name:"pending",status:"extracting"}] : [])
assert.equal(unknown.containers[0].status,"unknown");assert.equal(unknown.containers[0].startOnBoot,null);assert.equal(unknown.containers[0].image,"")
const empty = await readContainerServerState(server, async()=>[])
assert.equal(empty.availability,"available");assert.equal(empty.containers.length,0)
for (const raw of [{containers:[]},[{}],[row,row]]) {
const result = await readContainerServerState(server, async()=>raw)
assert.equal(result.availability,"error");assert.equal(result.failures[0].resource,"containers")
}
for(const status of [401,403,500]){const result=await readContainerServerState(server,async()=>{throw new MikrotikError(status,"/container","refused")});assert.equal(result.availability,"error")}
const unsupported=await readContainerServerState(server,async()=>{throw new MikrotikError(404,"/container","no such command")});assert.equal(unsupported.availability,"unsupported");assert.deepEqual(unsupported.failures,[])
for(const resource of ["envs","mounts"]){const result=await readContainerServerState(server,async path=>{if(path==="/container/"+resource)throw new Error("dependency refused");return read(path)});assert.equal(result.availability,"available");assert.equal(result.containers.length,1);assert.equal(result.failures[0].resource,resource)}
const badDependency=await readContainerServerState(server,async path=>path==="/container/envs"?{}:read(path));assert.equal(badDependency.failures[0].resource,"envs")
const aggregate=await collectContainersState([server,{...server,id:2}],srv=>srv.id===1?read:async()=>{throw new Error("offline")});assert.equal(aggregate.servers[0].containers.length,1);assert.equal(aggregate.servers[1].availability,"error")
assert.equal((await collectContainersState([],()=>read)).servers.length,0)
for (const value of [
{...aggregate,servers:[good,good]},
{...aggregate,servers:[{...good,serverId:2}]},
{...aggregate,servers:[{...good,availability:"error",failures:[]}]},
{...aggregate,servers:[{...good,containers:[good.containers[0],good.containers[0]]}]},
{...aggregate,servers:[{...unsupported,failures:[{resource:"envs",error:"x"}]}]},
]) assert.equal(containersStateSchema.safeParse(value).success,false)
console.log("Containers state: independent devices, malformed/duplicate IDs, unknown status/boot, known empty, missing package, partial dependencies, zeros and envelope validation; no DB/RouterOS")
const limitOnly=await readContainerServerState(server,async path=>path==="/container"?[{".id":"*C","memory-high":"52428800"}]:[]);assert.equal(limitOnly.containers[0].memMb,undefined)
const modern=await readContainerServerState(server,async path=>path==="/container"?[{...row,envlist:"e,e2",mounts:undefined,mountlists:"m"}]:path==="/container/envs"?[{list:"e",key:"A",value:"1"},{list:"e2",key:"B",value:"2"}]:[{list:"m",src:"/disk",dst:"/data"}]);assert.equal(modern.containers[0].envs.length,2);assert.equal(modern.containers[0].mounts.length,1)
let factories=0
const setupFailure=await collectContainersState([server,{...server,id:2}],srv=>{if(srv.id===2)throw new Error("client setup refused");factories++;return read});assert.equal(setupFailure.servers[0].containers.length,1);assert.equal(setupFailure.servers[1].availability,"error");assert.equal(setupFailure.servers[1].failures[0].error,"client setup refused");assert.equal(factories,1)