tableflip/process_test.go

89 lines
1.6 KiB
Go

package tableflip
import (
"fmt"
"os"
"strings"
)
type testProcess struct {
fds []*os.File
env env
signals chan os.Signal
sigErr chan error
waitErr chan error
quit chan struct{}
}
func newTestProcess(fds []*os.File, envstr []string) (*testProcess, error) {
environ := make(map[string]string)
for _, entry := range envstr {
parts := strings.SplitN(entry, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid env entry: %s", entry)
}
environ[parts[0]] = parts[1]
}
return &testProcess{
fds,
env{
newFile: func(fd uintptr, name string) *os.File {
return fds[fd-3]
},
getenv: func(key string) string {
return environ[key]
},
closeOnExec: func(int) {},
},
make(chan os.Signal, 1),
make(chan error),
make(chan error),
make(chan struct{}),
}, nil
}
func (tp *testProcess) Signal(sig os.Signal) error {
select {
case tp.signals <- sig:
return <-tp.sigErr
case <-tp.quit:
return nil
}
}
func (tp *testProcess) Wait() error {
select {
case err := <-tp.waitErr:
return err
case <-tp.quit:
return nil
}
}
func (tp *testProcess) String() string {
return fmt.Sprintf("tp=%p", tp)
}
func (tp *testProcess) exit(err error) {
select {
case tp.waitErr <- err:
close(tp.quit)
case <-tp.quit:
}
}
func (tp *testProcess) recvSignal(err error) os.Signal {
sig := <-tp.signals
tp.sigErr <- err
return sig
}
func (tp *testProcess) notify() (map[fileName]*file, <-chan error, error) {
parent, files, err := newParent(&tp.env)
if err != nil {
return nil, nil, err
}
return files, parent.result, parent.sendReady()
}