403 lines
9.1 KiB
Go
403 lines
9.1 KiB
Go
package manifest
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
func TestSetJSONLSaveHook(t *testing.T) {
|
|
old := SetJSONLSaveHook(func() error { return fmt.Errorf("hook error") })
|
|
if old != nil {
|
|
t.Error("expected nil old hook")
|
|
}
|
|
restore := SetJSONLSaveHook(old)
|
|
if restore == nil {
|
|
t.Error("expected non-nil restore function")
|
|
}
|
|
}
|
|
|
|
func TestJSONLSaveHookError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m := LoadJSONL(dir)
|
|
if err := m.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
old := SetJSONLSaveHook(func() error { return fmt.Errorf("hook error") })
|
|
defer SetJSONLSaveHook(old)
|
|
if err := m.Save(); err == nil {
|
|
t.Error("expected hook error from Save")
|
|
}
|
|
m.Close()
|
|
}
|
|
|
|
func TestJSONLSyncFuncError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m := LoadJSONL(dir)
|
|
if err := m.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
m.syncFunc = func() error { return fmt.Errorf("sync func error") }
|
|
if err := m.Save(); err == nil {
|
|
t.Error("expected syncFunc error from Save")
|
|
}
|
|
m.Close()
|
|
}
|
|
|
|
func TestSQLiteOpenAppendSQLError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.open = func(driverName, dataSourceName string) (*sql.DB, error) {
|
|
return nil, fmt.Errorf("simulated open error")
|
|
}
|
|
if err := m.OpenAppend(); err == nil {
|
|
t.Error("expected error from sql.Open failure")
|
|
}
|
|
}
|
|
|
|
func TestSQLiteOpenAppendCreateTableError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
realOpen := m.open
|
|
m.open = func(driverName, dataSourceName string) (*sql.DB, error) {
|
|
db, err := realOpen(driverName, dataSourceName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
db.Close()
|
|
return db, nil
|
|
}
|
|
if err := m.OpenAppend(); err == nil {
|
|
t.Error("expected error from closed DB CREATE TABLE")
|
|
}
|
|
}
|
|
|
|
func TestSQLiteHasAfterClose(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)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
m.Close()
|
|
if m.Has("x1") {
|
|
t.Error("Has should return false after Close")
|
|
}
|
|
}
|
|
|
|
func TestSQLiteEntriesAfterClose(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)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
m.Close()
|
|
entries := m.Entries()
|
|
if entries != nil {
|
|
t.Errorf("Entries should return nil after Close, got %d entries", len(entries))
|
|
}
|
|
}
|
|
|
|
func TestSQLiteOpenAppendMkdirAllError(t *testing.T) {
|
|
m, err := LoadSQLite("/proc/cannot-write")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := m.OpenAppend(); err == nil {
|
|
t.Error("expected error creating dir under /proc")
|
|
m.Close()
|
|
}
|
|
}
|
|
|
|
func TestSQLiteOpenAppendNilOpener(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.open = nil
|
|
if err := m.OpenAppend(); err != nil {
|
|
t.Errorf("expected nil opener to use sql.Open fallback, got err: %v", err)
|
|
}
|
|
m.Close()
|
|
}
|
|
|
|
func TestSQLiteOpenAppendCreateIndexError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
realOpen := m.open
|
|
m.open = func(driverName, dataSourceName string) (*sql.DB, error) {
|
|
db, err := realOpen(driverName, dataSourceName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
db.Close()
|
|
return db, nil
|
|
}
|
|
if err := m.OpenAppend(); err == nil {
|
|
t.Error("expected error from closed DB")
|
|
}
|
|
}
|
|
|
|
func TestSQLiteHasQueryError(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)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
closedDB := m.db
|
|
closedDB.Close()
|
|
result := m.Has("x1")
|
|
if result {
|
|
t.Error("Has should return false with broken DB connection")
|
|
}
|
|
}
|
|
|
|
func TestSQLiteEntriesQueryError(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)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
closedDB := m.db
|
|
closedDB.Close()
|
|
entries := m.Entries()
|
|
if entries == nil {
|
|
t.Error("Entries should return non-nil map with broken DB connection")
|
|
}
|
|
if len(entries) != 0 {
|
|
t.Errorf("Entries should be empty with broken DB connection, got %d", len(entries))
|
|
}
|
|
}
|
|
|
|
func TestSQLiteHasQueryErrorWithOpenDB(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)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
closedDB := m.db
|
|
closedDB.Close()
|
|
if m.Has("x1") {
|
|
t.Error("Has should return false with closed DB")
|
|
}
|
|
}
|
|
|
|
func TestSQLiteEntriesQueryErrorWithOpenDB(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)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
closedDB := m.db
|
|
closedDB.Close()
|
|
entries := m.Entries()
|
|
if entries != nil && len(entries) != 0 {
|
|
t.Errorf("Entries should be empty with closed DB, got %d", len(entries))
|
|
}
|
|
}
|
|
|
|
func TestSQLiteCreateIndexError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
realOpen := m.open
|
|
callCount := 0
|
|
m.open = func(driverName, dataSourceName string) (*sql.DB, error) {
|
|
db, err := realOpen(driverName, dataSourceName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m.execFunc = func(query string, args ...any) (sql.Result, error) {
|
|
callCount++
|
|
if callCount == 2 {
|
|
return nil, fmt.Errorf("injected CREATE INDEX error")
|
|
}
|
|
return db.Exec(query, args...)
|
|
}
|
|
return db, nil
|
|
}
|
|
if err := m.OpenAppend(); err == nil {
|
|
t.Error("expected error from CREATE INDEX")
|
|
m.Close()
|
|
}
|
|
}
|
|
|
|
func TestConvertFromJSONLOpenAppendSQLError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m := LoadJSONL(dir)
|
|
if err := m.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
m.Close()
|
|
oldOpen := sqliteOpenFunc
|
|
sqliteOpenFunc = func(driverName, dataSourceName string) (*sql.DB, error) {
|
|
return nil, fmt.Errorf("simulated sqlite open error")
|
|
}
|
|
defer func() { sqliteOpenFunc = oldOpen }()
|
|
_, err := ConvertFromJSONL(dir)
|
|
if err == nil {
|
|
t.Error("expected error from dst.OpenAppend during ConvertFromJSONL")
|
|
}
|
|
}
|
|
|
|
func TestConvertFromJSONLDstOpenAppendError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m := LoadJSONL(dir)
|
|
if err := m.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
m.Close()
|
|
realOpen := defaultSQLOpener()
|
|
oldOpen := sqliteOpenFunc
|
|
sqliteOpenFunc = func(driverName, dataSourceName string) (*sql.DB, error) {
|
|
db, err := realOpen(driverName, dataSourceName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
db.Close()
|
|
return db, nil
|
|
}
|
|
defer func() { sqliteOpenFunc = oldOpen }()
|
|
_, err := ConvertFromJSONL(dir)
|
|
if err == nil {
|
|
t.Error("expected error from dst.OpenAppend during ConvertFromJSONL")
|
|
}
|
|
}
|
|
|
|
func TestConvertFromSQLiteSrcOpenAppendError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
src, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := src.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
src.Add("x1", "photo.jpg", 1024, "local")
|
|
src.Close()
|
|
realOpen := defaultSQLOpener()
|
|
callCount := 0
|
|
oldOpen := sqliteOpenFunc
|
|
sqliteOpenFunc = func(driverName, dataSourceName string) (*sql.DB, error) {
|
|
callCount++
|
|
db, err := realOpen(driverName, dataSourceName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if callCount > 0 {
|
|
db.Close()
|
|
}
|
|
return db, nil
|
|
}
|
|
defer func() { sqliteOpenFunc = oldOpen }()
|
|
_, err = ConvertFromSQLite(dir)
|
|
if err == nil {
|
|
t.Error("expected error from src.OpenAppend during ConvertFromSQLite")
|
|
}
|
|
}
|
|
|
|
func TestConvertFromSQLiteDstOpenAppendError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
src, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := src.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
src.Add("x1", "photo.jpg", 1024, "local")
|
|
src.Close()
|
|
jsonlPath := JSONLPath(dir)
|
|
f, err := os.Create(jsonlPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f.Close()
|
|
os.Chmod(jsonlPath, 0444)
|
|
defer os.Chmod(jsonlPath, 0644)
|
|
_, err = ConvertFromSQLite(dir)
|
|
if err == nil {
|
|
t.Error("expected error from dst.OpenAppend during ConvertFromSQLite")
|
|
}
|
|
}
|
|
|
|
func TestJSONLSaveError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
m := LoadJSONL(dir)
|
|
if err := m.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.Add("x1", "photo.jpg", 1024, "local")
|
|
m.file.Close()
|
|
if err := m.Save(); err == nil {
|
|
t.Error("expected Sync error on closed file")
|
|
}
|
|
m.Close()
|
|
}
|
|
|
|
func TestConvertFromSQLiteSaveError(t *testing.T) {
|
|
dir := t.TempDir()
|
|
src, err := LoadSQLite(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := src.OpenAppend(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
src.Add("x1", "photo.jpg", 1024, "local")
|
|
src.Close()
|
|
oldHook := jsonlSaveHook
|
|
jsonlSaveHook = func() error { return fmt.Errorf("simulated sync error") }
|
|
defer func() { jsonlSaveHook = oldHook }()
|
|
_, err = ConvertFromSQLite(dir)
|
|
if err == nil {
|
|
t.Error("expected error from dst.Save during ConvertFromSQLite")
|
|
}
|
|
if err != nil && !strings.Contains(err.Error(), "save jsonl") {
|
|
t.Errorf("expected save jsonl error, got: %v", err)
|
|
}
|
|
}
|