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
8 timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
10 class Mv(GridTestMixin, CLITestMixin, unittest.TestCase):
11 def test_mv_behavior(self):
12 self.basedir = "cli/Mv/mv_behavior"
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:"))
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"))
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"))
42 # Next, make a remote directory.
43 d.addCallback(lambda res:
44 self.do_cli("mkdir", "tahoe: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):
53 "Error: You can't overwrite a directory with a file", err,
54 "mv shouldn't overwrite directories" ))
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"))
78 # directory/directory2/some_file
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"))
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",
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"))
105 def test_mv_error_if_DELETE_fails(self):
106 self.basedir = "cli/Mv/mv_error_if_DELETE_fails"
108 fn1 = os.path.join(self.basedir, "file1")
109 DATA1 = "Nuclear launch codes"
110 fileutil.write(fn1, DATA1)
112 original_do_http = tahoe_mv.do_http
113 def mock_do_http(method, url, body=""):
114 if method == "DELETE":
118 resp = FakeResponse()
119 resp.status = '500 Something Went Wrong'
120 resp.reason = '*shrug*'
123 return original_do_http(method, url, body=body)
124 tahoe_mv.do_http = mock_do_http
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:"))
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)
139 def _restore_do_http(res):
140 tahoe_mv.do_http = original_do_http
142 d.addBoth(_restore_do_http)
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
149 self.basedir = "cli/Mv/mv_without_alias"
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
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,
167 d.addCallback(lambda ign: self.do_cli("mv", "havasu:afile",
169 d.addCallback(_check)
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"
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
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,
194 d.addCallback(lambda ign: self.do_cli("mv", "havasu:afile",
196 d.addCallback(_check)