v0.5.0: manifests, filters, logging, docs
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
package manifest
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func TestNoopLogWriter(t *testing.T) {
|
||||
lw := NoopLogWriter
|
||||
lw.Log(LogEntry{Event: "test"})
|
||||
lw.Close()
|
||||
noopLogWriter{}.Log(LogEntry{Event: "test"})
|
||||
noopLogWriter{}.Close()
|
||||
}
|
||||
|
||||
func TestNewSQLiteLogWriter(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
dbPath := filepath.Join(dir, "test.db")
|
||||
db, err := sql.Open("sqlite", dbPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
lw, err := NewSQLiteLogWriter(db)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
lw.Log(LogEntry{
|
||||
Timestamp: 1700000000,
|
||||
Level: "info",
|
||||
Event: "export_done",
|
||||
AssetID: "asset-1",
|
||||
Album: "Favorites",
|
||||
Filename: "photo.jpg",
|
||||
Size: 1024,
|
||||
Cloud: "local",
|
||||
DurationMs: 500,
|
||||
Message: "",
|
||||
})
|
||||
|
||||
lw.Log(LogEntry{
|
||||
Timestamp: 1700000001,
|
||||
Level: "error",
|
||||
Event: "export_fail",
|
||||
AssetID: "asset-2",
|
||||
Filename: "bad.jpg",
|
||||
Message: "timeout",
|
||||
})
|
||||
|
||||
lw.Close()
|
||||
|
||||
var count int
|
||||
err = db.QueryRow(`SELECT COUNT(*) FROM logs`).Scan(&count)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if count != 2 {
|
||||
t.Errorf("expected 2 log entries, got %d", count)
|
||||
}
|
||||
|
||||
var event, level, assetID string
|
||||
err = db.QueryRow(`SELECT event, level, asset_id FROM logs WHERE asset_id = 'asset-1'`).Scan(&event, &level, &assetID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if event != "export_done" || level != "info" || assetID != "asset-1" {
|
||||
t.Errorf("unexpected row: event=%s level=%s asset_id=%s", event, level, assetID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLiteLogWriterNilDB(t *testing.T) {
|
||||
w := &sqliteLogWriter{db: nil}
|
||||
w.Log(LogEntry{Event: "test"})
|
||||
w.Close()
|
||||
}
|
||||
|
||||
func TestNewSQLiteLogWriterError(t *testing.T) {
|
||||
db, err := sql.Open("sqlite", filepath.Join(t.TempDir(), "test.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := NewSQLiteLogWriter(db); err == nil {
|
||||
t.Error("expected error for closed db")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLiteLogWriterCloseConcrete(t *testing.T) {
|
||||
(&sqliteLogWriter{}).Close()
|
||||
}
|
||||
|
||||
func TestNewFileLogWriter(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "export.log")
|
||||
lw, err := NewFileLogWriter(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
lw.Log(LogEntry{
|
||||
Timestamp: 1700000000,
|
||||
Level: "info",
|
||||
Event: "export_done",
|
||||
Filename: "photo.jpg",
|
||||
Size: 2048,
|
||||
})
|
||||
|
||||
lw.Close()
|
||||
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(data) == 0 {
|
||||
t.Error("expected log data")
|
||||
}
|
||||
if data[len(data)-1] != '\n' {
|
||||
t.Error("expected trailing newline")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileLogWriterClosed(t *testing.T) {
|
||||
w := &fileLogWriter{f: nil}
|
||||
w.Log(LogEntry{Event: "test"})
|
||||
w.Close()
|
||||
}
|
||||
|
||||
func TestNewFileLogWriterError(t *testing.T) {
|
||||
_, err := NewFileLogWriter("/nonexistent/dir/export.log")
|
||||
if err == nil {
|
||||
t.Error("expected error for bad path")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileLogWriterDoubleClose(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "export.log")
|
||||
lw, err := NewFileLogWriter(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
lw.Close()
|
||||
lw.Close()
|
||||
}
|
||||
|
||||
func TestLogPath(t *testing.T) {
|
||||
p := LogPath("/tmp/out")
|
||||
if p != "/tmp/out/export.log" {
|
||||
t.Errorf("expected /tmp/out/export.log, got %s", p)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenLogWriterSQLite(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
m, err := LoadSQLite(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := m.OpenAppend(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer m.Close()
|
||||
|
||||
lw, err := OpenLogWriter(m, dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
lw.Log(LogEntry{Event: "test", Level: "info"})
|
||||
lw.Close()
|
||||
}
|
||||
|
||||
func TestOpenLogWriterJSONL(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
m := LoadJSONL(dir)
|
||||
if err := m.OpenAppend(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer m.Close()
|
||||
|
||||
lw, err := OpenLogWriter(m, dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
lw.Log(LogEntry{Event: "test", Level: "info"})
|
||||
lw.Close()
|
||||
|
||||
if _, err := os.Stat(LogPath(dir)); os.IsNotExist(err) {
|
||||
t.Error("expected export.log to exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenLogWriterNilManifest(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
lw, err := OpenLogWriter(nil, dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
lw.Log(LogEntry{Event: "test", Level: "info"})
|
||||
lw.Close()
|
||||
if _, err := os.Stat(LogPath(dir)); os.IsNotExist(err) {
|
||||
t.Error("expected export.log to exist for nil manifest")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user