| // Copyright 2016 syzkaller project authors. All rights reserved. |
| // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| |
| package vmimpl |
| |
| import ( |
| "bytes" |
| "io" |
| "testing" |
| "time" |
| |
| "github.com/google/syzkaller/pkg/osutil" |
| ) |
| |
| func TestMerger(t *testing.T) { |
| tee := new(bytes.Buffer) |
| merger := NewOutputMerger(tee) |
| |
| rp1, wp1, err := osutil.LongPipe() |
| if err != nil { |
| t.Fatal(err) |
| } |
| defer wp1.Close() |
| merger.Add("pipe1", rp1) |
| |
| rp2, wp2, err := osutil.LongPipe() |
| if err != nil { |
| t.Fatal(err) |
| } |
| defer wp2.Close() |
| merger.Add("pipe2", rp2) |
| |
| wp1.Write([]byte("111")) |
| select { |
| case <-merger.Output: |
| t.Fatalf("merger produced incomplete line") |
| case <-time.After(10 * time.Millisecond): |
| } |
| |
| wp2.Write([]byte("222")) |
| select { |
| case <-merger.Output: |
| t.Fatalf("merger produced incomplete line") |
| case <-time.After(10 * time.Millisecond): |
| } |
| |
| wp1.Write([]byte("333\n444")) |
| got := string(<-merger.Output) |
| if want := "111333\n"; got != want { |
| t.Fatalf("bad line: '%s', want '%s'", got, want) |
| } |
| |
| wp2.Write([]byte("555\n666\n777")) |
| got = string(<-merger.Output) |
| if want := "222555\n666\n"; got != want { |
| t.Fatalf("bad line: '%s', want '%s'", got, want) |
| } |
| |
| wp1.Close() |
| got = string(<-merger.Output) |
| if want := "444\n"; got != want { |
| t.Fatalf("bad line: '%s', want '%s'", got, want) |
| } |
| |
| if err := <-merger.Err; err == nil { |
| t.Fatalf("merger did not produce an error on pipe close") |
| } else if merr := err.(MergerError); merr.Name != "pipe1" || merr.R != rp1 || merr.Err != io.EOF { |
| t.Fatalf("merger produced wrong error: %v", err) |
| } |
| |
| wp2.Close() |
| got = string(<-merger.Output) |
| if want := "777\n"; got != want { |
| t.Fatalf("bad line: '%s', want '%s'", got, want) |
| } |
| |
| merger.Wait() |
| want := "111333\n222555\n666\n444\n777\n" |
| if got := tee.String(); got != want { |
| t.Fatalf("bad tee: '%s', want '%s'", got, want) |
| } |
| } |