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