carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package applog
2
3import (
4 "regexp"
5 "testing"
6 "time"
7)
8
9func at(sec int) time.Time { return time.Date(2026, 8, 10, 12, 0, sec, 0, time.UTC) }
10
11func TestFilterMatch(t *testing.T) {
12 rec := Record{
13 TS: at(30), Box: "b1", Host: "ledgerpay.bde.oncarlos.com",
14 Stream: StreamApp, Level: LevelWarn, Msg: "slow query on /checkout",
15 Fields: map[string]string{"request_id": "r1"},
16 }
17 cases := []struct {
18 name string
19 f Filter
20 want bool
21 }{
22 {"zero filter matches", Filter{}, true},
23 {"since inclusive window", Filter{Since: at(30)}, true},
24 {"since excludes older", Filter{Since: at(31)}, false},
25 {"until excludes newer", Filter{Until: at(29)}, false},
26 {"stream match", Filter{Stream: StreamApp}, true},
27 {"stream mismatch", Filter{Stream: StreamPlatform}, false},
28 {"host match", Filter{Host: "ledgerpay.bde.oncarlos.com"}, true},
29 {"host mismatch", Filter{Host: "other"}, false},
30 {"level threshold met", Filter{Level: LevelWarn}, true},
31 {"level below threshold", Filter{Level: LevelError}, false},
32 {"grep on msg", Filter{Grep: regexp.MustCompile(`checkout`)}, true},
33 {"grep miss", Filter{Grep: regexp.MustCompile(`nope`)}, false},
34 {"field match", Filter{Fields: map[string]string{"request_id": "r1"}}, true},
35 {"field mismatch", Filter{Fields: map[string]string{"request_id": "r2"}}, false},
36 {"field absent", Filter{Fields: map[string]string{"user": "u"}}, false},
37 }
38 for _, tc := range cases {
39 t.Run(tc.name, func(t *testing.T) {
40 if got := tc.f.Match(rec); got != tc.want {
41 t.Fatalf("Match = %v, want %v", got, tc.want)
42 }
43 })
44 }
45 // A record with NO level never satisfies a level threshold — levels are
46 // never guessed, so it cannot claim to clear a bar it never set.
47 unleveled := rec
48 unleveled.Level = ""
49 if (Filter{Level: LevelDebug}).Match(unleveled) {
50 t.Fatal("unleveled record passed a level threshold")
51 }
52}
53
54// TestMergeRecords: cross-box merge orders by (ts, box, seq) — per-box
55// order preserved, best-effort across boxes, deterministic tiebreak.
56func TestMergeRecords(t *testing.T) {
57 b1 := []Record{
58 {TS: at(1), Box: "b1", Seq: 10, Msg: "b1-first"},
59 {TS: at(3), Box: "b1", Seq: 11, Msg: "b1-second"},
60 }
61 b2 := []Record{
62 {TS: at(2), Box: "b2", Seq: 5, Msg: "b2-first"},
63 {TS: at(3), Box: "a0", Seq: 1, Msg: "a0-tiebreak"}, // same ts as b1-second
64 }
65 got := MergeRecords(b1, b2)
66 want := []string{"b1-first", "b2-first", "a0-tiebreak", "b1-second"}
67 if len(got) != len(want) {
68 t.Fatalf("merged %d records", len(got))
69 }
70 for i, m := range want {
71 if got[i].Msg != m {
72 t.Fatalf("order[%d] = %q, want %q (full: %+v)", i, got[i].Msg, m, got)
73 }
74 }
75}
76
77func TestParseSinceUntil(t *testing.T) {
78 now := time.Date(2026, 8, 10, 12, 0, 0, 0, time.UTC)
79 if got, err := ParseTimeArg("15m", now); err != nil || !got.Equal(now.Add(-15*time.Minute)) {
80 t.Fatalf("duration shorthand: %v %v", got, err)
81 }
82 if got, err := ParseTimeArg("2026-08-10T11:00:00Z", now); err != nil || got.Hour() != 11 {
83 t.Fatalf("RFC3339: %v %v", got, err)
84 }
85 if _, err := ParseTimeArg("yesterday-ish", now); err == nil {
86 t.Fatal("garbage parsed")
87 }
88 if got, err := ParseTimeArg("", now); err != nil || !got.IsZero() {
89 t.Fatalf("empty should be zero time, no error: %v %v", got, err)
90 }
91}
92