"strings"
"time"
+ "git.arvados.org/arvados.git/lib/diagnostics"
"git.arvados.org/arvados.git/sdk/go/arvados"
+ "git.arvados.org/arvados.git/sdk/go/arvadostest"
"golang.org/x/net/context"
. "gopkg.in/check.v1"
)
-func busyboxDockerImage(c *C) string {
- fnm := "busybox_uclibc.tar"
- cachedir := c.MkDir()
- cachefile := cachedir + "/" + fnm
- if _, err := os.Stat(cachefile); err == nil {
- return cachefile
- }
-
- f, err := ioutil.TempFile(cachedir, "")
- c.Assert(err, IsNil)
- defer f.Close()
- defer os.Remove(f.Name())
-
- resp, err := http.Get("https://cache.arvados.org/" + fnm)
- c.Assert(err, IsNil)
- defer resp.Body.Close()
- _, err = io.Copy(f, resp.Body)
- c.Assert(err, IsNil)
- err = f.Close()
- c.Assert(err, IsNil)
- err = os.Rename(f.Name(), cachefile)
- c.Assert(err, IsNil)
-
- return cachefile
-}
-
type nopWriteCloser struct{ io.Writer }
func (nopWriteCloser) Close() error { return nil }
Stdout: nopWriteCloser{&s.stdout},
Stderr: nopWriteCloser{&s.stderr},
}
- err := s.executor.LoadImage("", busyboxDockerImage(c), arvados.Container{}, "", nil)
+ err := s.executor.LoadImage("", arvadostest.BusyboxDockerImage(c), arvados.Container{}, "", nil)
c.Assert(err, IsNil)
}
}
func (s *executorSuite) TestExecTrivialContainer(c *C) {
+ c.Logf("Using container runtime: %s", s.executor.Runtime())
s.spec.Command = []string{"echo", "ok"}
s.checkRun(c, 0)
c.Check(s.stdout.String(), Equals, "ok\n")
c.Check(s.stderr.String(), Equals, "")
}
+func (s *executorSuite) TestDiagnosticsImage(c *C) {
+ s.newExecutor(c)
+ imagefile := c.MkDir() + "/hello-world.tar"
+ err := ioutil.WriteFile(imagefile, diagnostics.HelloWorldDockerImage, 0777)
+ c.Assert(err, IsNil)
+ err = s.executor.LoadImage("", imagefile, arvados.Container{}, "", nil)
+ c.Assert(err, IsNil)
+
+ c.Logf("Using container runtime: %s", s.executor.Runtime())
+ s.spec.Image = "hello-world"
+ s.spec.Command = []string{"/hello"}
+ s.checkRun(c, 0)
+ c.Check(s.stdout.String(), Matches, `(?ms)\nHello from Docker!\n.*`)
+}
+
func (s *executorSuite) TestExitStatus(c *C) {
s.spec.Command = []string{"false"}
s.checkRun(c, 1)
}
func (s *executorSuite) TestIPAddress(c *C) {
- s.spec.Command = []string{"nc", "-l", "-p", "1951", "-e", "printf", `HTTP/1.1 418 I'm a teapot\r\n\r\n`}
+ // Listen on an available port on the host.
+ ln, err := net.Listen("tcp", net.JoinHostPort("0.0.0.0", "0"))
+ c.Assert(err, IsNil)
+ defer ln.Close()
+ _, port, err := net.SplitHostPort(ln.Addr().String())
+ c.Assert(err, IsNil)
+
+ // Start a container that listens on the same port number that
+ // is already in use on the host.
+ s.spec.Command = []string{"nc", "-l", "-p", port, "-e", "printf", `HTTP/1.1 418 I'm a teapot\r\n\r\n`}
s.spec.EnableNetwork = true
c.Assert(s.executor.Create(s.spec), IsNil)
c.Assert(s.executor.Start(), IsNil)
starttime := time.Now()
- ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second))
+ ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
defer cancel()
for ctx.Err() == nil {
break
}
}
+ // When we connect to the port using s.executor.IPAddress(),
+ // we should reach the nc process running inside the
+ // container, not the net.Listen() running outside the
+ // container, even though both listen on the same port.
ip, err := s.executor.IPAddress()
if c.Check(err, IsNil) && c.Check(ip, Not(Equals), "") {
- req, err := http.NewRequest("BREW", "http://"+net.JoinHostPort(ip, "1951"), nil)
+ req, err := http.NewRequest("BREW", "http://"+net.JoinHostPort(ip, port), nil)
c.Assert(err, IsNil)
resp, err := http.DefaultClient.Do(req)
c.Assert(err, IsNil)
code, _ := s.executor.Wait(ctx)
c.Logf("container ran for %v", time.Now().Sub(starttime))
c.Check(code, Equals, -1)
+
+ c.Logf("stdout:\n%s\n\n", s.stdout.String())
+ c.Logf("stderr:\n%s\n\n", s.stderr.String())
}
func (s *executorSuite) TestInject(c *C) {