aboutsummaryrefslogtreecommitdiff
path: root/internal/config/load_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-11 14:47:10 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-11 15:01:57 +0200
commit42b02c47be9b285099203e44a2570636d4ca6f03 (patch)
tree82bcb9e19bd886f36e1ca7b2d94a204c988f1fd1 /internal/config/load_test.go
downloadkrino-42b02c47be9b285099203e44a2570636d4ca6f03.tar.gz
krino-42b02c47be9b285099203e44a2570636d4ca6f03.zip
krino: foundation — sexp reader, config language, init/new/check
Diffstat (limited to 'internal/config/load_test.go')
-rw-r--r--internal/config/load_test.go106
1 files changed, 106 insertions, 0 deletions
diff --git a/internal/config/load_test.go b/internal/config/load_test.go
new file mode 100644
index 0000000..be72fc0
--- /dev/null
+++ b/internal/config/load_test.go
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package config
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+ "time"
+)
+
+// writeFiles creates each file under root, making directories as needed.
+func writeFiles(t *testing.T, root string, files map[string]string) {
+ t.Helper()
+ for name, body := range files {
+ p := filepath.Join(root, name)
+ if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.WriteFile(p, []byte(body), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ }
+}
+
+func TestLoad(t *testing.T) {
+ root := t.TempDir()
+ writeFiles(t, root, map[string]string{
+ "krino.conf": `(include "a" "b") (defaults (min-age 5m))`,
+ "dirs/a.conf": `(path "/tmp/a") (min-age 1m) (rule "r" (stop))`,
+ "dirs/b.conf": `(path "/tmp/b") (rule "r" (stop))`,
+ })
+ main := filepath.Join(root, "krino.conf")
+ cfg, errs := Load(main)
+ if len(errs) > 0 {
+ t.Fatal(errs)
+ }
+ if len(cfg.Dirs) != 2 || cfg.Dirs[0].Name != "a" || cfg.Dirs[1].Path != "/tmp/b" {
+ t.Fatalf("dirs = %+v", cfg.Dirs)
+ }
+ if got := cfg.Resolved(cfg.Dirs[0]).MinAge; got != time.Minute {
+ t.Errorf("a min-age = %v, want the directory's 1m", got)
+ }
+ if got := cfg.Resolved(cfg.Dirs[1]).MinAge; got != 5*time.Minute {
+ t.Errorf("b min-age = %v, want the default 5m", got)
+ }
+ cfg, errs = Load(main, "b")
+ if len(errs) > 0 || len(cfg.Dirs) != 1 || cfg.Dirs[0].Name != "b" {
+ t.Fatalf("Load(b) = %+v, %v", cfg, errs)
+ }
+}
+
+func TestLoadErrors(t *testing.T) {
+ root := t.TempDir()
+ main := filepath.Join(root, "krino.conf")
+ cfg, errs := Load(main)
+ if cfg != nil || len(errs) != 1 || errs[0].Error() != main+": not found; create it with: krino init" {
+ t.Fatalf("missing main file: %v", errs)
+ }
+ writeFiles(t, root, map[string]string{"krino.conf": "(include \"gone\")\n"})
+ _, errs = Load(main)
+ want := fmt.Sprintf(`%s:1:10: included "gone", but %s does not exist; create it with: krino new gone PATH`,
+ main, filepath.Join(root, "dirs", "gone.conf"))
+ if len(errs) != 1 || errs[0].Error() != want {
+ t.Fatalf("missing dir file:\n got %v\n want %s", errs, want)
+ }
+ _, errs = Load(main, "other")
+ if len(errs) != 1 || !strings.HasSuffix(errs[0].Error(), `: "other" is not in include`) {
+ t.Fatalf("unknown name: %v", errs)
+ }
+}
+
+// TestLoadSyntaxErrorStopsAtOneDiag is item C: a krino.conf that fails to
+// parse must report only the syntax error, not also "not in include" for
+// names the caller asked for.
+func TestLoadSyntaxErrorStopsAtOneDiag(t *testing.T) {
+ root := t.TempDir()
+ writeFiles(t, root, map[string]string{"krino.conf": `(include "dl"`})
+ main := filepath.Join(root, "krino.conf")
+ _, errs := Load(main, "dl")
+ if len(errs) != 1 {
+ t.Fatalf("errs = %v, want exactly one diag", errs)
+ }
+ want := fmt.Sprintf(`%s:1:1: "(" never closed: (include "dl")`, main)
+ if errs[0].Error() != want {
+ t.Fatalf("got %s\nwant %s", errs[0], want)
+ }
+}
+
+func TestDefaultFileAndLogFile(t *testing.T) {
+ t.Setenv("XDG_CONFIG_HOME", "/conf")
+ t.Setenv("XDG_STATE_HOME", "/state")
+ if got := DefaultFile(); got != "/conf/krino/krino.conf" {
+ t.Errorf("DefaultFile() = %q", got)
+ }
+ c := &Config{Main: &Main{}}
+ if got := c.LogFile(); got != "/state/krino/krino.log" {
+ t.Errorf("LogFile() = %q", got)
+ }
+ c.Main.Log = "/x.log"
+ if got := c.LogFile(); got != "/x.log" {
+ t.Errorf("LogFile() = %q", got)
+ }
+}