package restoretest import ( "bufio" "encoding/json" "fmt" "os" ) // AppendHistory hängt result an die JSONL-Protokolldatei an // (Akzeptanzkriterium 2/Pflichtprüfung 3: Historie zeigt mehrere // zurückliegende Testläufe nachvollziehbar an — append-only, nichts wird // überschrieben). func AppendHistory(logPath string, result Result) error { f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o600) if err != nil { return fmt.Errorf("restoretest: protokolldatei öffnen: %w", err) } defer func() { _ = f.Close() }() line, err := json.Marshal(result) if err != nil { return fmt.Errorf("restoretest: ergebnis kodieren: %w", err) } if _, err := f.Write(append(line, '\n')); err != nil { return fmt.Errorf("restoretest: ergebnis schreiben: %w", err) } return nil } // ReadHistory liest alle bisherigen Testlauf-Ergebnisse — Nachweis der // Nachvollziehbarkeit über mehrere Läufe hinweg. func ReadHistory(logPath string) ([]Result, error) { f, err := os.Open(logPath) if err != nil { if os.IsNotExist(err) { return nil, nil } return nil, fmt.Errorf("restoretest: protokolldatei lesen: %w", err) } defer func() { _ = f.Close() }() var results []Result scanner := bufio.NewScanner(f) scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024) for scanner.Scan() { line := scanner.Bytes() if len(line) == 0 { continue } var r Result if err := json.Unmarshal(line, &r); err != nil { return nil, fmt.Errorf("restoretest: protokollzeile dekodieren: %w", err) } results = append(results, r) } if err := scanner.Err(); err != nil { return nil, fmt.Errorf("restoretest: protokolldatei durchlaufen: %w", err) } return results, nil }