Path: blob/master/src/packages/file-server/zfs/test/util.ts
1450 views
// application/typescript text1import { context, setContext } from "@cocalc/file-server/zfs/config";2import { mkdtemp, rm } from "fs/promises";3import { tmpdir } from "os";4import { join } from "path";5import { executeCode } from "@cocalc/backend/execute-code";6import { initDataDir } from "@cocalc/file-server/zfs/util";7import { resetDb } from "@cocalc/file-server/zfs/db";8import { getPools } from "@cocalc/file-server/zfs/pools";9import { map as asyncMap } from "awaiting";1011// export "describe" from here that is a no-op unless TEST_ZFS is set1213const Describe = process.env.TEST_ZFS ? describe : describe.skip;14const describe0 = describe;15export { Describe as describe, describe0 };1617export async function init() {18if (!context.PREFIX.includes("test")) {19throw Error("context.PREFIX must contain 'test'");20}21await initDataDir();22resetDb();23}2425export async function createTestPools({26size = "10G",27count = 1,28prefix,29}: {30size?: string;31count?: number;32prefix?: string;33}): Promise<{ tempDir: string; pools: string[]; prefix?: string }> {34setContext({ prefix });35if (!context.PREFIX.includes("test")) {36throw Error(`context.PREFIX=${context.PREFIX} must contain 'test'`);37}38// Create temp directory39const tempDir = await mkdtemp(join(tmpdir(), "test-"));40const pools: string[] = [];41// in case pools left from a failing test:42for (const pool of Object.keys(await getPools())) {43try {44await executeCode({45command: "sudo",46args: ["zpool", "destroy", pool],47});48} catch {}49}50for (let n = 0; n < count; n++) {51const image = join(tempDir, `${n}`, "0.img");52await executeCode({53command: "mkdir",54args: [join(tempDir, `${n}`)],55});56await executeCode({57command: "truncate",58args: ["-s", size, image],59});60const pool = `${context.PREFIX}-${n}`;61pools.push(pool);62await executeCode({63command: "sudo",64args: ["zpool", "create", pool, image],65});66}67// ensure pool cache is cleared:68await getPools({ noCache: true });69return { tempDir, pools, prefix };70}7172// Even after setting sharefnfs=off, it can be a while (a minute?) until NFS73// fully frees up the share so we can destroy the pool. This makes it instant,74// which is very useful for unit testing.75export async function restartNfsServer() {76await executeCode({77command: "sudo",78args: ["service", "nfs-kernel-server", "restart"],79});80}8182export async function deleteTestPools(x?: {83tempDir: string;84pools: string[];85prefix?: string;86}) {87if (!x) {88return;89}90const { tempDir, pools, prefix } = x;91setContext({ prefix });92if (!context.PREFIX.includes("test")) {93throw Error("context.PREFIX must contain 'test'");94}9596const f = async (pool) => {97try {98await executeCode({99command: "sudo",100args: ["zpool", "destroy", pool],101});102} catch (err) {103// if (!`$err}`.includes("no such pool")) {104// console.log(err);105// }106}107};108await asyncMap(pools, pools.length, f);109await rm(tempDir, { recursive: true });110}111112113