Ctrl K
ComunidadGuías…

engine/logwriter_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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)
	}
}