8311: Add git_tree mount type.
[arvados.git] / services / crunch-run / git_mount_test.go
diff --git a/services/crunch-run/git_mount_test.go b/services/crunch-run/git_mount_test.go
new file mode 100644 (file)
index 0000000..4c6ce7f
--- /dev/null
@@ -0,0 +1,164 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package main
+
+import (
+       "io/ioutil"
+       "os"
+       "path/filepath"
+
+       "git.curoverse.com/arvados.git/sdk/go/arvados"
+       "git.curoverse.com/arvados.git/sdk/go/arvadostest"
+       check "gopkg.in/check.v1"
+       git_client "gopkg.in/src-d/go-git.v4/plumbing/transport/client"
+       git_http "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
+)
+
+type GitMountSuite struct {
+       tmpdir string
+}
+
+var _ = check.Suite(&GitMountSuite{})
+
+func (s *GitMountSuite) SetUpSuite(c *check.C) {
+       git_client.InstallProtocol("https", git_http.NewClient(arvados.InsecureHTTPClient))
+}
+
+func (s *GitMountSuite) SetUpTest(c *check.C) {
+       port, err := ioutil.ReadFile("../../tmp/arv-git-httpd-ssl.port")
+       c.Assert(err, check.IsNil)
+       discoveryMap["gitUrl"] = "https://localhost:" + string(port)
+
+       s.tmpdir, err = ioutil.TempDir("", "")
+       c.Assert(err, check.IsNil)
+}
+
+func (s *GitMountSuite) TearDownTest(c *check.C) {
+       err := os.RemoveAll(s.tmpdir)
+       c.Check(err, check.IsNil)
+}
+
+// Commit fd3531f is crunch-run-tree-test
+func (s *GitMountSuite) TestextractTree(c *check.C) {
+       gm := gitMount{
+               Path:   "/",
+               UUID:   arvadostest.Repository2UUID,
+               Commit: "fd3531f42995344f36c30b79f55f27b502f3d344",
+       }
+       err := gm.extractTree(&ArvTestClient{}, s.tmpdir)
+       c.Check(err, check.IsNil)
+
+       fnm := filepath.Join(s.tmpdir, "dir1/dir2/file with mode 0644")
+       data, err := ioutil.ReadFile(fnm)
+       c.Check(err, check.IsNil)
+       c.Check(data, check.DeepEquals, []byte{0, 1, 2, 3})
+       fi, err := os.Stat(fnm)
+       c.Check(err, check.IsNil)
+       if err == nil {
+               c.Check(fi.Mode(), check.Equals, os.FileMode(0644))
+       }
+
+       fnm = filepath.Join(s.tmpdir, "dir1/dir2/file with mode 0755")
+       data, err = ioutil.ReadFile(fnm)
+       c.Check(err, check.IsNil)
+       c.Check(string(data), check.DeepEquals, "#!/bin/sh\nexec echo OK\n")
+       fi, err = os.Stat(fnm)
+       c.Check(err, check.IsNil)
+       if err == nil {
+               c.Check(fi.Mode(), check.Equals, os.FileMode(0755))
+       }
+
+       // Ensure there's no extra stuff like a ".git" dir
+       s.checkTmpdirContents(c, []string{"dir1"})
+}
+
+// Commit 5ebfab0 is not the tip of any branch or tag, but is
+// reachable in branch "crunch-run-non-tip-test".
+func (s *GitMountSuite) TestExtractNonTipCommit(c *check.C) {
+       gm := gitMount{
+               Path:   "/",
+               UUID:   arvadostest.Repository2UUID,
+               Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
+       }
+       err := gm.extractTree(&ArvTestClient{}, s.tmpdir)
+       c.Check(err, check.IsNil)
+
+       fnm := filepath.Join(s.tmpdir, "file only on testbranch")
+       data, err := ioutil.ReadFile(fnm)
+       c.Check(err, check.IsNil)
+       c.Check(string(data), check.DeepEquals, "testfile\n")
+}
+
+func (s *GitMountSuite) TestNonexistentRepository(c *check.C) {
+       gm := gitMount{
+               Path:   "/",
+               UUID:   "zzzzz-s0uqq-nonexistentrepo",
+               Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
+       }
+       err := gm.extractTree(&ArvTestClient{}, s.tmpdir)
+       c.Check(err, check.NotNil)
+       c.Check(err, check.ErrorMatches, ".*repository not found.*")
+
+       s.checkTmpdirContents(c, []string{})
+}
+
+func (s *GitMountSuite) TestNonexistentCommit(c *check.C) {
+       gm := gitMount{
+               Path:   "/",
+               UUID:   arvadostest.Repository2UUID,
+               Commit: "bb66b6bb6b6bbb6b6b6b66b6b6b6b6b6b6b6b66b",
+       }
+       err := gm.extractTree(&ArvTestClient{}, s.tmpdir)
+       c.Check(err, check.NotNil)
+       c.Check(err, check.ErrorMatches, ".*object not found.*")
+
+       s.checkTmpdirContents(c, []string{})
+}
+
+func (s *GitMountSuite) TestInvalid(c *check.C) {
+       for _, trial := range []struct {
+               gm      gitMount
+               matcher string
+       }{
+               {
+                       gm: gitMount{
+                               Path:   "/",
+                               UUID:   arvadostest.Repository2UUID,
+                               Commit: "abc123",
+                       },
+                       matcher: ".*sha1.*",
+               },
+               {
+                       gm: gitMount{
+                               Path:   "/dir1/",
+                               UUID:   arvadostest.Repository2UUID,
+                               Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
+                       },
+                       matcher: ".*path.*",
+               },
+               {
+                       gm: gitMount{
+                               Path:   "/",
+                               Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
+                       },
+                       matcher: ".*UUID.*",
+               },
+       } {
+               err := trial.gm.extractTree(&ArvTestClient{}, s.tmpdir)
+               c.Check(err, check.NotNil)
+               s.checkTmpdirContents(c, []string{})
+
+               err := trial.gm.validate()
+               c.Check(err, check.ErrorMatches, trial.matcher)
+       }
+}
+
+func (s *GitMountSuite) checkTmpdirContents(c *check.C, expect []string) {
+       f, err := os.Open(s.tmpdir)
+       c.Check(err, check.IsNil)
+       names, err := f.Readdirnames(-1)
+       c.Check(err, check.IsNil)
+       c.Check(names, check.DeepEquals, expect)
+}