summaryrefslogtreecommitdiffhomepage
path: root/runsc/test/testutil/docker.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-10-17 12:27:58 -0700
committerShentubot <shentubot@google.com>2018-10-17 12:29:05 -0700
commit4e6f0892c96c374b1abcf5c39b75ba52d98c97f8 (patch)
treecb21538ad26a50ff61086d55c1bef36d5026e4c0 /runsc/test/testutil/docker.go
parent578fe5a50dcf8e104b6bce3802987b0f8c069ade (diff)
runsc: Support job control signals for the root container.
Now containers run with "docker run -it" support control characters like ^C and ^Z. This required refactoring our signal handling a bit. Signals delivered to the "runsc boot" process are turned into loader.Signal calls with the appropriate delivery mode. Previously they were always sent directly to PID 1. PiperOrigin-RevId: 217566770 Change-Id: I5b7220d9a0f2b591a56335479454a200c6de8732
Diffstat (limited to 'runsc/test/testutil/docker.go')
-rw-r--r--runsc/test/testutil/docker.go39
1 files changed, 39 insertions, 0 deletions
diff --git a/runsc/test/testutil/docker.go b/runsc/test/testutil/docker.go
index 8a51d3eed..4e48817cf 100644
--- a/runsc/test/testutil/docker.go
+++ b/runsc/test/testutil/docker.go
@@ -25,6 +25,7 @@ import (
"regexp"
"strconv"
"strings"
+ "syscall"
"time"
"github.com/kr/pty"
@@ -198,6 +199,13 @@ func (d *Docker) Run(args ...string) error {
return err
}
+// RunWithPty is like Run but with an attached pty.
+func (d *Docker) RunWithPty(args ...string) (*exec.Cmd, *os.File, error) {
+ a := []string{"run", "--runtime", d.Runtime, "--name", d.Name, "-it"}
+ a = append(a, args...)
+ return doWithPty(a...)
+}
+
// RunFg calls 'docker run' with the arguments provided in the foreground. It
// blocks until the container exits and returns the output.
func (d *Docker) RunFg(args ...string) (string, error) {
@@ -307,6 +315,37 @@ func (d *Docker) ID() (string, error) {
return strings.TrimSpace(string(out)), nil
}
+// Wait waits for container to exit, up to the given timeout. Returns error if
+// wait fails or timeout is hit. Returns the application return code otherwise.
+// Note that the application may have failed even if err == nil, always check
+// the exit code.
+func (d *Docker) Wait(timeout time.Duration) (syscall.WaitStatus, error) {
+ timeoutChan := time.After(timeout)
+ waitChan := make(chan (syscall.WaitStatus))
+ errChan := make(chan (error))
+
+ go func() {
+ out, err := do("wait", d.Name)
+ if err != nil {
+ errChan <- fmt.Errorf("error waiting for container %q: %v", d.Name, err)
+ }
+ exit, err := strconv.Atoi(strings.TrimSuffix(string(out), "\n"))
+ if err != nil {
+ errChan <- fmt.Errorf("error parsing exit code %q: %v", out, err)
+ }
+ waitChan <- syscall.WaitStatus(uint32(exit))
+ }()
+
+ select {
+ case ws := <-waitChan:
+ return ws, nil
+ case err := <-errChan:
+ return syscall.WaitStatus(1), err
+ case <-timeoutChan:
+ return syscall.WaitStatus(1), fmt.Errorf("timeout waiting for container %q", d.Name)
+ }
+}
+
// WaitForOutput calls 'docker logs' to retrieve containers output and searches
// for the given pattern.
func (d *Docker) WaitForOutput(pattern string, timeout time.Duration) (string, error) {