12630: Test containerSpec setup and singularity exec args.
authorTom Clegg <tom@curii.com>
Mon, 13 Dec 2021 18:58:13 +0000 (13:58 -0500)
committerTom Clegg <tom@curii.com>
Mon, 13 Dec 2021 18:58:13 +0000 (13:58 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

lib/crunchrun/crunchrun_test.go
lib/crunchrun/singularity.go
lib/crunchrun/singularity_test.go

index c28cf73cbe0cfc694f81464eae65350c703238f8..67b18857b0ea3cf5321e529a8984ed5e89017628 100644 (file)
@@ -715,6 +715,7 @@ func (s *TestSuite) TestFullRunHello(c *C) {
                c.Check(s.executor.created.RAM, Equals, int64(1000000))
                c.Check(s.executor.created.NetworkMode, Equals, "default")
                c.Check(s.executor.created.EnableNetwork, Equals, false)
+               c.Check(s.executor.created.CUDADeviceCount, Equals, 0)
                fmt.Fprintln(s.executor.created.Stdout, "hello world")
        })
 
@@ -982,6 +983,42 @@ func (s *TestSuite) TestFullRunSetOutputStorageClasses(c *C) {
        c.Check(s.testContainerKeepClient.StorageClasses, DeepEquals, []string{"foo", "bar"})
 }
 
+func (s *TestSuite) TestEnableCUDADeviceCount(c *C) {
+       s.fullRunHelper(c, `{
+    "command": ["pwd"],
+    "container_image": "`+arvadostest.DockerImage112PDH+`",
+    "cwd": "/bin",
+    "environment": {},
+    "mounts": {"/tmp": {"kind": "tmp"} },
+    "output_path": "/tmp",
+    "priority": 1,
+    "runtime_constraints": {"cuda_device_count": 2},
+    "state": "Locked",
+    "output_storage_classes": ["foo", "bar"]
+}`, nil, 0, func() {
+               fmt.Fprintln(s.executor.created.Stdout, "ok")
+       })
+       c.Check(s.executor.created.CUDADeviceCount, Equals, 2)
+}
+
+func (s *TestSuite) TestEnableCUDAHardwareCapability(c *C) {
+       s.fullRunHelper(c, `{
+    "command": ["pwd"],
+    "container_image": "`+arvadostest.DockerImage112PDH+`",
+    "cwd": "/bin",
+    "environment": {},
+    "mounts": {"/tmp": {"kind": "tmp"} },
+    "output_path": "/tmp",
+    "priority": 1,
+    "runtime_constraints": {"cuda_hardware_capability": "foo"},
+    "state": "Locked",
+    "output_storage_classes": ["foo", "bar"]
+}`, nil, 0, func() {
+               fmt.Fprintln(s.executor.created.Stdout, "ok")
+       })
+       c.Check(s.executor.created.CUDADeviceCount, Equals, 1)
+}
+
 func (s *TestSuite) TestStopOnSignal(c *C) {
        s.executor.runFunc = func() {
                s.executor.created.Stdout.Write([]byte("foo\n"))
index 2128aeb2271f8d57da1fe5630d7bd7b7b105e1c6..cda10aa611b7cf8d3d1d03822495f91a9ee0f8d6 100644 (file)
@@ -241,8 +241,8 @@ func (e *singularityExecutor) Create(spec containerSpec) error {
        return nil
 }
 
-func (e *singularityExecutor) Start() error {
-       args := []string{"singularity", "exec", "--containall", "--cleanenv", "--pwd", e.spec.WorkingDir}
+func (e *singularityExecutor) execCmd(path string) *exec.Cmd {
+       args := []string{path, "exec", "--containall", "--cleanenv", "--pwd", e.spec.WorkingDir}
        if !e.spec.EnableNetwork {
                args = append(args, "--net", "--network=none")
        }
@@ -287,11 +287,7 @@ func (e *singularityExecutor) Start() error {
        args = append(args, e.imageFilename)
        args = append(args, e.spec.Command...)
 
-       path, err := exec.LookPath(args[0])
-       if err != nil {
-               return err
-       }
-       child := &exec.Cmd{
+       return &exec.Cmd{
                Path:   path,
                Args:   args,
                Env:    env,
@@ -299,6 +295,14 @@ func (e *singularityExecutor) Start() error {
                Stdout: e.spec.Stdout,
                Stderr: e.spec.Stderr,
        }
+}
+
+func (e *singularityExecutor) Start() error {
+       path, err := exec.LookPath("singularity")
+       if err != nil {
+               return err
+       }
+       child := e.execCmd(path)
        err = child.Start()
        if err != nil {
                return err
index a1263da3215ad6d07d7fcf2db444c06528d7dd72..cdeafee88242b3330adcf2c5ae7550fdcb104f46 100644 (file)
@@ -27,3 +27,26 @@ func (s *singularitySuite) SetUpSuite(c *C) {
                c.Assert(err, IsNil)
        }
 }
+
+var _ = Suite(&singularityStubSuite{})
+
+// singularityStubSuite tests don't really invoke singularity, so we
+// can run them even if singularity is not installed.
+type singularityStubSuite struct{}
+
+func (s *singularityStubSuite) TestSingularityExecArgs(c *C) {
+       e, err := newSingularityExecutor(c.Logf)
+       c.Assert(err, IsNil)
+       err = e.Create(containerSpec{
+               WorkingDir:      "/WorkingDir",
+               Env:             map[string]string{"FOO": "bar"},
+               BindMounts:      map[string]bindmount{"/mnt": {HostPath: "/hostpath", ReadOnly: true}},
+               EnableNetwork:   false,
+               CUDADeviceCount: 3,
+       })
+       c.Check(err, IsNil)
+       e.imageFilename = "/fake/image.sif"
+       cmd := e.execCmd("./singularity")
+       c.Check(cmd.Args, DeepEquals, []string{"./singularity", "exec", "--containall", "--cleanenv", "--pwd", "/WorkingDir", "--net", "--network=none", "--nv", "--bind", "/hostpath:/mnt:ro", "/fake/image.sif"})
+       c.Check(cmd.Env, DeepEquals, []string{"SINGULARITYENV_FOO=bar"})
+}