Tweak arvbox build order, API server depends on arvados-server
[arvados.git] / sdk / go / arvados / fs_project_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package arvados
6
7 import (
8         "bytes"
9         "encoding/json"
10         "io"
11         "os"
12         "path/filepath"
13         "strings"
14
15         check "gopkg.in/check.v1"
16 )
17
18 type spiedRequest struct {
19         method string
20         path   string
21         params map[string]interface{}
22 }
23
24 type spyingClient struct {
25         *Client
26         calls []spiedRequest
27 }
28
29 func (sc *spyingClient) RequestAndDecode(dst interface{}, method, path string, body io.Reader, params interface{}) error {
30         var paramsCopy map[string]interface{}
31         var buf bytes.Buffer
32         json.NewEncoder(&buf).Encode(params)
33         json.NewDecoder(&buf).Decode(&paramsCopy)
34         sc.calls = append(sc.calls, spiedRequest{
35                 method: method,
36                 path:   path,
37                 params: paramsCopy,
38         })
39         return sc.Client.RequestAndDecode(dst, method, path, body, params)
40 }
41
42 func (s *SiteFSSuite) TestCurrentUserHome(c *check.C) {
43         s.fs.MountProject("home", "")
44         s.testHomeProject(c, "/home")
45 }
46
47 func (s *SiteFSSuite) TestUsersDir(c *check.C) {
48         s.testHomeProject(c, "/users/active")
49 }
50
51 func (s *SiteFSSuite) testHomeProject(c *check.C, path string) {
52         f, err := s.fs.Open(path)
53         c.Assert(err, check.IsNil)
54         fis, err := f.Readdir(-1)
55         c.Check(len(fis), check.Not(check.Equals), 0)
56
57         ok := false
58         for _, fi := range fis {
59                 c.Check(fi.Name(), check.Not(check.Equals), "")
60                 if fi.Name() == "A Project" {
61                         ok = true
62                 }
63         }
64         c.Check(ok, check.Equals, true)
65
66         f, err = s.fs.Open(path + "/A Project/..")
67         c.Assert(err, check.IsNil)
68         fi, err := f.Stat()
69         c.Assert(err, check.IsNil)
70         c.Check(fi.IsDir(), check.Equals, true)
71         _, basename := filepath.Split(path)
72         c.Check(fi.Name(), check.Equals, basename)
73
74         f, err = s.fs.Open(path + "/A Project/A Subproject")
75         c.Assert(err, check.IsNil)
76         fi, err = f.Stat()
77         c.Assert(err, check.IsNil)
78         c.Check(fi.IsDir(), check.Equals, true)
79
80         for _, nx := range []string{
81                 path + "/Unrestricted public data",
82                 path + "/Unrestricted public data/does not exist",
83                 path + "/A Project/does not exist",
84         } {
85                 c.Log(nx)
86                 f, err = s.fs.Open(nx)
87                 c.Check(err, check.NotNil)
88                 c.Check(os.IsNotExist(err), check.Equals, true)
89         }
90 }
91
92 func (s *SiteFSSuite) TestProjectReaddirAfterLoadOne(c *check.C) {
93         f, err := s.fs.Open("/users/active/A Project/A Subproject")
94         c.Assert(err, check.IsNil)
95         defer f.Close()
96         f, err = s.fs.Open("/users/active/A Project/Project does not exist")
97         c.Assert(err, check.NotNil)
98         f, err = s.fs.Open("/users/active/A Project/A Subproject")
99         c.Assert(err, check.IsNil)
100         defer f.Close()
101         f, err = s.fs.Open("/users/active/A Project")
102         c.Assert(err, check.IsNil)
103         defer f.Close()
104         fis, err := f.Readdir(-1)
105         c.Assert(err, check.IsNil)
106         c.Logf("%#v", fis)
107         var foundSubproject, foundCollection bool
108         for _, fi := range fis {
109                 switch fi.Name() {
110                 case "A Subproject":
111                         foundSubproject = true
112                 case "collection_to_move_around":
113                         foundCollection = true
114                 }
115         }
116         c.Check(foundSubproject, check.Equals, true)
117         c.Check(foundCollection, check.Equals, true)
118 }
119
120 func (s *SiteFSSuite) TestSlashInName(c *check.C) {
121         var badCollection Collection
122         err := s.client.RequestAndDecode(&badCollection, "POST", "arvados/v1/collections", nil, map[string]interface{}{
123                 "collection": map[string]string{
124                         "name":       "bad/collection",
125                         "owner_uuid": fixtureAProjectUUID,
126                 },
127         })
128         c.Assert(err, check.IsNil)
129         defer s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+badCollection.UUID, nil, nil)
130
131         var badProject Group
132         err = s.client.RequestAndDecode(&badProject, "POST", "arvados/v1/groups", nil, map[string]interface{}{
133                 "group": map[string]string{
134                         "name":        "bad/project",
135                         "group_class": "project",
136                         "owner_uuid":  fixtureAProjectUUID,
137                 },
138         })
139         c.Assert(err, check.IsNil)
140         defer s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/groups/"+badProject.UUID, nil, nil)
141
142         dir, err := s.fs.Open("/users/active/A Project")
143         c.Assert(err, check.IsNil)
144         fis, err := dir.Readdir(-1)
145         c.Check(err, check.IsNil)
146         for _, fi := range fis {
147                 c.Logf("fi.Name() == %q", fi.Name())
148                 c.Check(strings.Contains(fi.Name(), "/"), check.Equals, false)
149         }
150 }
151
152 func (s *SiteFSSuite) TestProjectUpdatedByOther(c *check.C) {
153         s.fs.MountProject("home", "")
154
155         project, err := s.fs.OpenFile("/home/A Project", 0, 0)
156         c.Assert(err, check.IsNil)
157
158         _, err = s.fs.Open("/home/A Project/oob")
159         c.Check(err, check.NotNil)
160
161         var oob Collection
162         err = s.client.RequestAndDecode(&oob, "POST", "arvados/v1/collections", nil, map[string]interface{}{
163                 "collection": map[string]string{
164                         "name":       "oob",
165                         "owner_uuid": fixtureAProjectUUID,
166                 },
167         })
168         c.Assert(err, check.IsNil)
169         defer s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+oob.UUID, nil, nil)
170
171         err = project.Sync()
172         c.Check(err, check.IsNil)
173         f, err := s.fs.Open("/home/A Project/oob")
174         c.Assert(err, check.IsNil)
175         fi, err := f.Stat()
176         c.Assert(err, check.IsNil)
177         c.Check(fi.IsDir(), check.Equals, true)
178         f.Close()
179
180         wf, err := s.fs.OpenFile("/home/A Project/oob/test.txt", os.O_CREATE|os.O_RDWR, 0700)
181         c.Assert(err, check.IsNil)
182         _, err = wf.Write([]byte("hello oob\n"))
183         c.Check(err, check.IsNil)
184         err = wf.Close()
185         c.Check(err, check.IsNil)
186
187         // Delete test.txt behind s.fs's back by updating the
188         // collection record with an empty ManifestText.
189         err = s.client.RequestAndDecode(nil, "PATCH", "arvados/v1/collections/"+oob.UUID, nil, map[string]interface{}{
190                 "collection": map[string]string{
191                         "manifest_text":      "",
192                         "portable_data_hash": "d41d8cd98f00b204e9800998ecf8427e+0",
193                 },
194         })
195         c.Assert(err, check.IsNil)
196
197         err = project.Sync()
198         c.Check(err, check.IsNil)
199         _, err = s.fs.Open("/home/A Project/oob/test.txt")
200         c.Check(err, check.NotNil)
201         _, err = s.fs.Open("/home/A Project/oob")
202         c.Check(err, check.IsNil)
203
204         err = s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+oob.UUID, nil, nil)
205         c.Assert(err, check.IsNil)
206
207         err = project.Sync()
208         c.Check(err, check.IsNil)
209         _, err = s.fs.Open("/home/A Project/oob")
210         c.Check(err, check.NotNil)
211 }