...

Source file src/go.uber.org/zap/zaptest/logger_test.go

Documentation: go.uber.org/zap/zaptest

     1  // Copyright (c) 2017 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package zaptest
    22  
    23  import (
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"strings"
    28  	"testing"
    29  
    30  	"go.uber.org/zap"
    31  	"go.uber.org/zap/internal/ztest"
    32  	"go.uber.org/zap/zapcore"
    33  
    34  	"github.com/stretchr/testify/assert"
    35  )
    36  
    37  func TestTestLogger(t *testing.T) {
    38  	ts := newTestLogSpy(t)
    39  	defer ts.AssertPassed()
    40  
    41  	log := NewLogger(ts)
    42  
    43  	log.Info("received work order")
    44  	log.Debug("starting work")
    45  	log.Warn("work may fail")
    46  	log.Error("work failed", zap.Error(errors.New("great sadness")))
    47  
    48  	assert.Panics(t, func() {
    49  		log.Panic("failed to do work")
    50  	}, "log.Panic should panic")
    51  
    52  	ts.AssertMessages(
    53  		"INFO	received work order",
    54  		"DEBUG	starting work",
    55  		"WARN	work may fail",
    56  		`ERROR	work failed	{"error": "great sadness"}`,
    57  		"PANIC	failed to do work",
    58  	)
    59  }
    60  
    61  func TestTestLoggerSupportsLevels(t *testing.T) {
    62  	ts := newTestLogSpy(t)
    63  	defer ts.AssertPassed()
    64  
    65  	log := NewLogger(ts, Level(zap.WarnLevel))
    66  
    67  	log.Info("received work order")
    68  	log.Debug("starting work")
    69  	log.Warn("work may fail")
    70  	log.Error("work failed", zap.Error(errors.New("great sadness")))
    71  
    72  	assert.Panics(t, func() {
    73  		log.Panic("failed to do work")
    74  	}, "log.Panic should panic")
    75  
    76  	ts.AssertMessages(
    77  		"WARN	work may fail",
    78  		`ERROR	work failed	{"error": "great sadness"}`,
    79  		"PANIC	failed to do work",
    80  	)
    81  }
    82  
    83  func TestTestLoggerSupportsWrappedZapOptions(t *testing.T) {
    84  	ts := newTestLogSpy(t)
    85  	defer ts.AssertPassed()
    86  
    87  	log := NewLogger(ts, WrapOptions(zap.AddCaller(), zap.Fields(zap.String("k1", "v1"))))
    88  
    89  	log.Info("received work order")
    90  	log.Debug("starting work")
    91  	log.Warn("work may fail")
    92  	log.Error("work failed", zap.Error(errors.New("great sadness")))
    93  
    94  	assert.Panics(t, func() {
    95  		log.Panic("failed to do work")
    96  	}, "log.Panic should panic")
    97  
    98  	ts.AssertMessages(
    99  		`INFO	zaptest/logger_test.go:89	received work order	{"k1": "v1"}`,
   100  		`DEBUG	zaptest/logger_test.go:90	starting work	{"k1": "v1"}`,
   101  		`WARN	zaptest/logger_test.go:91	work may fail	{"k1": "v1"}`,
   102  		`ERROR	zaptest/logger_test.go:92	work failed	{"k1": "v1", "error": "great sadness"}`,
   103  		`PANIC	zaptest/logger_test.go:95	failed to do work	{"k1": "v1"}`,
   104  	)
   105  }
   106  
   107  func TestTestingWriter(t *testing.T) {
   108  	ts := newTestLogSpy(t)
   109  	w := NewTestingWriter(ts)
   110  
   111  	n, err := io.WriteString(w, "hello\n\n")
   112  	assert.NoError(t, err, "WriteString must not fail")
   113  	assert.Equal(t, 7, n)
   114  }
   115  
   116  func TestTestLoggerErrorOutput(t *testing.T) {
   117  	// This test verifies that the test logger logs internal messages to the
   118  	// testing.T and marks the test as failed.
   119  
   120  	ts := newTestLogSpy(t)
   121  	defer ts.AssertFailed()
   122  
   123  	log := NewLogger(ts)
   124  
   125  	// Replace with a core that fails.
   126  	log = log.WithOptions(zap.WrapCore(func(zapcore.Core) zapcore.Core {
   127  		return zapcore.NewCore(
   128  			zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
   129  			zapcore.Lock(zapcore.AddSync(ztest.FailWriter{})),
   130  			zapcore.DebugLevel,
   131  		)
   132  	}))
   133  
   134  	log.Info("foo") // this fails
   135  
   136  	if assert.Len(t, ts.Messages, 1, "expected a log message") {
   137  		assert.Regexp(t, `write error: failed`, ts.Messages[0])
   138  	}
   139  }
   140  
   141  // testLogSpy is a testing.TB that captures logged messages.
   142  type testLogSpy struct {
   143  	testing.TB
   144  
   145  	failed   bool
   146  	Messages []string
   147  }
   148  
   149  func newTestLogSpy(t testing.TB) *testLogSpy {
   150  	return &testLogSpy{TB: t}
   151  }
   152  
   153  func (t *testLogSpy) Fail() {
   154  	t.failed = true
   155  }
   156  
   157  func (t *testLogSpy) Failed() bool {
   158  	return t.failed
   159  }
   160  
   161  func (t *testLogSpy) FailNow() {
   162  	t.Fail()
   163  	t.TB.FailNow()
   164  }
   165  
   166  func (t *testLogSpy) Logf(format string, args ...interface{}) {
   167  	// Log messages are in the format,
   168  	//
   169  	//   2017-10-27T13:03:01.000-0700	DEBUG	your message here	{data here}
   170  	//
   171  	// We strip the first part of these messages because we can't really test
   172  	// for the timestamp from these tests.
   173  	m := fmt.Sprintf(format, args...)
   174  	m = m[strings.IndexByte(m, '\t')+1:]
   175  	t.Messages = append(t.Messages, m)
   176  	t.TB.Log(m)
   177  }
   178  
   179  func (t *testLogSpy) AssertMessages(msgs ...string) {
   180  	assert.Equal(t.TB, msgs, t.Messages, "logged messages did not match")
   181  }
   182  
   183  func (t *testLogSpy) AssertPassed() {
   184  	t.assertFailed(false, "expected test to pass")
   185  }
   186  
   187  func (t *testLogSpy) AssertFailed() {
   188  	t.assertFailed(true, "expected test to fail")
   189  }
   190  
   191  func (t *testLogSpy) assertFailed(v bool, msg string) {
   192  	assert.Equal(t.TB, v, t.failed, msg)
   193  }
   194  

View as plain text