github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/broadcaster/unbuffered_test.go (about) 1 package broadcaster // import "github.com/demonoid81/moby/pkg/broadcaster" 2 3 import ( 4 "bytes" 5 "errors" 6 "strings" 7 "testing" 8 ) 9 10 type dummyWriter struct { 11 buffer bytes.Buffer 12 failOnWrite bool 13 } 14 15 func (dw *dummyWriter) Write(p []byte) (n int, err error) { 16 if dw.failOnWrite { 17 return 0, errors.New("Fake fail") 18 } 19 return dw.buffer.Write(p) 20 } 21 22 func (dw *dummyWriter) String() string { 23 return dw.buffer.String() 24 } 25 26 func (dw *dummyWriter) Close() error { 27 return nil 28 } 29 30 func TestUnbuffered(t *testing.T) { 31 writer := new(Unbuffered) 32 33 // Test 1: Both bufferA and bufferB should contain "foo" 34 bufferA := &dummyWriter{} 35 writer.Add(bufferA) 36 bufferB := &dummyWriter{} 37 writer.Add(bufferB) 38 writer.Write([]byte("foo")) 39 40 if bufferA.String() != "foo" { 41 t.Errorf("Buffer contains %v", bufferA.String()) 42 } 43 44 if bufferB.String() != "foo" { 45 t.Errorf("Buffer contains %v", bufferB.String()) 46 } 47 48 // Test2: bufferA and bufferB should contain "foobar", 49 // while bufferC should only contain "bar" 50 bufferC := &dummyWriter{} 51 writer.Add(bufferC) 52 writer.Write([]byte("bar")) 53 54 if bufferA.String() != "foobar" { 55 t.Errorf("Buffer contains %v", bufferA.String()) 56 } 57 58 if bufferB.String() != "foobar" { 59 t.Errorf("Buffer contains %v", bufferB.String()) 60 } 61 62 if bufferC.String() != "bar" { 63 t.Errorf("Buffer contains %v", bufferC.String()) 64 } 65 66 // Test3: Test eviction on failure 67 bufferA.failOnWrite = true 68 writer.Write([]byte("fail")) 69 if bufferA.String() != "foobar" { 70 t.Errorf("Buffer contains %v", bufferA.String()) 71 } 72 if bufferC.String() != "barfail" { 73 t.Errorf("Buffer contains %v", bufferC.String()) 74 } 75 // Even though we reset the flag, no more writes should go in there 76 bufferA.failOnWrite = false 77 writer.Write([]byte("test")) 78 if bufferA.String() != "foobar" { 79 t.Errorf("Buffer contains %v", bufferA.String()) 80 } 81 if bufferC.String() != "barfailtest" { 82 t.Errorf("Buffer contains %v", bufferC.String()) 83 } 84 85 // Test4: Test eviction on multiple simultaneous failures 86 bufferB.failOnWrite = true 87 bufferC.failOnWrite = true 88 bufferD := &dummyWriter{} 89 writer.Add(bufferD) 90 writer.Write([]byte("yo")) 91 writer.Write([]byte("ink")) 92 if strings.Contains(bufferB.String(), "yoink") { 93 t.Errorf("bufferB received write. contents: %q", bufferB) 94 } 95 if strings.Contains(bufferC.String(), "yoink") { 96 t.Errorf("bufferC received write. contents: %q", bufferC) 97 } 98 if g, w := bufferD.String(), "yoink"; g != w { 99 t.Errorf("bufferD = %q, want %q", g, w) 100 } 101 102 writer.Clean() 103 } 104 105 type devNullCloser int 106 107 func (d devNullCloser) Close() error { 108 return nil 109 } 110 111 func (d devNullCloser) Write(buf []byte) (int, error) { 112 return len(buf), nil 113 } 114 115 // This test checks for races. It is only useful when run with the race detector. 116 func TestRaceUnbuffered(t *testing.T) { 117 writer := new(Unbuffered) 118 c := make(chan bool) 119 go func() { 120 writer.Add(devNullCloser(0)) 121 c <- true 122 }() 123 writer.Write([]byte("hello")) 124 <-c 125 } 126 127 func BenchmarkUnbuffered(b *testing.B) { 128 writer := new(Unbuffered) 129 setUpWriter := func() { 130 for i := 0; i < 100; i++ { 131 writer.Add(devNullCloser(0)) 132 writer.Add(devNullCloser(0)) 133 writer.Add(devNullCloser(0)) 134 } 135 } 136 testLine := "Line that thinks that it is log line from docker" 137 var buf bytes.Buffer 138 for i := 0; i < 100; i++ { 139 buf.Write([]byte(testLine + "\n")) 140 } 141 // line without eol 142 buf.Write([]byte(testLine)) 143 testText := buf.Bytes() 144 b.SetBytes(int64(5 * len(testText))) 145 b.ResetTimer() 146 for i := 0; i < b.N; i++ { 147 b.StopTimer() 148 setUpWriter() 149 b.StartTimer() 150 151 for j := 0; j < 5; j++ { 152 if _, err := writer.Write(testText); err != nil { 153 b.Fatal(err) 154 } 155 } 156 157 b.StopTimer() 158 writer.Clean() 159 b.StartTimer() 160 } 161 }