fix(volumes): avoid ENOENT during test connection cleanup

This commit is contained in:
Nicolas Meienberger 2026-04-20 23:06:26 +02:00
parent f967450eea
commit 2dfbd04fa5
No known key found for this signature in database
2 changed files with 64 additions and 26 deletions

View file

@ -262,4 +262,41 @@ describe("volumeService.testConnection", () => {
expect(mount).toHaveBeenCalledOnce(); expect(mount).toHaveBeenCalledOnce();
expect(unmount).toHaveBeenCalledOnce(); expect(unmount).toHaveBeenCalledOnce();
}); });
test("does not fail when backend unmount already removed the temp mount path", async () => {
const mount = vi.fn().mockResolvedValue({ status: "mounted" });
let mountPath: string | undefined;
const unmount = vi.fn().mockImplementation(async () => {
await fs.rm(mountPath!, { recursive: true, force: true });
return { status: "unmounted" };
});
vi.spyOn(backendModule, "createVolumeBackend").mockImplementation((_volume, tempPath) => {
mountPath = tempPath;
return {
mount,
unmount,
checkHealth: vi.fn(),
};
});
await expect(
volumeService.testConnection({
backend: "nfs",
server: "127.0.0.1",
exportPath: "/exports/test",
version: "4",
port: 2049,
readOnly: false,
}),
).resolves.toEqual({
success: true,
message: "Connection successful",
});
expect(mountPath).toEqual(expect.stringContaining(`${path.sep}zerobyte-test-`));
await expect(fs.access(mountPath as string)).rejects.toThrow();
expect(mount).toHaveBeenCalledOnce();
expect(unmount).toHaveBeenCalledOnce();
});
}); });

View file

@ -232,36 +232,37 @@ const updateVolume = async (shortId: ShortId, volumeData: UpdateVolumeBody) => {
const testConnection = async (backendConfig: BackendConfig) => { const testConnection = async (backendConfig: BackendConfig) => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "zerobyte-test-")); const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "zerobyte-test-"));
const encryptedConfig = await encryptVolumeConfig(backendConfig); try {
const encryptedConfig = await encryptVolumeConfig(backendConfig);
const mockVolume = { const mockVolume = {
id: 0, id: 0,
shortId: asShortId("test"), shortId: asShortId("test"),
name: "test-connection", name: "test-connection",
config: encryptedConfig, config: encryptedConfig,
createdAt: Date.now(), createdAt: Date.now(),
updatedAt: Date.now(), updatedAt: Date.now(),
lastHealthCheck: Date.now(), lastHealthCheck: Date.now(),
type: encryptedConfig.backend, type: encryptedConfig.backend,
status: "unmounted" as const, status: "unmounted" as const,
lastError: null, lastError: null,
provisioningId: null, provisioningId: null,
autoRemount: true, autoRemount: true,
organizationId: "test-org", organizationId: "test-org",
}; };
const backend = createVolumeBackend(mockVolume, tempDir); const backend = createVolumeBackend(mockVolume, tempDir);
const { error } = await backend.mount(); const { error } = await backend.mount();
await backend.unmount(); await backend.unmount();
await fs.access(tempDir); return {
await fs.rm(tempDir, { recursive: true, force: true }); success: !error,
message: error ? toMessage(error) : "Connection successful",
return { };
success: !error, } finally {
message: error ? toMessage(error) : "Connection successful", await fs.rm(tempDir, { recursive: true, force: true });
}; }
}; };
const checkHealth = async (shortId: ShortId) => { const checkHealth = async (shortId: ShortId) => {