github.com/eatbyte/docker@v1.6.0/engine/streams_test.go (about) 1 package engine 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "strings" 10 "testing" 11 ) 12 13 type sentinelWriteCloser struct { 14 calledWrite bool 15 calledClose bool 16 } 17 18 func (w *sentinelWriteCloser) Write(p []byte) (int, error) { 19 w.calledWrite = true 20 return len(p), nil 21 } 22 23 func (w *sentinelWriteCloser) Close() error { 24 w.calledClose = true 25 return nil 26 } 27 28 func TestOutputAddEnv(t *testing.T) { 29 input := "{\"foo\": \"bar\", \"answer_to_life_the_universe_and_everything\": 42}" 30 o := NewOutput() 31 result, err := o.AddEnv() 32 if err != nil { 33 t.Fatal(err) 34 } 35 o.Write([]byte(input)) 36 o.Close() 37 if v := result.Get("foo"); v != "bar" { 38 t.Errorf("Expected %v, got %v", "bar", v) 39 } 40 if v := result.GetInt("answer_to_life_the_universe_and_everything"); v != 42 { 41 t.Errorf("Expected %v, got %v", 42, v) 42 } 43 if v := result.Get("this-value-doesnt-exist"); v != "" { 44 t.Errorf("Expected %v, got %v", "", v) 45 } 46 } 47 48 func TestOutputAddClose(t *testing.T) { 49 o := NewOutput() 50 var s sentinelWriteCloser 51 o.Add(&s) 52 if err := o.Close(); err != nil { 53 t.Fatal(err) 54 } 55 // Write data after the output is closed. 56 // Write should succeed, but no destination should receive it. 57 if _, err := o.Write([]byte("foo bar")); err != nil { 58 t.Fatal(err) 59 } 60 if !s.calledClose { 61 t.Fatal("Output.Close() didn't close the destination") 62 } 63 } 64 65 func TestOutputAddPipe(t *testing.T) { 66 var testInputs = []string{ 67 "hello, world!", 68 "One\nTwo\nThree", 69 "", 70 "A line\nThen another nl-terminated line\n", 71 "A line followed by an empty line\n\n", 72 } 73 for _, input := range testInputs { 74 expectedOutput := input 75 o := NewOutput() 76 r, err := o.AddPipe() 77 if err != nil { 78 t.Fatal(err) 79 } 80 go func(o *Output) { 81 if n, err := o.Write([]byte(input)); err != nil { 82 t.Error(err) 83 } else if n != len(input) { 84 t.Errorf("Expected %d, got %d", len(input), n) 85 } 86 if err := o.Close(); err != nil { 87 t.Error(err) 88 } 89 }(o) 90 output, err := ioutil.ReadAll(r) 91 if err != nil { 92 t.Fatal(err) 93 } 94 if string(output) != expectedOutput { 95 t.Errorf("Last line is not stored as return string.\nExpected: '%s'\nGot: '%s'", expectedOutput, output) 96 } 97 } 98 } 99 100 func TestTail(t *testing.T) { 101 var tests = make(map[string][]string) 102 tests["hello, world!"] = []string{ 103 "", 104 "hello, world!", 105 "hello, world!", 106 "hello, world!", 107 } 108 tests["One\nTwo\nThree"] = []string{ 109 "", 110 "Three", 111 "Two\nThree", 112 "One\nTwo\nThree", 113 } 114 tests["One\nTwo\n\n\n"] = []string{ 115 "", 116 "Two", 117 "One\nTwo", 118 } 119 for input, outputs := range tests { 120 for n, expectedOutput := range outputs { 121 output := Tail(bytes.NewBufferString(input), n) 122 if output != expectedOutput { 123 t.Errorf("Tail n=%d returned wrong result.\nExpected: '%s'\nGot : '%s'", n, expectedOutput, output) 124 } 125 } 126 } 127 } 128 129 func lastLine(txt string) string { 130 scanner := bufio.NewScanner(strings.NewReader(txt)) 131 var lastLine string 132 for scanner.Scan() { 133 lastLine = scanner.Text() 134 } 135 return lastLine 136 } 137 138 func TestOutputAdd(t *testing.T) { 139 o := NewOutput() 140 b := &bytes.Buffer{} 141 o.Add(b) 142 input := "hello, world!" 143 if n, err := o.Write([]byte(input)); err != nil { 144 t.Fatal(err) 145 } else if n != len(input) { 146 t.Fatalf("Expected %d, got %d", len(input), n) 147 } 148 if output := b.String(); output != input { 149 t.Fatalf("Received wrong data from Add.\nExpected: '%s'\nGot: '%s'", input, output) 150 } 151 } 152 153 func TestOutputWriteError(t *testing.T) { 154 o := NewOutput() 155 buf := &bytes.Buffer{} 156 o.Add(buf) 157 r, w := io.Pipe() 158 input := "Hello there" 159 expectedErr := fmt.Errorf("This is an error") 160 r.CloseWithError(expectedErr) 161 o.Add(w) 162 n, err := o.Write([]byte(input)) 163 if err != expectedErr { 164 t.Fatalf("Output.Write() should return the first error encountered, if any") 165 } 166 if buf.String() != input { 167 t.Fatalf("Output.Write() should attempt write on all destinations, even after encountering an error") 168 } 169 if n != len(input) { 170 t.Fatalf("Output.Write() should return the size of the input if it successfully writes to at least one destination") 171 } 172 } 173 174 func TestInputAddEmpty(t *testing.T) { 175 i := NewInput() 176 var b bytes.Buffer 177 if err := i.Add(&b); err != nil { 178 t.Fatal(err) 179 } 180 data, err := ioutil.ReadAll(i) 181 if err != nil { 182 t.Fatal(err) 183 } 184 if len(data) > 0 { 185 t.Fatalf("Read from empty input shoul yield no data") 186 } 187 } 188 189 func TestInputAddTwo(t *testing.T) { 190 i := NewInput() 191 var b1 bytes.Buffer 192 // First add should succeed 193 if err := i.Add(&b1); err != nil { 194 t.Fatal(err) 195 } 196 var b2 bytes.Buffer 197 // Second add should fail 198 if err := i.Add(&b2); err == nil { 199 t.Fatalf("Adding a second source should return an error") 200 } 201 } 202 203 func TestInputAddNotEmpty(t *testing.T) { 204 i := NewInput() 205 b := bytes.NewBufferString("hello world\nabc") 206 expectedResult := b.String() 207 i.Add(b) 208 result, err := ioutil.ReadAll(i) 209 if err != nil { 210 t.Fatal(err) 211 } 212 if string(result) != expectedResult { 213 t.Fatalf("Expected: %v\nReceived: %v", expectedResult, result) 214 } 215 }