package database import ( "os" "path/filepath" "strings" "testing" "git.eeqj.de/sneak/routewatch/internal/config" "git.eeqj.de/sneak/routewatch/internal/logger" ) // TestDockerignoreExcludesDatabaseFiles checks that .dockerignore keeps the // database file, and the WAL and shared-memory files SQLite writes next to it, // out of the build context wherever they sit in the clone. The image ships the // whole build context as a source archive. func TestDockerignoreExcludesDatabaseFiles(t *testing.T) { t.Parallel() db, err := New(&config.Config{StateDir: t.TempDir()}, logger.New()) if err != nil { t.Fatalf("failed to create database: %v", err) } defer func() { _ = db.Close() }() data, err := os.ReadFile("../../.dockerignore") if err != nil { t.Fatalf("failed to read .dockerignore: %v", err) } // Docker reads `**/` as any number of directories and the rest of the // pattern as filepath.Match does, so `**/` followed by a pattern that // matches a file's name excludes that file at any depth. var anyDepth []string for line := range strings.Lines(string(data)) { pattern, ok := strings.CutPrefix(strings.TrimSpace(line), "**/") if ok { anyDepth = append(anyDepth, pattern) } } name := filepath.Base(db.path) for _, file := range []string{name, name + "-wal", name + "-shm"} { excluded := false for _, pattern := range anyDepth { matched, err := filepath.Match(pattern, file) if err != nil { t.Fatalf("bad .dockerignore pattern **/%s: %v", pattern, err) } excluded = excluded || matched } if !excluded { t.Errorf(".dockerignore has no **/ pattern that excludes %s", file) } } }