- POST /api/v1/ingest: токен, лимит тела, gzip, durable-запись тела в сырой архив, учёт доставки в SQLite - код ответа отражает доставку, а не разбор: битый JSON — 400, непонятое содержимое — 200, данные уже сохранены и доразберутся позже - сохраняется полный набор заголовков запроса с вычисткой секретов по имени и по совпадению значения с токеном
112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
package config_test
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.vakhrushev.me/av/healthlog/internal/config"
|
|
)
|
|
|
|
// Отсутствующий конфиг — не ошибка: локальный запуск должен работать «из
|
|
// коробки», без файла.
|
|
func TestLoadMissingFileUsesDefaults(t *testing.T) {
|
|
cfg, err := config.Load(filepath.Join(t.TempDir(), "нет-такого.toml"))
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
|
|
if cfg.Server.Addr != ":8080" {
|
|
t.Errorf("addr = %q, ожидалось \":8080\"", cfg.Server.Addr)
|
|
}
|
|
if cfg.Ingest.MaxBodyMB != 64 {
|
|
t.Errorf("max_body_mb = %d, ожидалось 64", cfg.Ingest.MaxBodyMB)
|
|
}
|
|
if cfg.Server.ReadTimeout.D() != 5*time.Minute {
|
|
t.Errorf("read_timeout = %v, ожидалось 5m", cfg.Server.ReadTimeout.D())
|
|
}
|
|
if len(cfg.Auth.WriteTokens) != 0 {
|
|
t.Errorf("write_tokens = %v, ожидался пустой список", cfg.Auth.WriteTokens)
|
|
}
|
|
}
|
|
|
|
func TestLoadReadsFile(t *testing.T) {
|
|
path := writeConfig(t, `
|
|
[server]
|
|
addr = "127.0.0.1:9000"
|
|
read_timeout = "1m"
|
|
|
|
[auth]
|
|
write_tokens = ["секрет"]
|
|
|
|
[ingest]
|
|
max_body_mb = 8
|
|
|
|
[log]
|
|
level = "debug"
|
|
format = "text"
|
|
`)
|
|
|
|
cfg, err := config.Load(path)
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
|
|
if cfg.Server.Addr != "127.0.0.1:9000" {
|
|
t.Errorf("addr = %q", cfg.Server.Addr)
|
|
}
|
|
if cfg.Server.ReadTimeout.D() != time.Minute {
|
|
t.Errorf("read_timeout = %v", cfg.Server.ReadTimeout.D())
|
|
}
|
|
if cfg.Ingest.MaxBodyMB != 8 {
|
|
t.Errorf("max_body_mb = %d", cfg.Ingest.MaxBodyMB)
|
|
}
|
|
if len(cfg.Auth.WriteTokens) != 1 || cfg.Auth.WriteTokens[0] != "секрет" {
|
|
t.Errorf("write_tokens = %v", cfg.Auth.WriteTokens)
|
|
}
|
|
}
|
|
|
|
// Валидация собирает все проблемы разом (errors.Join), а не чинится по одной
|
|
// за перезапуск.
|
|
func TestValidateReportsAllProblems(t *testing.T) {
|
|
path := writeConfig(t, `
|
|
[ingest]
|
|
max_body_mb = -1
|
|
|
|
[auth]
|
|
write_tokens = [" "]
|
|
|
|
[log]
|
|
level = "нет-такого"
|
|
format = "yaml"
|
|
`)
|
|
|
|
_, err := config.Load(path)
|
|
if err == nil {
|
|
t.Fatal("ожидалась ошибка валидации")
|
|
}
|
|
|
|
for _, want := range []error{config.ErrOutOfRange, config.ErrUnknownValue, config.ErrEmptyToken} {
|
|
if !errors.Is(err, want) {
|
|
t.Errorf("ошибка не содержит %v: %v", want, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLoadRejectsBrokenTOML(t *testing.T) {
|
|
if _, err := config.Load(writeConfig(t, "это не toml =")); err == nil {
|
|
t.Fatal("ожидалась ошибка разбора")
|
|
}
|
|
}
|
|
|
|
func writeConfig(t *testing.T, body string) string {
|
|
t.Helper()
|
|
path := filepath.Join(t.TempDir(), "config.toml")
|
|
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
|
|
t.Fatalf("подготовка конфига: %v", err)
|
|
}
|
|
return path
|
|
}
|