Skip to content

Commit 72fc976

Browse files
authored
Merge pull request #857 from guygurari/cp-mv-bug
address issue #854 : don't allow mv/cp of multiple files to single file
2 parents 15739e5 + 98b9854 commit 72fc976

File tree

3 files changed

+59
-6
lines changed

3 files changed

+59
-6
lines changed

run-tests-minio.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,32 @@ def pbucket(tail):
418418
## ====== Clean up local destination dir
419419
test_flushdir("Clean testsuite-out/", "testsuite-out")
420420

421+
## ====== Moving things without trailing '/'
422+
os.system('dd if=/dev/urandom of=testsuite-out/urandom1.bin bs=1k count=1 > /dev/null 2>&1')
423+
os.system('dd if=/dev/urandom of=testsuite-out/urandom2.bin bs=1k count=1 > /dev/null 2>&1')
424+
test_s3cmd("Put multiple files", ['put', 'testsuite-out/urandom1.bin', 'testsuite-out/urandom2.bin', '%s/' % pbucket(1)],
425+
must_find = ["%s/urandom1.bin" % pbucket(1), "%s/urandom2.bin" % pbucket(1)])
426+
427+
test_s3cmd("Move without '/'", ['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir' % pbucket(1)],
428+
retcode = 64,
429+
must_find = ['Destination must be a directory'])
430+
431+
test_s3cmd("Move recursive w/a '/'",
432+
['-r', 'mv', '%s/dir1' % pbucket(1), '%s/dir2' % pbucket(1)],
433+
retcode = 64,
434+
must_find = ['Destination must be a directory'])
435+
436+
## ====== Moving multiple files into directory with trailing '/'
437+
must_find = ["'%s/urandom1.bin' -> '%s/dir/urandom1.bin'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir/urandom2.bin'" % (pbucket(1),pbucket(1))]
438+
must_not_find = ["'%s/urandom1.bin' -> '%s/dir'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir'" % (pbucket(1),pbucket(1))]
439+
test_s3cmd("Move multiple files",
440+
['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir/' % pbucket(1)],
441+
must_find = must_find,
442+
must_not_find = must_not_find)
443+
444+
## ====== Clean up local destination dir
445+
test_flushdir("Clean testsuite-out/", "testsuite-out")
446+
421447
## ====== Sync from S3
422448
must_find = [ "'%s/xyz/binary/random-crap.md5' -> 'testsuite-out/xyz/binary/random-crap.md5'" % pbucket(1) ]
423449
if have_encoding:

run-tests.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ def test_curl_HEAD(label, src_file, **kwargs):
266266
cmd.append(src_file)
267267
return test(label, cmd, **kwargs)
268268

269-
bucket_prefix = u"%s-" % getpass.getuser()
269+
bucket_prefix = u"%s-" % getpass.getuser().lower()
270270

271271
argv = sys.argv[1:]
272272
while argv:
@@ -415,14 +415,39 @@ def pbucket(tail):
415415
## ====== Clean up local destination dir
416416
test_flushdir("Clean testsuite-out/", "testsuite-out")
417417

418+
## ====== Moving things without trailing '/'
419+
os.system('dd if=/dev/urandom of=testsuite-out/urandom1.bin bs=1k count=1 > /dev/null 2>&1')
420+
os.system('dd if=/dev/urandom of=testsuite-out/urandom2.bin bs=1k count=1 > /dev/null 2>&1')
421+
test_s3cmd("Put multiple files", ['put', 'testsuite-out/urandom1.bin', 'testsuite-out/urandom2.bin', '%s/' % pbucket(1)],
422+
must_find = ["%s/urandom1.bin" % pbucket(1), "%s/urandom2.bin" % pbucket(1)])
423+
424+
test_s3cmd("Move without '/'", ['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir' % pbucket(1)],
425+
retcode = 64,
426+
must_find = ['Destination must be a directory'])
427+
428+
test_s3cmd("Move recursive w/a '/'",
429+
['-r', 'mv', '%s/dir1' % pbucket(1), '%s/dir2' % pbucket(1)],
430+
retcode = 64,
431+
must_find = ['Destination must be a directory'])
432+
433+
## ====== Moving multiple files into directory with trailing '/'
434+
must_find = ["'%s/urandom1.bin' -> '%s/dir/urandom1.bin'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir/urandom2.bin'" % (pbucket(1),pbucket(1))]
435+
must_not_find = ["'%s/urandom1.bin' -> '%s/dir'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir'" % (pbucket(1),pbucket(1))]
436+
test_s3cmd("Move multiple files",
437+
['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir/' % pbucket(1)],
438+
must_find = must_find,
439+
must_not_find = must_not_find)
440+
441+
## ====== Clean up local destination dir
442+
test_flushdir("Clean testsuite-out/", "testsuite-out")
443+
418444
## ====== Sync from S3
419445
must_find = [ "'%s/xyz/binary/random-crap.md5' -> 'testsuite-out/xyz/binary/random-crap.md5'" % pbucket(1) ]
420446
if have_encoding:
421447
must_find.append(u"'%(pbucket)s/xyz/encodings/%(encoding)s/%(pattern)s' -> 'testsuite-out/xyz/encodings/%(encoding)s/%(pattern)s' " % { 'encoding' : encoding, 'pattern' : enc_pattern, 'pbucket' : pbucket(1) })
422448
test_s3cmd("Sync from S3", ['sync', '%s/xyz' % pbucket(1), 'testsuite-out'],
423449
must_find = must_find)
424450

425-
426451
## ====== Remove 'demo' directory
427452
test_rmdir("Remove 'dir-test/'", "testsuite-out/xyz/dir-test/")
428453

s3cmd

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -813,9 +813,13 @@ def subcmd_cp_mv(args, process_fce, action_str, message):
813813

814814
info(u"Summary: %d remote files to %s" % (remote_count, action_str))
815815

816+
if not destination_base.endswith('/'):
817+
# Trying to mv dir1/ to dir2 will not pass a test in S3.FileLists,
818+
# so we don't need to test for it here.
819+
if len(remote_list) > 1 or cfg.recursive:
820+
raise ParameterError("Destination must be a directory and end with '/' when acting on multiple sources.")
821+
816822
if cfg.recursive:
817-
if not destination_base.endswith("/"):
818-
destination_base += "/"
819823
for key in remote_list:
820824
remote_list[key]['dest_name'] = destination_base + key
821825
else:
@@ -1144,8 +1148,6 @@ def cmd_sync_remote2local(args):
11441148
if not destination_base.endswith(os.path.sep):
11451149
if fetch_source_args[0].endswith(u'/') or len(fetch_source_args) > 1:
11461150
raise ParameterError("Destination must be a directory and end with '/' when downloading multiple sources.")
1147-
elif fetch_source_args[0].endswith(u'/'):
1148-
fetch_source_args[0] += u'/'
11491151

11501152
stats_info = StatsInfo()
11511153

0 commit comments

Comments
 (0)