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  }