github.com/karrick/gorill@v1.10.3/multiWriteCloserFanOut_test.go (about) 1 package gorill 2 3 import ( 4 "bytes" 5 "io" 6 "testing" 7 "time" 8 ) 9 10 func TestMultiWriteCloserFanOutNoWriteClosers(t *testing.T) { 11 mw := NewMultiWriteCloserFanOut() 12 if want := 0; mw.Count() != want { 13 t.Errorf("Actual: %#v; Expected: %#v", mw.Count(), want) 14 } 15 n, err := mw.Write([]byte("blob")) 16 if want := 4; n != want { 17 t.Errorf("Actual: %#v; Expected: %#v", n, want) 18 } 19 if err != nil { 20 t.Errorf("Actual: %#v; Expected: %#v", err, nil) 21 } 22 mw.Close() 23 } 24 25 func TestMultiWriteCloserFanOutNewWriteCloser(t *testing.T) { 26 bb1 := NewNopCloseBuffer() 27 bb2 := NewNopCloseBuffer() 28 mw := NewMultiWriteCloserFanOut(bb1, bb2) 29 30 if want := 2; mw.Count() != want { 31 t.Errorf("Actual: %#v; Expected: %#v", mw.Count(), want) 32 } 33 n, err := mw.Write([]byte("blob")) 34 if want := 4; n != want { 35 t.Errorf("Actual: %#v; Expected: %#v", n, want) 36 } 37 if err != nil { 38 t.Errorf("Actual: %#v; Expected: %#v", err, nil) 39 } 40 if want := "blob"; bb1.String() != want { 41 t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want) 42 } 43 if want := "blob"; bb2.String() != want { 44 t.Errorf("Actual: %#v; Expected: %#v", bb2.String(), want) 45 } 46 mw.Close() 47 } 48 49 func TestMultiWriteCloserFanOutOneWriteCloser(t *testing.T) { 50 mw := NewMultiWriteCloserFanOut() 51 52 bb1 := NewNopCloseBuffer() 53 if actual, expected := mw.Add(bb1), 1; actual != expected { 54 t.Errorf("Actual: %#v; Expected: %#v", actual, expected) 55 } 56 if want := 1; mw.Count() != want { 57 t.Errorf("Actual: %#v; Expected: %#v", mw.Count(), want) 58 } 59 n, err := mw.Write([]byte("blob")) 60 if want := 4; n != want { 61 t.Errorf("Actual: %#v; Expected: %#v", n, want) 62 } 63 if err != nil { 64 t.Errorf("Actual: %#v; Expected: %#v", err, nil) 65 } 66 if want := "blob"; bb1.String() != want { 67 t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want) 68 } 69 mw.Close() 70 } 71 72 func TestMultiWriteCloserFanOutTwoWriteClosers(t *testing.T) { 73 mw := NewMultiWriteCloserFanOut() 74 75 bb1 := NewNopCloseBuffer() 76 mw.Add(bb1) 77 bb2 := NewNopCloseBuffer() 78 mw.Add(bb2) 79 if want := 2; mw.Count() != want { 80 t.Errorf("Actual: %#v; Expected: %#v", mw.Count(), want) 81 } 82 n, err := mw.Write([]byte("blob")) 83 if want := 4; n != want { 84 t.Errorf("Actual: %#v; Expected: %#v", n, want) 85 } 86 if err != nil { 87 t.Errorf("Actual: %#v; Expected: %#v", err, nil) 88 } 89 if want := "blob"; bb1.String() != want { 90 t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want) 91 } 92 if want := "blob"; bb2.String() != want { 93 t.Errorf("Actual: %#v; Expected: %#v", bb2.String(), want) 94 } 95 mw.Close() 96 } 97 98 func TestMultiWriteCloserFanOutRemoveWriteCloser(t *testing.T) { 99 mw := NewMultiWriteCloserFanOut() 100 101 bb1 := NewNopCloseBuffer() 102 mw.Add(bb1) 103 bb2 := NewNopCloseBuffer() 104 mw.Add(bb2) 105 if actual, expected := mw.Remove(bb1), 1; actual != expected { 106 t.Errorf("Actual: %#v; Expected: %#v", actual, expected) 107 } 108 n, err := mw.Write([]byte("blob")) 109 if want := 4; n != want { 110 t.Errorf("Actual: %#v; Expected: %#v", n, want) 111 } 112 if err != nil { 113 t.Errorf("Actual: %#v; Expected: %#v", err, nil) 114 } 115 if want := ""; bb1.String() != want { 116 t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want) 117 } 118 if want := "blob"; bb2.String() != want { 119 t.Errorf("Actual: %#v; Expected: %#v", bb2.String(), want) 120 } 121 // remove last one, should return true 122 if actual, expected := mw.Remove(bb2), 0; actual != expected { 123 t.Errorf("Actual: %#v; Expected: %#v", actual, expected) 124 } 125 mw.Close() 126 } 127 128 func TestMultiWriteCloserFanOutRemoveEveryWriteCloser(t *testing.T) { 129 mw := NewMultiWriteCloserFanOut() 130 131 bb1 := NewNopCloseBuffer() 132 mw.Add(bb1) 133 bb2 := NewNopCloseBuffer() 134 mw.Add(bb2) 135 mw.Remove(bb1) 136 mw.Remove(bb2) 137 if want := 0; mw.Count() != want { 138 t.Errorf("Actual: %#v; Expected: %#v", mw.Count(), want) 139 } 140 n, err := mw.Write([]byte("blob")) 141 if want := 4; n != want { 142 t.Errorf("Actual: %#v; Expected: %#v", n, want) 143 } 144 if err != nil { 145 t.Errorf("Actual: %#v; Expected: %#v", err, nil) 146 } 147 if want := ""; bb1.String() != want { 148 t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want) 149 } 150 if want := ""; bb2.String() != want { 151 t.Errorf("Actual: %#v; Expected: %#v", bb2.String(), want) 152 } 153 mw.Close() 154 } 155 156 type testWriteCloser struct { 157 closed bool 158 } 159 160 func (w *testWriteCloser) Write([]byte) (int, error) { 161 return 0, io.ErrShortWrite 162 } 163 164 func (w *testWriteCloser) Close() error { 165 w.closed = true 166 return nil 167 } 168 169 func (w *testWriteCloser) IsClosed() bool { 170 return w.closed 171 } 172 173 func TestMultiWriteCloserFanOutWriteErrorRemovesBadWriteCloser(t *testing.T) { 174 mw := NewMultiWriteCloserFanOut() 175 176 buf := NewNopCloseBuffer() 177 ew := &testWriteCloser{} 178 179 mw.Add(buf) 180 mw.Add(ew) 181 182 n, err := mw.Write([]byte(alphabet)) 183 if want := len(alphabet); n != want { 184 t.Errorf("Actual: %#v; Expected: %#v", n, want) 185 } 186 if err != nil { 187 t.Errorf("Actual: %#v; Expected: %#v", err, nil) 188 } 189 if want := alphabet; buf.String() != want { 190 t.Errorf("Actual: %#v; Expected: %#v", buf.String(), want) 191 } 192 193 mw.Remove(buf) 194 // NOTE: testWriteCloser should have been removed during error write 195 if want := true; ew.IsClosed() != want { 196 t.Errorf("Actual: %#v; Expected: %#v", ew.IsClosed(), want) 197 } 198 // NOTE: testWriteCloser should have been removed during error write 199 if want := 0; mw.Count() != want { 200 t.Errorf("Actual: %#v; Expected: %#v", mw.Count(), want) 201 } 202 mw.Close() 203 } 204 205 const writersCount = 1000 206 const data = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" 207 208 func BenchmarkWriterMultiWriteCloserFanOutWrite(b *testing.B) { 209 mw := NewMultiWriteCloserFanOut() 210 for i := 0; i < writersCount; i++ { 211 mw.Add(NewNopCloseBuffer()) 212 } 213 n, err := mw.Write([]byte(data)) 214 if n != len(data) { 215 b.Errorf("Actual: %#v; Expected: %#v", n, 4) 216 } 217 if err != nil { 218 b.Errorf("Actual: %#v; Expected: %#v", err, nil) 219 } 220 mw.Close() 221 } 222 223 func BenchmarkWriterMultiWriteCloserFanOutWriteSlow(b *testing.B) { 224 mw := NewMultiWriteCloserFanOut() 225 for i := 0; i < writersCount; i++ { 226 mw.Add(NopCloseWriter(SlowWriter(new(bytes.Buffer), 10*time.Millisecond))) 227 } 228 n, err := mw.Write([]byte(data)) 229 if n != len(data) { 230 b.Errorf("Actual: %#v; Expected: %#v", n, 4) 231 } 232 if err != nil { 233 b.Errorf("Actual: %#v; Expected: %#v", err, nil) 234 } 235 mw.Close() 236 }