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 }