github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/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 should 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  }