blob: f1465ad9a90363532f735556a0b52bafffb73229 [file] [log] [blame]
Serge Bazanski5faa2fc2020-09-07 14:09:30 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package logtree
18
19import (
20 "fmt"
Serge Bazanskif68153c2020-10-26 13:54:37 +010021 "log"
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020022 "strings"
23 "testing"
24 "time"
25)
26
27func TestBacklog(t *testing.T) {
28 tree := New()
29 tree.MustLeveledFor("main").Info("hello, main!")
30 tree.MustLeveledFor("main.foo").Info("hello, main.foo!")
31 tree.MustLeveledFor("main.bar").Info("hello, main.bar!")
32 tree.MustLeveledFor("aux").Info("hello, aux!")
Serge Bazanskif68153c2020-10-26 13:54:37 +010033 // No newline at the last entry - shouldn't get propagated to the backlog.
34 fmt.Fprintf(tree.MustRawFor("aux.process"), "processing foo\nprocessing bar\nbaz")
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020035
36 expect := func(dn DN, entries ...string) string {
Serge Bazanskif68153c2020-10-26 13:54:37 +010037 res, err := tree.Read(dn, WithChildren(), WithBacklog(BacklogAllAvailable))
38 if err != nil {
39 t.Fatalf("Read: %v", err)
40 }
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020041 if want, got := len(entries), len(res.Backlog); want != got {
42 t.Fatalf("wanted %d backlog entries, got %d", want, got)
43 }
44 got := make(map[string]bool)
45 for _, entry := range res.Backlog {
Serge Bazanskif68153c2020-10-26 13:54:37 +010046 if entry.Leveled != nil {
47 got[entry.Leveled.Message()] = true
48 }
49 if entry.Raw != nil {
50 got[entry.Raw.Data] = true
51 }
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020052 }
53 for _, entry := range entries {
54 if !got[entry] {
55 return fmt.Sprintf("missing entry %q", entry)
56 }
57 }
58 return ""
59 }
60
61 if res := expect("main", "hello, main!", "hello, main.foo!", "hello, main.bar!"); res != "" {
62 t.Errorf("retrieval at main failed: %s", res)
63 }
Serge Bazanskif68153c2020-10-26 13:54:37 +010064 if res := expect("", "hello, main!", "hello, main.foo!", "hello, main.bar!", "hello, aux!", "processing foo", "processing bar"); res != "" {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020065 t.Errorf("retrieval at root failed: %s", res)
66 }
Serge Bazanskif68153c2020-10-26 13:54:37 +010067 if res := expect("aux", "hello, aux!", "processing foo", "processing bar"); res != "" {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020068 t.Errorf("retrieval at aux failed: %s", res)
69 }
70}
71
72func TestStream(t *testing.T) {
73 tree := New()
74 tree.MustLeveledFor("main").Info("hello, backlog")
Serge Bazanskif68153c2020-10-26 13:54:37 +010075 fmt.Fprintf(tree.MustRawFor("main.process"), "hello, raw backlog\n")
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020076
Serge Bazanskif68153c2020-10-26 13:54:37 +010077 log.Printf("read start")
78 res, err := tree.Read("", WithBacklog(BacklogAllAvailable), WithChildren(), WithStream())
79 if err != nil {
80 t.Fatalf("Read: %v", err)
81 }
82 log.Printf("read done")
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020083 defer res.Close()
Serge Bazanskif68153c2020-10-26 13:54:37 +010084 if want, got := 2, len(res.Backlog); want != got {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020085 t.Errorf("wanted %d backlog item, got %d", want, got)
86 }
87
88 tree.MustLeveledFor("main").Info("hello, stream")
Serge Bazanskif68153c2020-10-26 13:54:37 +010089 fmt.Fprintf(tree.MustRawFor("main.raw"), "hello, raw stream\n")
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020090
Serge Bazanskif68153c2020-10-26 13:54:37 +010091 entries := make(map[string]bool)
92 timeout := time.After(time.Second * 1)
93 for {
94 done := false
95 select {
96 case <-timeout:
97 done = true
98 case p := <-res.Stream:
99 if p.Leveled != nil {
100 entries[p.Leveled.Message()] = true
101 }
102 if p.Raw != nil {
103 entries[p.Raw.Data] = true
104 }
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200105 }
Serge Bazanskif68153c2020-10-26 13:54:37 +0100106 if done {
107 break
108 }
109 }
110 if entry := "hello, stream"; !entries[entry] {
111 t.Errorf("Missing entry %q", entry)
112 }
113 if entry := "hello, raw stream"; !entries[entry] {
114 t.Errorf("Missing entry %q", entry)
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200115 }
116}
117
118func TestVerbose(t *testing.T) {
119 tree := New()
120
121 tree.MustLeveledFor("main").V(10).Info("this shouldn't get logged")
122
Serge Bazanskif68153c2020-10-26 13:54:37 +0100123 reader, err := tree.Read("", WithBacklog(BacklogAllAvailable), WithChildren())
124 if err != nil {
125 t.Fatalf("Read: %v", err)
126 }
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200127 if want, got := 0, len(reader.Backlog); want != got {
128 t.Fatalf("expected nothing to be logged, got %+v", reader.Backlog)
129 }
130
131 tree.SetVerbosity("main", 10)
132 tree.MustLeveledFor("main").V(10).Info("this should get logged")
133
Serge Bazanskif68153c2020-10-26 13:54:37 +0100134 reader, err = tree.Read("", WithBacklog(BacklogAllAvailable), WithChildren())
135 if err != nil {
136 t.Fatalf("Read: %v", err)
137 }
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200138 if want, got := 1, len(reader.Backlog); want != got {
139 t.Fatalf("expected %d entries to get logged, got %d", want, got)
140 }
141}
142
143func TestMetadata(t *testing.T) {
144 tree := New()
145 tree.MustLeveledFor("main").Error("i am an error")
146 tree.MustLeveledFor("main").Warning("i am a warning")
147 tree.MustLeveledFor("main").Info("i am informative")
148 tree.MustLeveledFor("main").V(0).Info("i am a zero-level debug")
149
Serge Bazanskif68153c2020-10-26 13:54:37 +0100150 reader, err := tree.Read("", WithChildren(), WithBacklog(BacklogAllAvailable))
151 if err != nil {
152 t.Fatalf("Read: %v", err)
153 }
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200154 if want, got := 4, len(reader.Backlog); want != got {
155 t.Fatalf("expected %d entries, got %d", want, got)
156 }
157
158 for _, te := range []struct {
159 ix int
160 severity Severity
161 message string
162 }{
163 {0, ERROR, "i am an error"},
164 {1, WARNING, "i am a warning"},
165 {2, INFO, "i am informative"},
166 {3, INFO, "i am a zero-level debug"},
167 } {
168 p := reader.Backlog[te.ix]
Serge Bazanskif68153c2020-10-26 13:54:37 +0100169 if want, got := te.severity, p.Leveled.Severity(); want != got {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200170 t.Errorf("wanted element %d to have severity %s, got %s", te.ix, want, got)
171 }
Serge Bazanskif68153c2020-10-26 13:54:37 +0100172 if want, got := te.message, p.Leveled.Message(); want != got {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200173 t.Errorf("wanted element %d to have message %q, got %q", te.ix, want, got)
174 }
Serge Bazanskif68153c2020-10-26 13:54:37 +0100175 if want, got := "logtree_test.go", strings.Split(p.Leveled.Location(), ":")[0]; want != got {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200176 t.Errorf("wanted element %d to have file %q, got %q", te.ix, want, got)
177 }
178 }
179}
180
181func TestSeverity(t *testing.T) {
182 tree := New()
183 tree.MustLeveledFor("main").Error("i am an error")
184 tree.MustLeveledFor("main").Warning("i am a warning")
185 tree.MustLeveledFor("main").Info("i am informative")
186 tree.MustLeveledFor("main").V(0).Info("i am a zero-level debug")
187
Serge Bazanskif68153c2020-10-26 13:54:37 +0100188 reader, err := tree.Read("main", WithBacklog(BacklogAllAvailable), LeveledWithMinimumSeverity(WARNING))
189 if err != nil {
190 t.Fatalf("Read: %v", err)
191 }
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200192 if want, got := 2, len(reader.Backlog); want != got {
193 t.Fatalf("wanted %d entries, got %d", want, got)
194 }
Serge Bazanskif68153c2020-10-26 13:54:37 +0100195 if want, got := "i am an error", reader.Backlog[0].Leveled.Message(); want != got {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200196 t.Fatalf("wanted entry %q, got %q", want, got)
197 }
Serge Bazanskif68153c2020-10-26 13:54:37 +0100198 if want, got := "i am a warning", reader.Backlog[1].Leveled.Message(); want != got {
Serge Bazanski5faa2fc2020-09-07 14:09:30 +0200199 t.Fatalf("wanted entry %q, got %q", want, got)
200 }
201}