engine/logwriter_test.go
Rama main · réplica de lectura del repositorio original.
package engine
import (
"os"
"path/filepath"
"strings"
"sync"
"testing"
)
// After the file has been moved aside, Reopen must create a new one and write there.
func TestLogWriterReopenAfterRotation(t *testing.T) {
dir := t.TempDir()
name := filepath.Join(dir, "access.log")
lw, err := openLogWriter(name, 0o644)
if err != nil {
t.Fatal(err)
}
defer lw.Close()
lw.WriteLine("before")
rotated := name + ".1"
if err := os.Rename(name, rotated); err != nil {
t.Fatal(err)
}
if err := lw.Reopen(); err != nil {
t.Fatal(err)
}
lw.WriteLine("after")
oldData, err := os.ReadFile(rotated)
if err != nil {
t.Fatal(err)
}
if got := strings.TrimSpace(string(oldData)); got != "before" {
t.Errorf("rotated file = %q, want %q", got, "before")
}
newData, err := os.ReadFile(name)
if err != nil {
t.Fatalf("a new log file should have been created: %v", err)
}
if got := strings.TrimSpace(string(newData)); got != "after" {
t.Errorf("new file = %q, want %q", got, "after")
}
}
// Concurrent writers must not lose or interleave lines.
func TestLogWriterConcurrentWrites(t *testing.T) {
dir := t.TempDir()
name := filepath.Join(dir, "access.log")
lw, err := openLogWriter(name, 0o644)
if err != nil {
t.Fatal(err)
}
defer lw.Close()
const writers = 50
var wg sync.WaitGroup
wg.Add(writers)
for i := range writers {
go func() {
defer wg.Done()
lw.WriteLine(strings.Repeat("x", 100) + string(rune('a'+i%26)))
}()
}
wg.Wait()
data, err := os.ReadFile(name)
if err != nil {
t.Fatal(err)
}
lines := strings.Split(strings.TrimSpace(string(data)), "\n")
if len(lines) != writers {
t.Fatalf("got %d lines, want %d", len(lines), writers)
}
for i, line := range lines {
if len(line) != 101 {
t.Fatalf("line %d has length %d, want 101 (torn write)", i, len(line))
}
}
}
// Writing to a closed logWriter must not panic.
func TestLogWriterWriteAfterClose(t *testing.T) {
dir := t.TempDir()
lw, err := openLogWriter(filepath.Join(dir, "access.log"), 0o644)
if err != nil {
t.Fatal(err)
}
lw.Close()
lw.WriteLine("ignored")
if _, err := lw.Write([]byte("ignored")); err != nil {
t.Errorf("Write after Close returned %v, want nil", err)
}
}
// The log files must not be readable by everyone, no matter the umask
func TestLogWriterPermissions(t *testing.T) {
filename := filepath.Join(t.TempDir(), "algernon.log")
lw, err := openLogWriter(filename, defaultLogPermissions)
if err != nil {
t.Fatal(err)
}
defer lw.Close()
lw.WriteLine("hello")
info, err := os.Stat(filename)
if err != nil {
t.Fatal(err)
}
if mode := info.Mode().Perm(); mode&0o007 != 0 {
t.Errorf("%s has mode %o, want no permissions for others", filename, mode)
}
}