perf(ui): кап буфера логов 10MB, O(1) вытеснение, дебаунс рендера
- LogBuffer: ленивое вытеснение через start + инкрементальный total убирает O(n^2) копирование entries[1:] при большом числе записей - LogPanel: лимит 10MB (maxLogBytes), перерисовка ленты коалесцируется (200мс) — строка не пересобирается на каждый append - build-publish-ui.ps1: корень проекта задаётся через PROJECT_PATH в .gitea-creds (относительно scripts/), без него — папка рядом со скриптом - тесты: живые записи Entries/Render, кап по байтам
This commit is contained in:
@@ -185,3 +185,47 @@ func TestLogBufferBounded(t *testing.T) {
|
||||
t.Fatalf("oversized entry text = %q, want %q", got, "efgh")
|
||||
}
|
||||
}
|
||||
|
||||
// Буфер держит только живые записи: ленивое вытеснение (start) не даёт
|
||||
// «мёртвым» записям попасть в Entries/Render.
|
||||
func TestLogBufferLiveEntriesOnly(t *testing.T) {
|
||||
b := NewLogBuffer(30)
|
||||
for i := 0; i < 3; i++ {
|
||||
b.Append(LogLevelInfo, "0123456789") // 10 байт + \n каждая
|
||||
}
|
||||
// сумма 33 > 30 → вытесняется первая запись, остаются две живые
|
||||
entries := b.Entries()
|
||||
if len(entries) != 2 {
|
||||
t.Fatalf("len(Entries) = %d, want 2 (мёртвая запись скрыта)", len(entries))
|
||||
}
|
||||
if entries[0].Text != "0123456789" || entries[1].Text != "0123456789" {
|
||||
t.Fatalf("unexpected live entries: %+v", entries)
|
||||
}
|
||||
if got, want := b.Render(allLevels()), "0123456789\n0123456789\n"; got != want {
|
||||
t.Fatalf("Render = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Кап считается по байтам текста, а не по числу записей: короткие записи
|
||||
// не вытесняются, пока их суммарный объём не превысит лимит.
|
||||
func TestLogBufferBytesCap(t *testing.T) {
|
||||
b := NewLogBuffer(100)
|
||||
for i := 0; i < 3; i++ {
|
||||
b.Append(LogLevelInfo, "hello") // 5 байт + \n
|
||||
}
|
||||
if got := len(b.Entries()); got != 3 {
|
||||
t.Fatalf("len(Entries) = %d, want 3 (все помещаются)", got)
|
||||
}
|
||||
|
||||
// одна большая запись вытесняет всё старое (live=1) и обрезается
|
||||
b2 := NewLogBuffer(8)
|
||||
b2.Append(LogLevelInfo, "short")
|
||||
b2.Append(LogLevelInfo, "verylongtext")
|
||||
entries := b2.Entries()
|
||||
if len(entries) != 1 {
|
||||
t.Fatalf("len(Entries) = %d, want 1", len(entries))
|
||||
}
|
||||
if entries[0].Text != "longtext" {
|
||||
t.Fatalf("oversized entry text = %q, want %q", entries[0].Text, "longtext")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user