Files
healthlog/internal/logging/logging_test.go
T
av 5ae0c5ff81 reindex: пересборка витрины проигрыванием журнала
- `healthlog reindex` собирает витрину из журнала (тела архива + учёт
  доставок) в ОТДЕЛЬНЫЙ файл базы, строго по `(received_at, id)`; рабочую
  базу читает без наката миграций и не трогает вовсе. Подмену делает
  человек при остановленном сервисе: переименование поверх открытого
  дескриптора портит базу молча.
- Журналом считается архив, а не таблица доставок: тело без учётной записи
  заводится заново (метка из ULID, размер и хеш по распакованному телу),
  запись без тела переносится, но не сворачивается. Оракул сходимости
  встроен — два отпечатка и «объектов было/стало»; пустой журнал успехом не
  считается.
- Прогон живого архива переехал на новый пакет: второго проигрывателя
  журнала в проекте не осталось, а его утверждение о ключе сна перестало
  быть константой, протухающей с каждой доставкой.
2026-08-02 09:07:46 +03:00

66 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logging
import (
"bytes"
"encoding/json"
"log/slog"
"strings"
"testing"
)
// Уровень — это адресат, а не громкость: DEBUG предназначен разработчику при
// отладке и в штатной работе наружу не выходит.
func TestУровеньОтсекаетНижние(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
log := NewTo(&buf, "warn", "json")
log.Debug("отладка")
log.Info("событие")
log.Warn("может стать проблемой")
out := buf.String()
if strings.Contains(out, "отладка") || strings.Contains(out, "событие") {
t.Errorf("уровень warn пропустил записи ниже себя: %s", out)
}
if !strings.Contains(out, "может стать проблемой") {
t.Errorf("запись уровня warn потерялась: %s", out)
}
}
// Время в логах — UTC: иначе порядок событий между машинами не сравнить.
func TestВремяВUTC(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
NewTo(&buf, "info", "json").Info("событие")
var rec map[string]any
if err := json.Unmarshal(buf.Bytes(), &rec); err != nil {
t.Fatalf("запись не JSON: %v (%s)", err, buf.String())
}
ts, _ := rec[slog.TimeKey].(string)
if !strings.HasSuffix(ts, "Z") {
t.Errorf("метка времени %q не в UTC", ts)
}
}
// Команды CLI пишут отчёт в stdout, поэтому их лог обязан идти в stderr —
// иначе отчёт не разобрать ни глазами, ни перенаправлением.
func TestNewErrПишетВStderrАNewВStdout(t *testing.T) {
t.Parallel()
// Прямой проверки потока здесь нет намеренно: подмена os.Stdout была бы
// мутацией глобала. Проверяем то, что от этих конструкторов зависит на
// самом деле, — что они собирают разные назначения и оба живые.
if New("info", "json") == nil || NewErr("info", "text") == nil {
t.Fatal("конструктор вернул nil")
}
var buf bytes.Buffer
NewTo(&buf, "info", "text").Info("событие", "ключ", "значение")
if !strings.Contains(buf.String(), "ключ=значение") {
t.Errorf("текстовый формат не применён: %s", buf.String())
}
}