(t *testing.T)
| 142 | } |
| 143 | |
| 144 | func TestAddDebugFileSink_SoftCap(t *testing.T) { |
| 145 | SetRedactor(nil) |
| 146 | console := &syncBuffer{} |
| 147 | logger := newConsoleLogger(console, zap.InfoLevel) |
| 148 | |
| 149 | tmp, err := os.CreateTemp(t.TempDir(), "cap-*.log") |
| 150 | if err != nil { |
| 151 | t.Fatalf("create temp: %v", err) |
| 152 | } |
| 153 | defer tmp.Close() |
| 154 | |
| 155 | const cap = int64(2 * 1024) // 2 KiB |
| 156 | wrapped, sink := AddDebugFileSink(logger, tmp, cap) |
| 157 | |
| 158 | // Each Debug entry will be on the order of 100 bytes encoded; emit |
| 159 | // enough to comfortably exceed 2 KiB. |
| 160 | payload := strings.Repeat("x", 200) |
| 161 | for i := 0; i < 200; i++ { |
| 162 | wrapped.Debug(payload) |
| 163 | } |
| 164 | if err := sink.Flush(); err != nil { |
| 165 | t.Fatalf("flush: %v", err) |
| 166 | } |
| 167 | if !sink.Capped() { |
| 168 | t.Fatalf("expected sink to report capped, got false") |
| 169 | } |
| 170 | if got := sink.Written(); got > cap { |
| 171 | t.Errorf("written bytes exceed cap: got %d, cap %d", got, cap) |
| 172 | } |
| 173 | info, err := os.Stat(tmp.Name()) |
| 174 | if err != nil { |
| 175 | t.Fatalf("stat: %v", err) |
| 176 | } |
| 177 | if info.Size() > cap { |
| 178 | t.Errorf("file size exceeds cap: got %d, cap %d", info.Size(), cap) |
| 179 | } |
| 180 | |
| 181 | // Further writes after the cap must not error and must not grow the file. |
| 182 | wrapped.Debug("post-cap-line") |
| 183 | if err := sink.Flush(); err != nil { |
| 184 | t.Fatalf("flush after cap: %v", err) |
| 185 | } |
| 186 | info2, _ := os.Stat(tmp.Name()) |
| 187 | if info2.Size() != info.Size() { |
| 188 | t.Errorf("file grew past cap: was %d, now %d", info.Size(), info2.Size()) |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | // countingRedactor counts how many times each redaction hook fires. |
| 193 | // Used to assert the redaction-once invariant — a single outer |
nothing calls this directly
no test coverage detected