tee_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright (c) 2016 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. package zapcore_test
  21. import (
  22. "errors"
  23. "testing"
  24. "go.uber.org/zap/internal/ztest"
  25. . "go.uber.org/zap/zapcore"
  26. "go.uber.org/zap/zaptest/observer"
  27. "github.com/stretchr/testify/assert"
  28. )
  29. func withTee(f func(core Core, debugLogs, warnLogs *observer.ObservedLogs)) {
  30. debugLogger, debugLogs := observer.New(DebugLevel)
  31. warnLogger, warnLogs := observer.New(WarnLevel)
  32. tee := NewTee(debugLogger, warnLogger)
  33. f(tee, debugLogs, warnLogs)
  34. }
  35. func TestTeeUnusualInput(t *testing.T) {
  36. // Verify that Tee handles receiving one and no inputs correctly.
  37. t.Run("one input", func(t *testing.T) {
  38. obs, _ := observer.New(DebugLevel)
  39. assert.Equal(t, obs, NewTee(obs), "Expected to return single inputs unchanged.")
  40. })
  41. t.Run("no input", func(t *testing.T) {
  42. assert.Equal(t, NewNopCore(), NewTee(), "Expected to return NopCore.")
  43. })
  44. }
  45. func TestTeeCheck(t *testing.T) {
  46. withTee(func(tee Core, debugLogs, warnLogs *observer.ObservedLogs) {
  47. debugEntry := Entry{Level: DebugLevel, Message: "log-at-debug"}
  48. infoEntry := Entry{Level: InfoLevel, Message: "log-at-info"}
  49. warnEntry := Entry{Level: WarnLevel, Message: "log-at-warn"}
  50. errorEntry := Entry{Level: ErrorLevel, Message: "log-at-error"}
  51. for _, ent := range []Entry{debugEntry, infoEntry, warnEntry, errorEntry} {
  52. if ce := tee.Check(ent, nil); ce != nil {
  53. ce.Write()
  54. }
  55. }
  56. assert.Equal(t, []observer.LoggedEntry{
  57. {Entry: debugEntry, Context: []Field{}},
  58. {Entry: infoEntry, Context: []Field{}},
  59. {Entry: warnEntry, Context: []Field{}},
  60. {Entry: errorEntry, Context: []Field{}},
  61. }, debugLogs.All())
  62. assert.Equal(t, []observer.LoggedEntry{
  63. {Entry: warnEntry, Context: []Field{}},
  64. {Entry: errorEntry, Context: []Field{}},
  65. }, warnLogs.All())
  66. })
  67. }
  68. func TestTeeWrite(t *testing.T) {
  69. // Calling the tee's Write method directly should always log, regardless of
  70. // the configured level.
  71. withTee(func(tee Core, debugLogs, warnLogs *observer.ObservedLogs) {
  72. debugEntry := Entry{Level: DebugLevel, Message: "log-at-debug"}
  73. warnEntry := Entry{Level: WarnLevel, Message: "log-at-warn"}
  74. for _, ent := range []Entry{debugEntry, warnEntry} {
  75. tee.Write(ent, nil)
  76. }
  77. for _, logs := range []*observer.ObservedLogs{debugLogs, warnLogs} {
  78. assert.Equal(t, []observer.LoggedEntry{
  79. {Entry: debugEntry, Context: []Field{}},
  80. {Entry: warnEntry, Context: []Field{}},
  81. }, logs.All())
  82. }
  83. })
  84. }
  85. func TestTeeWith(t *testing.T) {
  86. withTee(func(tee Core, debugLogs, warnLogs *observer.ObservedLogs) {
  87. f := makeInt64Field("k", 42)
  88. tee = tee.With([]Field{f})
  89. ent := Entry{Level: WarnLevel, Message: "log-at-warn"}
  90. if ce := tee.Check(ent, nil); ce != nil {
  91. ce.Write()
  92. }
  93. for _, logs := range []*observer.ObservedLogs{debugLogs, warnLogs} {
  94. assert.Equal(t, []observer.LoggedEntry{
  95. {Entry: ent, Context: []Field{f}},
  96. }, logs.All())
  97. }
  98. })
  99. }
  100. func TestTeeEnabled(t *testing.T) {
  101. infoLogger, _ := observer.New(InfoLevel)
  102. warnLogger, _ := observer.New(WarnLevel)
  103. tee := NewTee(infoLogger, warnLogger)
  104. tests := []struct {
  105. lvl Level
  106. enabled bool
  107. }{
  108. {DebugLevel, false},
  109. {InfoLevel, true},
  110. {WarnLevel, true},
  111. {ErrorLevel, true},
  112. {DPanicLevel, true},
  113. {PanicLevel, true},
  114. {FatalLevel, true},
  115. }
  116. for _, tt := range tests {
  117. assert.Equal(t, tt.enabled, tee.Enabled(tt.lvl), "Unexpected Enabled result for level %s.", tt.lvl)
  118. }
  119. }
  120. func TestTeeSync(t *testing.T) {
  121. infoLogger, _ := observer.New(InfoLevel)
  122. warnLogger, _ := observer.New(WarnLevel)
  123. tee := NewTee(infoLogger, warnLogger)
  124. assert.NoError(t, tee.Sync(), "Unexpected error from Syncing a tee.")
  125. sink := &ztest.Discarder{}
  126. err := errors.New("failed")
  127. sink.SetError(err)
  128. noSync := NewCore(
  129. NewJSONEncoder(testEncoderConfig()),
  130. sink,
  131. DebugLevel,
  132. )
  133. tee = NewTee(tee, noSync)
  134. assert.Equal(t, err, tee.Sync(), "Expected an error when part of tee can't Sync.")
  135. }