// 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) } }