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  }