Merge branch '17343-workbench1-optional'
[arvados.git] / lib / crunchrun / git_mount_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         "io/ioutil"
9         "net/url"
10         "os"
11         "path/filepath"
12
13         "git.arvados.org/arvados.git/lib/config"
14         "git.arvados.org/arvados.git/sdk/go/arvados"
15         "git.arvados.org/arvados.git/sdk/go/arvadostest"
16         "git.arvados.org/arvados.git/sdk/go/ctxlog"
17         check "gopkg.in/check.v1"
18         git_client "gopkg.in/src-d/go-git.v4/plumbing/transport/client"
19         git_http "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
20 )
21
22 type GitMountSuite struct {
23         tmpdir string
24 }
25
26 var _ = check.Suite(&GitMountSuite{})
27
28 func (s *GitMountSuite) SetUpTest(c *check.C) {
29         s.useTestGitServer(c)
30
31         var err error
32         s.tmpdir, err = ioutil.TempDir("", "")
33         c.Assert(err, check.IsNil)
34 }
35
36 func (s *GitMountSuite) TearDownTest(c *check.C) {
37         err := os.RemoveAll(s.tmpdir)
38         c.Check(err, check.IsNil)
39 }
40
41 // Commit fd3531f is crunch-run-tree-test
42 func (s *GitMountSuite) TestextractTree(c *check.C) {
43         gm := gitMount{
44                 Path:   "/",
45                 UUID:   arvadostest.Repository2UUID,
46                 Commit: "fd3531f42995344f36c30b79f55f27b502f3d344",
47         }
48         err := gm.extractTree(&ArvTestClient{}, s.tmpdir, arvadostest.ActiveToken)
49         c.Check(err, check.IsNil)
50
51         fnm := filepath.Join(s.tmpdir, "dir1/dir2/file with mode 0644")
52         data, err := ioutil.ReadFile(fnm)
53         c.Check(err, check.IsNil)
54         c.Check(data, check.DeepEquals, []byte{0, 1, 2, 3})
55         fi, err := os.Stat(fnm)
56         c.Check(err, check.IsNil)
57         if err == nil {
58                 c.Check(fi.Mode(), check.Equals, os.FileMode(0644))
59         }
60
61         fnm = filepath.Join(s.tmpdir, "dir1/dir2/file with mode 0755")
62         data, err = ioutil.ReadFile(fnm)
63         c.Check(err, check.IsNil)
64         c.Check(string(data), check.DeepEquals, "#!/bin/sh\nexec echo OK\n")
65         fi, err = os.Stat(fnm)
66         c.Check(err, check.IsNil)
67         if err == nil {
68                 c.Check(fi.Mode(), check.Equals, os.FileMode(0755))
69         }
70
71         // Ensure there's no extra stuff like a ".git" dir
72         s.checkTmpdirContents(c, []string{"dir1"})
73
74         // Ensure tmpdir is world-readable and world-executable so the
75         // UID inside the container can use it.
76         fi, err = os.Stat(s.tmpdir)
77         c.Check(err, check.IsNil)
78         c.Check(fi.Mode()&os.ModePerm, check.Equals, os.FileMode(0755))
79 }
80
81 // Commit 5ebfab0 is not the tip of any branch or tag, but is
82 // reachable in branch "crunch-run-non-tip-test".
83 func (s *GitMountSuite) TestExtractNonTipCommit(c *check.C) {
84         gm := gitMount{
85                 UUID:   arvadostest.Repository2UUID,
86                 Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
87         }
88         err := gm.extractTree(&ArvTestClient{}, s.tmpdir, arvadostest.ActiveToken)
89         c.Check(err, check.IsNil)
90
91         fnm := filepath.Join(s.tmpdir, "file only on testbranch")
92         data, err := ioutil.ReadFile(fnm)
93         c.Check(err, check.IsNil)
94         c.Check(string(data), check.DeepEquals, "testfile\n")
95 }
96
97 func (s *GitMountSuite) TestNonexistentRepository(c *check.C) {
98         gm := gitMount{
99                 Path:   "/",
100                 UUID:   "zzzzz-s0uqq-nonexistentrepo",
101                 Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
102         }
103         err := gm.extractTree(&ArvTestClient{}, s.tmpdir, arvadostest.ActiveToken)
104         c.Check(err, check.NotNil)
105         c.Check(err, check.ErrorMatches, ".*repository not found.*")
106
107         s.checkTmpdirContents(c, []string{})
108 }
109
110 func (s *GitMountSuite) TestNonexistentCommit(c *check.C) {
111         gm := gitMount{
112                 Path:   "/",
113                 UUID:   arvadostest.Repository2UUID,
114                 Commit: "bb66b6bb6b6bbb6b6b6b66b6b6b6b6b6b6b6b66b",
115         }
116         err := gm.extractTree(&ArvTestClient{}, s.tmpdir, arvadostest.ActiveToken)
117         c.Check(err, check.NotNil)
118         c.Check(err, check.ErrorMatches, ".*object not found.*")
119
120         s.checkTmpdirContents(c, []string{})
121 }
122
123 func (s *GitMountSuite) TestGitUrlDiscoveryFails(c *check.C) {
124         delete(discoveryMap, "gitUrl")
125         gm := gitMount{
126                 Path:   "/",
127                 UUID:   arvadostest.Repository2UUID,
128                 Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
129         }
130         err := gm.extractTree(&ArvTestClient{}, s.tmpdir, arvadostest.ActiveToken)
131         c.Check(err, check.ErrorMatches, ".*gitUrl.*")
132 }
133
134 func (s *GitMountSuite) TestInvalid(c *check.C) {
135         for _, trial := range []struct {
136                 gm      gitMount
137                 matcher string
138         }{
139                 {
140                         gm: gitMount{
141                                 Path:   "/",
142                                 UUID:   arvadostest.Repository2UUID,
143                                 Commit: "abc123",
144                         },
145                         matcher: ".*SHA1.*",
146                 },
147                 {
148                         gm: gitMount{
149                                 Path:           "/",
150                                 UUID:           arvadostest.Repository2UUID,
151                                 RepositoryName: arvadostest.Repository2Name,
152                                 Commit:         "5ebfab0522851df01fec11ec55a6d0f4877b542e",
153                         },
154                         matcher: ".*repository_name.*",
155                 },
156                 {
157                         gm: gitMount{
158                                 Path:   "/",
159                                 GitURL: "https://localhost:0/" + arvadostest.Repository2Name + ".git",
160                                 Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
161                         },
162                         matcher: ".*git_url.*",
163                 },
164                 {
165                         gm: gitMount{
166                                 Path:   "/dir1/",
167                                 UUID:   arvadostest.Repository2UUID,
168                                 Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
169                         },
170                         matcher: ".*path.*",
171                 },
172                 {
173                         gm: gitMount{
174                                 Path:   "/",
175                                 Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e",
176                         },
177                         matcher: ".*UUID.*",
178                 },
179                 {
180                         gm: gitMount{
181                                 Path:     "/",
182                                 UUID:     arvadostest.Repository2UUID,
183                                 Commit:   "5ebfab0522851df01fec11ec55a6d0f4877b542e",
184                                 Writable: true,
185                         },
186                         matcher: ".*writable.*",
187                 },
188         } {
189                 err := trial.gm.extractTree(&ArvTestClient{}, s.tmpdir, arvadostest.ActiveToken)
190                 c.Check(err, check.NotNil)
191                 s.checkTmpdirContents(c, []string{})
192
193                 err = trial.gm.validate()
194                 c.Check(err, check.ErrorMatches, trial.matcher)
195         }
196 }
197
198 func (s *GitMountSuite) checkTmpdirContents(c *check.C, expect []string) {
199         f, err := os.Open(s.tmpdir)
200         c.Check(err, check.IsNil)
201         names, err := f.Readdirnames(-1)
202         c.Check(err, check.IsNil)
203         c.Check(names, check.DeepEquals, expect)
204 }
205
206 func (*GitMountSuite) useTestGitServer(c *check.C) {
207         git_client.InstallProtocol("https", git_http.NewClient(arvados.InsecureHTTPClient))
208
209         loader := config.NewLoader(nil, ctxlog.TestLogger(c))
210         cfg, err := loader.Load()
211         c.Assert(err, check.IsNil)
212         cluster, err := cfg.GetCluster("")
213         c.Assert(err, check.IsNil)
214
215         discoveryMap["gitUrl"] = (*url.URL)(&cluster.Services.GitHTTP.ExternalURL).String()
216 }