mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-23 19:39:40 +00:00
af643baa32
VM infrastructure currently has several problems: - Config struct is complete mess with a superset of params for all VM types - verification of Config is mess spread across several places - there is no place where VM code could do global initialization like creating GCE connection, uploading GCE image to GCS, matching adb devices with consoles, etc - it hard to add private VM implementations such impl would need to add code to config package which would lead to constant merge conflicts - interface for VM implementation is mixed with interface for VM users this does not allow to provide best interface for both of them - there is no way to add common code for all VM implementations This change solves these problems by: - splitting VM interface for users (vm package) and VM interface for VM implementations (vmimpl pacakge), this in turn allows to add common code - adding Pool concept that allows to do global initialization and config checking at the right time - decoupling manager config from VM-specific config each VM type now defines own config Note: manager configs need to be changed after this change: VM-specific parts are moved to own "vm" subobject. Note: this change also drops "local" VM type. Its story was long unclear and there is now syz-stress which solves the same problem.
80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
// 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"
|
|
"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 || err.Error() != "failed to read from pipe1: EOF" {
|
|
t.Fatalf("merger did not produce io.EOF: %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 := string(tee.Bytes()); got != want {
|
|
t.Fatalf("bad tee: '%s', want '%s'", got, want)
|
|
}
|
|
}
|