Files
TaskPool/internal/services/tasks/tiny_log_test.go
T

105 lines
3.0 KiB
Go

package tasks
import (
"bytes"
"testing"
)
func TestTinyLog_UTF8Splitting(t *testing.T) {
tl, err := NewTinyLog("test-utf8", nil)
if err != nil {
t.Fatalf("Failed to create TinyLog: %v", err)
}
defer tl.Close()
// "你好" in UTF-8: E4 BD A0, E5 a5 bd
part1 := []byte{0xE4, 0xBD} // Partial "你"
part2 := []byte{0xA0, 0xE5, 0xA5} // Rest of "你", partial "好"
part3 := []byte{0xBD, '\n'} // Rest of "好", newline
_, _ = tl.Write(part1)
if len(tl.remainder) != 2 {
t.Errorf("Expected remainder len 2, got %d", len(tl.remainder))
}
_, _ = tl.Write(part2)
// Currently it should collect both parts but still no newline,
// so remainder should be 5 bytes.
if len(tl.remainder) != 5 {
t.Errorf("Expected remainder len 5, got %d", len(tl.remainder))
}
_, _ = tl.Write(part3)
if len(tl.remainder) != 0 {
t.Errorf("Expected remainder len 0 after newline, got %d", len(tl.remainder))
}
// Read and verify
data, err := tl.ReadLastLines(1)
if err != nil {
t.Fatalf("ReadLastLines failed: %v", err)
}
if !bytes.Contains(data, []byte("你好")) {
t.Errorf("Expected output to contain '你好', got %q", data)
}
}
func TestTinyLog_CarriageReturn(t *testing.T) {
tl, err := NewTinyLog("test-cr", nil)
if err != nil {
t.Fatalf("Failed to create TinyLog: %v", err)
}
defer tl.Close()
input := []byte("progress: 50%\rprogress: 100%\r\n")
_, _ = tl.Write(input)
data, err := tl.ReadLastLines(10)
if err != nil {
t.Fatalf("ReadLastLines failed: %v", err)
}
// Should contain both progress lines (or at least be split correctly)
if !bytes.Contains(data, []byte("progress: 50%")) {
t.Errorf("Expected output to contain 'progress: 50%%', got %q", data)
}
if !bytes.Contains(data, []byte("progress: 100%")) {
t.Errorf("Expected output to contain 'progress: 100%%', got %q", data)
}
}
func TestTinyLog_LongLineCut(t *testing.T) {
tl, err := NewTinyLog("test-long", nil)
if err != nil {
t.Fatalf("Failed to create TinyLog: %v", err)
}
defer tl.Close()
// Create a buffer of maxLogBufferLen-1 bytes with a multi-byte character at the maxLogBufferLen boundary
// We want to ensure it doesn't cut in the middle of a 3-byte char.
longData := make([]byte, maxLogBufferLen-1)
for i := range longData {
longData[i] = 'A'
}
// "你" is E4 BD A0
longData = append(longData, 0xE4, 0xBD, 0xA0) // This starts at index maxLogBufferLen-1.
// Index maxLogBufferLen-1: E4
// Index maxLogBufferLen: BD
// Index maxLogBufferLen+1: A0
// If we cut at maxLogBufferLen, we split E4 and BD.
_, _ = tl.Write(longData)
// Since it's > maxLogBufferLen and no newline, it should trigger the cut.
// Our logic finds the last safe boundary before maxLogBufferLen.
// RuneStart(E4) at maxLogBufferLen-1 is true. FullRune(E4 at maxLogBufferLen-1 in payload[:maxLogBufferLen]) is false.
// So lastSafe should be maxLogBufferLen-1.
// The first maxLogBufferLen-1 bytes (all 'A') should be processed.
// The "你" should be in remainder.
if len(tl.remainder) != 3 {
t.Errorf("Expected remainder len 3 (the char '你'), got %d", len(tl.remainder))
}
}