Update test.
[arvados.git] / lib / crunchrun / singularity_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package crunchrun
6
7 import (
8         "os"
9         "os/exec"
10
11         . "gopkg.in/check.v1"
12 )
13
14 var _ = Suite(&singularitySuite{})
15
16 type singularitySuite struct {
17         executorSuite
18 }
19
20 func (s *singularitySuite) SetUpSuite(c *C) {
21         _, err := exec.LookPath("singularity")
22         if err != nil {
23                 c.Skip("looks like singularity is not installed")
24         }
25         s.newExecutor = func(c *C) {
26                 var err error
27                 s.executor, err = newSingularityExecutor(c.Logf)
28                 c.Assert(err, IsNil)
29         }
30 }
31
32 func (s *singularitySuite) TearDownSuite(c *C) {
33         if s.executor != nil {
34                 s.executor.Close()
35         }
36 }
37
38 func (s *singularitySuite) TestEnableNetwork_Listen(c *C) {
39         // With modern iptables, singularity (as of 4.2.1) cannot
40         // enable networking when invoked by a regular user. Under
41         // arvados-dispatch-cloud, crunch-run runs as root, so it's
42         // OK. For testing, assuming tests are not running as root, we
43         // use sudo -- but only if requested via environment variable.
44         if os.Getuid() == 0 {
45                 // already root
46         } else if os.Getenv("ARVADOS_TEST_PRIVESC") == "sudo" {
47                 c.Logf("ARVADOS_TEST_PRIVESC is 'sudo', invoking 'sudo singularity ...'")
48                 s.executor.(*singularityExecutor).sudo = true
49         } else {
50                 c.Skip("test case needs to run singularity as root -- set ARVADOS_TEST_PRIVESC=sudo to enable this test")
51         }
52         s.executorSuite.TestEnableNetwork_Listen(c)
53 }
54
55 func (s *singularitySuite) TestInject(c *C) {
56         path, err := exec.LookPath("nsenter")
57         if err != nil || path != "/var/lib/arvados/bin/nsenter" {
58                 c.Skip("looks like /var/lib/arvados/bin/nsenter is not installed -- re-run `arvados-server install`?")
59         }
60         s.executorSuite.TestInject(c)
61 }
62
63 var _ = Suite(&singularityStubSuite{})
64
65 // singularityStubSuite tests don't really invoke singularity, so we
66 // can run them even if singularity is not installed.
67 type singularityStubSuite struct{}
68
69 func (s *singularityStubSuite) TestSingularityExecArgs(c *C) {
70         e, err := newSingularityExecutor(c.Logf)
71         c.Assert(err, IsNil)
72         err = e.Create(containerSpec{
73                 WorkingDir:      "/WorkingDir",
74                 Env:             map[string]string{"FOO": "bar"},
75                 BindMounts:      map[string]bindmount{"/mnt": {HostPath: "/hostpath", ReadOnly: true}},
76                 EnableNetwork:   false,
77                 CUDADeviceCount: 3,
78                 VCPUs:           2,
79                 RAM:             12345678,
80         })
81         c.Check(err, IsNil)
82         e.imageFilename = "/fake/image.sif"
83         cmd := e.execCmd("./singularity")
84         expectArgs := []string{"./singularity", "exec", "--containall", "--cleanenv", "--pwd=/WorkingDir", "--net", "--network=none", "--nv"}
85         if cgroupSupport["cpu"] {
86                 expectArgs = append(expectArgs, "--cpus", "2")
87         }
88         if cgroupSupport["memory"] {
89                 expectArgs = append(expectArgs, "--memory", "12345678")
90         }
91         expectArgs = append(expectArgs, "--bind", "/hostpath:/mnt:ro", "/fake/image.sif")
92         c.Check(cmd.Args, DeepEquals, expectArgs)
93         c.Check(cmd.Env, DeepEquals, []string{
94                 "SINGULARITYENV_FOO=bar",
95                 "SINGULARITY_NO_EVAL=1",
96                 "XDG_RUNTIME_DIR=" + os.Getenv("XDG_RUNTIME_DIR"),
97                 "DBUS_SESSION_BUS_ADDRESS=" + os.Getenv("DBUS_SESSION_BUS_ADDRESS"),
98         })
99 }