write_syncer_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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
  21. import (
  22. "bytes"
  23. "errors"
  24. "testing"
  25. "io"
  26. "github.com/stretchr/testify/assert"
  27. "github.com/stretchr/testify/require"
  28. "go.uber.org/zap/internal/ztest"
  29. )
  30. type writeSyncSpy struct {
  31. io.Writer
  32. ztest.Syncer
  33. }
  34. func requireWriteWorks(t testing.TB, ws WriteSyncer) {
  35. n, err := ws.Write([]byte("foo"))
  36. require.NoError(t, err, "Unexpected error writing to WriteSyncer.")
  37. require.Equal(t, 3, n, "Wrote an unexpected number of bytes.")
  38. }
  39. func TestAddSyncWriteSyncer(t *testing.T) {
  40. buf := &bytes.Buffer{}
  41. concrete := &writeSyncSpy{Writer: buf}
  42. ws := AddSync(concrete)
  43. requireWriteWorks(t, ws)
  44. require.NoError(t, ws.Sync(), "Unexpected error syncing a WriteSyncer.")
  45. require.True(t, concrete.Called(), "Expected to dispatch to concrete type's Sync method.")
  46. concrete.SetError(errors.New("fail"))
  47. assert.Error(t, ws.Sync(), "Expected to propagate errors from concrete type's Sync method.")
  48. }
  49. func TestAddSyncWriter(t *testing.T) {
  50. // If we pass a plain io.Writer, make sure that we still get a WriteSyncer
  51. // with a no-op Sync.
  52. buf := &bytes.Buffer{}
  53. ws := AddSync(buf)
  54. requireWriteWorks(t, ws)
  55. assert.NoError(t, ws.Sync(), "Unexpected error calling a no-op Sync method.")
  56. }
  57. func TestNewMultiWriteSyncerWorksForSingleWriter(t *testing.T) {
  58. w := &ztest.Buffer{}
  59. ws := NewMultiWriteSyncer(w)
  60. assert.Equal(t, w, ws, "Expected NewMultiWriteSyncer to return the same WriteSyncer object for a single argument.")
  61. ws.Sync()
  62. assert.True(t, w.Called(), "Expected Sync to be called on the created WriteSyncer")
  63. }
  64. func TestMultiWriteSyncerWritesBoth(t *testing.T) {
  65. first := &bytes.Buffer{}
  66. second := &bytes.Buffer{}
  67. ws := NewMultiWriteSyncer(AddSync(first), AddSync(second))
  68. msg := []byte("dumbledore")
  69. n, err := ws.Write(msg)
  70. require.NoError(t, err, "Expected successful buffer write")
  71. assert.Equal(t, len(msg), n)
  72. assert.Equal(t, msg, first.Bytes())
  73. assert.Equal(t, msg, second.Bytes())
  74. }
  75. func TestMultiWriteSyncerFailsWrite(t *testing.T) {
  76. ws := NewMultiWriteSyncer(AddSync(&ztest.FailWriter{}))
  77. _, err := ws.Write([]byte("test"))
  78. assert.Error(t, err, "Write error should propagate")
  79. }
  80. func TestMultiWriteSyncerFailsShortWrite(t *testing.T) {
  81. ws := NewMultiWriteSyncer(AddSync(&ztest.ShortWriter{}))
  82. n, err := ws.Write([]byte("test"))
  83. assert.NoError(t, err, "Expected fake-success from short write")
  84. assert.Equal(t, 3, n, "Expected byte count to return from underlying writer")
  85. }
  86. func TestWritestoAllSyncs_EvenIfFirstErrors(t *testing.T) {
  87. failer := &ztest.FailWriter{}
  88. second := &bytes.Buffer{}
  89. ws := NewMultiWriteSyncer(AddSync(failer), AddSync(second))
  90. _, err := ws.Write([]byte("fail"))
  91. assert.Error(t, err, "Expected error from call to a writer that failed")
  92. assert.Equal(t, []byte("fail"), second.Bytes(), "Expected second sink to be written after first error")
  93. }
  94. func TestMultiWriteSyncerSync_PropagatesErrors(t *testing.T) {
  95. badsink := &ztest.Buffer{}
  96. badsink.SetError(errors.New("sink is full"))
  97. ws := NewMultiWriteSyncer(&ztest.Discarder{}, badsink)
  98. assert.Error(t, ws.Sync(), "Expected sync error to propagate")
  99. }
  100. func TestMultiWriteSyncerSync_NoErrorsOnDiscard(t *testing.T) {
  101. ws := NewMultiWriteSyncer(&ztest.Discarder{})
  102. assert.NoError(t, ws.Sync(), "Expected error-free sync to /dev/null")
  103. }
  104. func TestMultiWriteSyncerSync_AllCalled(t *testing.T) {
  105. failed, second := &ztest.Buffer{}, &ztest.Buffer{}
  106. failed.SetError(errors.New("disposal broken"))
  107. ws := NewMultiWriteSyncer(failed, second)
  108. assert.Error(t, ws.Sync(), "Expected first sink to fail")
  109. assert.True(t, failed.Called(), "Expected first sink to have Sync method called.")
  110. assert.True(t, second.Called(), "Expected call to Sync even with first failure.")
  111. }