1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package zapcore_test
22
23 import (
24 "errors"
25 "os"
26 "testing"
27 "time"
28
29 "go.uber.org/zap/internal/ztest"
30
31 . "go.uber.org/zap/zapcore"
32
33 "github.com/stretchr/testify/assert"
34 "github.com/stretchr/testify/require"
35 )
36
37 func makeInt64Field(key string, val int) Field {
38 return Field{Type: Int64Type, Integer: int64(val), Key: key}
39 }
40
41 func TestNopCore(t *testing.T) {
42 entry := Entry{
43 Message: "test",
44 Level: InfoLevel,
45 Time: time.Now(),
46 LoggerName: "main",
47 Stack: "fake-stack",
48 }
49 ce := &CheckedEntry{}
50
51 allLevels := []Level{
52 DebugLevel,
53 InfoLevel,
54 WarnLevel,
55 ErrorLevel,
56 DPanicLevel,
57 PanicLevel,
58 FatalLevel,
59 }
60 core := NewNopCore()
61 assert.Equal(t, core, core.With([]Field{makeInt64Field("k", 42)}), "Expected no-op With.")
62 for _, level := range allLevels {
63 assert.False(t, core.Enabled(level), "Expected all levels to be disabled in no-op core.")
64 assert.Equal(t, ce, core.Check(entry, ce), "Expected no-op Check to return checked entry unchanged.")
65 assert.NoError(t, core.Write(entry, nil), "Expected no-op Writes to always succeed.")
66 assert.NoError(t, core.Sync(), "Expected no-op Syncs to always succeed.")
67 }
68 }
69
70 func TestIOCore(t *testing.T) {
71 temp, err := os.CreateTemp(t.TempDir(), "test.log")
72 require.NoError(t, err)
73
74
75
76 cfg := testEncoderConfig()
77 cfg.TimeKey = ""
78
79 core := NewCore(
80 NewJSONEncoder(cfg),
81 temp,
82 InfoLevel,
83 ).With([]Field{makeInt64Field("k", 1)})
84 defer assert.NoError(t, core.Sync(), "Expected Syncing a temp file to succeed.")
85
86 t.Run("LevelOf", func(t *testing.T) {
87 assert.Equal(t, InfoLevel, LevelOf(core), "Incorrect Core Level")
88 })
89
90 if ce := core.Check(Entry{Level: DebugLevel, Message: "debug"}, nil); ce != nil {
91 ce.Write(makeInt64Field("k", 2))
92 }
93 if ce := core.Check(Entry{Level: InfoLevel, Message: "info"}, nil); ce != nil {
94 ce.Write(makeInt64Field("k", 3))
95 }
96 if ce := core.Check(Entry{Level: WarnLevel, Message: "warn"}, nil); ce != nil {
97 ce.Write(makeInt64Field("k", 4))
98 }
99
100 logged, err := os.ReadFile(temp.Name())
101 require.NoError(t, err, "Failed to read from temp file.")
102 require.Equal(
103 t,
104 `{"level":"info","msg":"info","k":1,"k":3}`+"\n"+
105 `{"level":"warn","msg":"warn","k":1,"k":4}`+"\n",
106 string(logged),
107 "Unexpected log output.",
108 )
109 }
110
111 func TestIOCoreSyncFail(t *testing.T) {
112 sink := &ztest.Discarder{}
113 err := errors.New("failed")
114 sink.SetError(err)
115
116 core := NewCore(
117 NewJSONEncoder(testEncoderConfig()),
118 sink,
119 DebugLevel,
120 )
121
122 assert.Equal(
123 t,
124 err,
125 core.Sync(),
126 "Expected core.Sync to return errors from underlying WriteSyncer.",
127 )
128 }
129
130 func TestIOCoreSyncsOutput(t *testing.T) {
131 tests := []struct {
132 entry Entry
133 shouldSync bool
134 }{
135 {Entry{Level: DebugLevel}, false},
136 {Entry{Level: InfoLevel}, false},
137 {Entry{Level: WarnLevel}, false},
138 {Entry{Level: ErrorLevel}, false},
139 {Entry{Level: DPanicLevel}, true},
140 {Entry{Level: PanicLevel}, true},
141 {Entry{Level: FatalLevel}, true},
142 }
143
144 for _, tt := range tests {
145 sink := &ztest.Discarder{}
146 core := NewCore(
147 NewJSONEncoder(testEncoderConfig()),
148 sink,
149 DebugLevel,
150 )
151
152 assert.NoError(t, core.Write(tt.entry, nil), "Unexpected error writing entry.")
153 assert.Equal(t, tt.shouldSync, sink.Called(), "Incorrect Sync behavior.")
154 }
155 }
156
157 func TestIOCoreWriteFailure(t *testing.T) {
158 core := NewCore(
159 NewJSONEncoder(testEncoderConfig()),
160 Lock(&ztest.FailWriter{}),
161 DebugLevel,
162 )
163 err := core.Write(Entry{}, nil)
164
165 assert.Error(t, err, "Expected writing Entry to fail.")
166 }
167
View as plain text