github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/logging/logger_writers_test.go (about) 1 package logging_test 2 3 import ( 4 "fmt" 5 "io" 6 "testing" 7 "time" 8 9 "github.com/apex/log" 10 "github.com/heroku/color" 11 "github.com/sclevine/spec" 12 "github.com/sclevine/spec/report" 13 14 "github.com/buildpacks/pack/internal/style" 15 "github.com/buildpacks/pack/pkg/logging" 16 h "github.com/buildpacks/pack/testhelpers" 17 ) 18 19 func TestLogWithWriters(t *testing.T) { 20 spec.Run(t, "LogWithWriters", testLogWithWriters, spec.Parallel(), spec.Report(report.Terminal{})) 21 } 22 23 func testLogWithWriters(t *testing.T, when spec.G, it spec.S) { 24 var ( 25 logger *logging.LogWithWriters 26 outCons, errCons *color.Console 27 fOut, fErr func() string 28 timeFmt = "2006/01/02 15:04:05.000000" 29 testTime = "2019/05/15 01:01:01.000000" 30 ) 31 32 it.Before(func() { 33 outCons, fOut = h.MockWriterAndOutput() 34 errCons, fErr = h.MockWriterAndOutput() 35 logger = logging.NewLogWithWriters(outCons, errCons, logging.WithClock(func() time.Time { 36 clock, _ := time.Parse(timeFmt, testTime) 37 return clock 38 })) 39 }) 40 41 when("default", func() { 42 it("has no time and color", func() { 43 logger.Info(color.HiBlueString("test")) 44 h.AssertEq(t, fOut(), "\x1b[94mtest\x1b[0m\n") 45 }) 46 47 it("will not log debug messages", func() { 48 logger.Debug("debug_") 49 logger.Debugf("debugf") 50 51 output := fOut() 52 h.AssertNotContains(t, output, "debug_\n") 53 h.AssertNotContains(t, output, "debugf\n") 54 }) 55 56 it("logs info and warning messages to standard writer", func() { 57 logger.Info("info_") 58 logger.Infof("infof") 59 logger.Warn("warn_") 60 logger.Warnf("warnf") 61 62 output := fOut() 63 h.AssertContains(t, output, "info_\n") 64 h.AssertContains(t, output, "infof\n") 65 h.AssertContains(t, output, "warn_\n") 66 h.AssertContains(t, output, "warnf\n") 67 }) 68 69 it("logs error to error writer", func() { 70 logger.Error("error_") 71 logger.Errorf("errorf") 72 73 output := fErr() 74 h.AssertContains(t, output, "error_\n") 75 h.AssertContains(t, output, "errorf\n") 76 }) 77 78 it("will return correct writers", func() { 79 h.AssertSameInstance(t, logger.Writer(), outCons) 80 h.AssertSameInstance(t, logger.WriterForLevel(logging.DebugLevel), io.Discard) 81 }) 82 83 it("is only verbose for debug level", func() { 84 h.AssertFalse(t, logger.IsVerbose()) 85 86 logger.Level = log.DebugLevel 87 h.AssertTrue(t, logger.IsVerbose()) 88 }) 89 }) 90 91 when("time is set to true", func() { 92 it("time is logged in info", func() { 93 logger.WantTime(true) 94 logger.Info("test") 95 h.AssertEq(t, fOut(), "2019/05/15 01:01:01.000000 test\n") 96 }) 97 98 it("time is logged in error", func() { 99 logger.WantTime(true) 100 logger.Error("test") 101 h.AssertEq(t, fErr(), fmt.Sprintf("2019/05/15 01:01:01.000000 %stest\n", style.Error("ERROR: "))) 102 }) 103 104 when("WriterForLevel", func() { 105 it("time is logged in info", func() { 106 logger.WantTime(true) 107 writer := logger.WriterForLevel(logging.InfoLevel) 108 writer.Write([]byte("test\n")) 109 h.AssertEq(t, fOut(), "2019/05/15 01:01:01.000000 test\n") 110 }) 111 112 it("time is logged in error", func() { 113 logger.WantTime(true) 114 writer := logger.WriterForLevel(logging.ErrorLevel) 115 writer.Write([]byte("test\n")) 116 // The writer doesn't prepend the level 117 h.AssertEq(t, fErr(), "2019/05/15 01:01:01.000000 test\n") 118 }) 119 }) 120 }) 121 122 when("colors are disabled", func() { 123 it("don't display colors", func() { 124 outCons.DisableColors(true) 125 logger.Info(color.HiBlueString("test")) 126 h.AssertEq(t, fOut(), "test\n") 127 }) 128 }) 129 130 when("quiet is set to true", func() { 131 it.Before(func() { 132 logger.WantQuiet(true) 133 }) 134 135 it("will not log debug or info messages", func() { 136 logger.Debug("debug_") 137 logger.Debugf("debugf") 138 logger.Info("info_") 139 logger.Infof("infof") 140 141 output := fOut() 142 h.AssertNotContains(t, output, "debug_\n") 143 h.AssertNotContains(t, output, "debugf\n") 144 h.AssertNotContains(t, output, "info_\n") 145 h.AssertNotContains(t, output, "infof\n") 146 }) 147 148 it("logs warnings to standard writer", func() { 149 logger.Warn("warn_") 150 logger.Warnf("warnf") 151 152 output := fOut() 153 h.AssertContains(t, output, "warn_\n") 154 h.AssertContains(t, output, "warnf\n") 155 }) 156 157 it("logs error to error writer", func() { 158 logger.Error("error_") 159 logger.Errorf("errorf") 160 161 output := fErr() 162 h.AssertContains(t, output, "error_\n") 163 h.AssertContains(t, output, "errorf\n") 164 }) 165 166 it("will return correct writers", func() { 167 h.AssertSameInstance(t, logger.Writer(), outCons) 168 h.AssertSameInstance(t, logger.WriterForLevel(logging.DebugLevel), io.Discard) 169 h.AssertSameInstance(t, logger.WriterForLevel(logging.InfoLevel), io.Discard) 170 }) 171 }) 172 173 when("verbose is set to true", func() { 174 it.Before(func() { 175 logger.WantVerbose(true) 176 }) 177 178 it("all messages are logged", func() { 179 logger.Debug("debug_") 180 logger.Debugf("debugf") 181 logger.Info("info_") 182 logger.Infof("infof") 183 logger.Warn("warn_") 184 logger.Warnf("warnf") 185 186 output := fOut() 187 h.AssertContains(t, output, "debug_") 188 h.AssertContains(t, output, "debugf") 189 h.AssertContains(t, output, "info_") 190 h.AssertContains(t, output, "infof") 191 h.AssertContains(t, output, "warn_") 192 h.AssertContains(t, output, "warnf") 193 }) 194 195 it("logs error to error writer", func() { 196 logger.Error("error_") 197 logger.Errorf("errorf") 198 199 output := fErr() 200 h.AssertContains(t, output, "error_\n") 201 h.AssertContains(t, output, "errorf\n") 202 }) 203 204 it("will return correct writers", func() { 205 h.AssertSameInstance(t, logger.Writer(), outCons) 206 assertLogWriterHasOut(t, logger.WriterForLevel(logging.DebugLevel), outCons) 207 assertLogWriterHasOut(t, logger.WriterForLevel(logging.InfoLevel), outCons) 208 assertLogWriterHasOut(t, logger.WriterForLevel(logging.WarnLevel), outCons) 209 assertLogWriterHasOut(t, logger.WriterForLevel(logging.ErrorLevel), errCons) 210 }) 211 }) 212 213 it("will convert an empty string to a line feed", func() { 214 logger.Info("") 215 expected := "\n" 216 h.AssertEq(t, fOut(), expected) 217 }) 218 } 219 220 func assertLogWriterHasOut(t *testing.T, writer io.Writer, out io.Writer) { 221 logWriter, ok := writer.(hasWriter) 222 h.AssertTrue(t, ok) 223 h.AssertSameInstance(t, logWriter.Writer(), out) 224 } 225 226 type hasWriter interface { 227 Writer() io.Writer 228 }