106 lines
3.7 KiB
TypeScript
106 lines
3.7 KiB
TypeScript
import { mkdtemp, readdir, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
/**
|
|
* Die Bereitschaftsprüfung der Dateiablage.
|
|
*
|
|
* Bis v1.12.0 fiel eine kaputte Speicherkonfiguration erst auf, wenn
|
|
* jemand ein Dokument ablegen wollte. Auf dem Livesystem waren das
|
|
* mehrere Wochen nach der Installation — und dann mitten in der Arbeit,
|
|
* mit einer Meldung, die nichts sagte.
|
|
*
|
|
* Die Prüfung schreibt eine winzige Datei, liest sie zurück und räumt sie
|
|
* weg. Sie beantwortet damit drei Fragen auf einmal: erreichbar,
|
|
* Ablagebereich vorhanden, Schreibrecht da.
|
|
*/
|
|
|
|
let verzeichnis = ''
|
|
|
|
beforeEach(async () => {
|
|
verzeichnis = await mkdtemp(join(tmpdir(), 'bc-pruefung-'))
|
|
process.env.SPEICHER_TREIBER = 'datei'
|
|
process.env.DATEI_SPEICHER_PFAD = verzeichnis
|
|
vi.resetModules()
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await rm(verzeichnis, { recursive: true, force: true })
|
|
delete process.env.SPEICHER_TREIBER
|
|
delete process.env.DATEI_SPEICHER_PFAD
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
describe('Bereitschaftsprüfung', () => {
|
|
it('meldet eine benutzbare Ablage', async () => {
|
|
const { speicherPruefen } = await import('@/lib/speicher/pruefung')
|
|
|
|
const zustand = await speicherPruefen()
|
|
|
|
expect(zustand.ok).toBe(true)
|
|
expect(zustand.treiber).toBe('datei')
|
|
})
|
|
|
|
it('lässt nichts liegen', async () => {
|
|
// Eine Pruefung, die bei jedem Aufruf eine Datei zuruecklaesst, waere
|
|
// nach einem Jahr Betrieb ein Verzeichnis voller Muell.
|
|
const { speicherPruefen } = await import('@/lib/speicher/pruefung')
|
|
|
|
await speicherPruefen()
|
|
await speicherPruefen()
|
|
await speicherPruefen()
|
|
|
|
const inhalt = await readdir(join(verzeichnis, 'pruefung')).catch(() => [])
|
|
expect(inhalt).toEqual([])
|
|
})
|
|
|
|
it('meldet einen Fehler, statt zu werfen', async () => {
|
|
// Der Aufrufer ist die Gesundheitsauskunft. Wirft die Pruefung, ist
|
|
// die Auskunft weg - und mit ihr die Erklaerung.
|
|
// Eine Datei als Ablageverzeichnis: Das Anlegen des Unterordners
|
|
// scheitert dann zuverlaessig und auf jedem System.
|
|
const alsDatei = join(verzeichnis, 'keine-ablage')
|
|
await writeFile(alsDatei, 'ich bin eine Datei')
|
|
process.env.DATEI_SPEICHER_PFAD = alsDatei
|
|
const { speicherPruefen } = await import('@/lib/speicher/pruefung')
|
|
|
|
const zustand = await speicherPruefen()
|
|
|
|
expect(zustand.ok).toBe(false)
|
|
if (!zustand.ok) expect(zustand.meldung.length).toBeGreaterThan(10)
|
|
})
|
|
})
|
|
|
|
describe('Gemerkter Zustand', () => {
|
|
it('prüft nicht bei jedem Aufruf neu', async () => {
|
|
// Der Healthcheck fragt alle 30 Sekunden. Ohne Schonfrist schriebe er
|
|
// ebenso oft eine Probedatei in den Objektspeicher.
|
|
const modul = await import('@/lib/speicher/pruefung')
|
|
modul.zustandVergessen()
|
|
|
|
const erste = await modul.speicherZustand()
|
|
const zweite = await modul.speicherZustand()
|
|
|
|
expect(zweite).toBe(erste)
|
|
})
|
|
|
|
it('meldet denselben Zustand nicht wieder und wieder', async () => {
|
|
const protokoll = vi.spyOn(console, 'log').mockImplementation(() => {})
|
|
const modul = await import('@/lib/speicher/pruefung')
|
|
modul.zustandVergessen()
|
|
|
|
await modul.speicherZustand()
|
|
// Wie nach fuenf Minuten: neu pruefen, aber das Meldegedaechtnis bleibt.
|
|
modul.schonfristUeberspringen()
|
|
await modul.speicherZustand()
|
|
|
|
// Zweimal geprueft, aber nur die erste Meldung - sonst stuende alle
|
|
// fuenf Minuten dieselbe Zeile im Log und niemand liest sie mehr.
|
|
const speicherzeilen = protokoll.mock.calls.filter((aufruf) =>
|
|
String(aufruf[0]).startsWith('[speicher]'),
|
|
)
|
|
expect(speicherzeilen).toHaveLength(1)
|
|
})
|
|
})
|