]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/test/test_cli_mv.py
Avoid spurious SUCCESS!?? for test_format_time_y2038.
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / test / test_cli_mv.py
1 import os.path
2 from twisted.trial import unittest
3 from allmydata.util import fileutil
4 from allmydata.test.no_network import GridTestMixin
5 from allmydata.scripts import tahoe_mv
6 from .test_cli import CLITestMixin
7
8 timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
9
10 class Mv(GridTestMixin, CLITestMixin, unittest.TestCase):
11     def test_mv_behavior(self):
12         self.basedir = "cli/Mv/mv_behavior"
13         self.set_up_grid()
14         fn1 = os.path.join(self.basedir, "file1")
15         DATA1 = "Nuclear launch codes"
16         fileutil.write(fn1, DATA1)
17         fn2 = os.path.join(self.basedir, "file2")
18         DATA2 = "UML diagrams"
19         fileutil.write(fn2, DATA2)
20         # copy both files to the grid
21         d = self.do_cli("create-alias", "tahoe")
22         d.addCallback(lambda res:
23             self.do_cli("cp", fn1, "tahoe:"))
24         d.addCallback(lambda res:
25             self.do_cli("cp", fn2, "tahoe:"))
26
27         # do mv file1 file3
28         # (we should be able to rename files)
29         d.addCallback(lambda res:
30             self.do_cli("mv", "tahoe:file1", "tahoe:file3"))
31         d.addCallback(lambda (rc, out, err):
32             self.failUnlessIn("OK", out, "mv didn't rename a file"))
33
34         # do mv file3 file2
35         # (This should succeed without issue)
36         d.addCallback(lambda res:
37             self.do_cli("mv", "tahoe:file3", "tahoe:file2"))
38         # Out should contain "OK" to show that the transfer worked.
39         d.addCallback(lambda (rc,out,err):
40             self.failUnlessIn("OK", out, "mv didn't output OK after mving"))
41
42         # Next, make a remote directory.
43         d.addCallback(lambda res:
44             self.do_cli("mkdir", "tahoe:directory"))
45
46         # mv file2 directory
47         # (should fail with a descriptive error message; the CLI mv
48         #  client should support this)
49         d.addCallback(lambda res:
50             self.do_cli("mv", "tahoe:file2", "tahoe:directory"))
51         d.addCallback(lambda (rc, out, err):
52             self.failUnlessIn(
53                 "Error: You can't overwrite a directory with a file", err,
54                 "mv shouldn't overwrite directories" ))
55
56         # mv file2 directory/
57         # (should succeed by making file2 a child node of directory)
58         d.addCallback(lambda res:
59             self.do_cli("mv", "tahoe:file2", "tahoe:directory/"))
60         # We should see an "OK"...
61         d.addCallback(lambda (rc, out, err):
62             self.failUnlessIn("OK", out,
63                             "mv didn't mv a file into a directory"))
64         # ... and be able to GET the file
65         d.addCallback(lambda res:
66             self.do_cli("get", "tahoe:directory/file2", self.basedir + "new"))
67         d.addCallback(lambda (rc, out, err):
68             self.failUnless(os.path.exists(self.basedir + "new"),
69                             "mv didn't write the destination file"))
70         # ... and not find the file where it was before.
71         d.addCallback(lambda res:
72             self.do_cli("get", "tahoe:file2", "file2"))
73         d.addCallback(lambda (rc, out, err):
74             self.failUnlessIn("404", err,
75                             "mv left the source file intact"))
76
77         # Let's build:
78         # directory/directory2/some_file
79         # directory3
80         d.addCallback(lambda res:
81             self.do_cli("mkdir", "tahoe:directory/directory2"))
82         d.addCallback(lambda res:
83             self.do_cli("cp", fn2, "tahoe:directory/directory2/some_file"))
84         d.addCallback(lambda res:
85             self.do_cli("mkdir", "tahoe:directory3"))
86
87         # Let's now try to mv directory/directory2/some_file to
88         # directory3/some_file
89         d.addCallback(lambda res:
90             self.do_cli("mv", "tahoe:directory/directory2/some_file",
91                         "tahoe:directory3/"))
92         # We should have just some_file in tahoe:directory3
93         d.addCallback(lambda res:
94             self.do_cli("get", "tahoe:directory3/some_file", "some_file"))
95         d.addCallback(lambda (rc, out, err):
96             self.failUnless("404" not in err,
97                               "mv didn't handle nested directories correctly"))
98         d.addCallback(lambda res:
99             self.do_cli("get", "tahoe:directory3/directory", "directory"))
100         d.addCallback(lambda (rc, out, err):
101             self.failUnlessIn("404", err,
102                               "mv moved the wrong thing"))
103         return d
104
105     def test_mv_error_if_DELETE_fails(self):
106         self.basedir = "cli/Mv/mv_error_if_DELETE_fails"
107         self.set_up_grid()
108         fn1 = os.path.join(self.basedir, "file1")
109         DATA1 = "Nuclear launch codes"
110         fileutil.write(fn1, DATA1)
111
112         original_do_http = tahoe_mv.do_http
113         def mock_do_http(method, url, body=""):
114             if method == "DELETE":
115                 class FakeResponse:
116                     def read(self):
117                         return "response"
118                 resp = FakeResponse()
119                 resp.status = '500 Something Went Wrong'
120                 resp.reason = '*shrug*'
121                 return resp
122             else:
123                 return original_do_http(method, url, body=body)
124         tahoe_mv.do_http = mock_do_http
125
126         # copy file to the grid
127         d = self.do_cli("create-alias", "tahoe")
128         d.addCallback(lambda res:
129             self.do_cli("cp", fn1, "tahoe:"))
130
131         # do mv file1 file2
132         d.addCallback(lambda res:
133             self.do_cli("mv", "tahoe:file1", "tahoe:file2"))
134         def _check( (rc, out, err) ):
135             self.failIfIn("OK", out, "mv printed 'OK' even though the DELETE failed")
136             self.failUnlessEqual(rc, 2)
137         d.addCallback(_check)
138
139         def _restore_do_http(res):
140             tahoe_mv.do_http = original_do_http
141             return res
142         d.addBoth(_restore_do_http)
143         return d
144
145     def test_mv_without_alias(self):
146         # doing 'tahoe mv' without explicitly specifying an alias or
147         # creating the default 'tahoe' alias should fail with a useful
148         # error message.
149         self.basedir = "cli/Mv/mv_without_alias"
150         self.set_up_grid()
151         d = self.do_cli("mv", "afile", "anotherfile")
152         def _check((rc, out, err)):
153             self.failUnlessReallyEqual(rc, 1)
154             self.failUnlessIn("error:", err)
155             self.failUnlessReallyEqual(out, "")
156         d.addCallback(_check)
157         # check to see that the validation extends to the
158         # target argument by making an alias that will work with the first
159         # one.
160         d.addCallback(lambda ign: self.do_cli("create-alias", "havasu"))
161         def _create_a_test_file(ign):
162             self.test_file_path = os.path.join(self.basedir, "afile")
163             fileutil.write(self.test_file_path, "puppies" * 100)
164         d.addCallback(_create_a_test_file)
165         d.addCallback(lambda ign: self.do_cli("put", self.test_file_path,
166                                               "havasu:afile"))
167         d.addCallback(lambda ign: self.do_cli("mv", "havasu:afile",
168                                               "anotherfile"))
169         d.addCallback(_check)
170         return d
171
172     def test_mv_with_nonexistent_alias(self):
173         # doing 'tahoe mv' with an alias that doesn't exist should fail
174         # with an informative error message.
175         self.basedir = "cli/Mv/mv_with_nonexistent_alias"
176         self.set_up_grid()
177         d = self.do_cli("mv", "fake:afile", "fake:anotherfile")
178         def _check((rc, out, err)):
179             self.failUnlessReallyEqual(rc, 1)
180             self.failUnlessIn("error:", err)
181             self.failUnlessIn("fake", err)
182             self.failUnlessReallyEqual(out, "")
183         d.addCallback(_check)
184         # check to see that the validation extends to the
185         # target argument by making an alias that will work with the first
186         # one.
187         d.addCallback(lambda ign: self.do_cli("create-alias", "havasu"))
188         def _create_a_test_file(ign):
189             self.test_file_path = os.path.join(self.basedir, "afile")
190             fileutil.write(self.test_file_path, "puppies" * 100)
191         d.addCallback(_create_a_test_file)
192         d.addCallback(lambda ign: self.do_cli("put", self.test_file_path,
193                                               "havasu:afile"))
194         d.addCallback(lambda ign: self.do_cli("mv", "havasu:afile",
195                                               "fake:anotherfile"))
196         d.addCallback(_check)
197         return d