Browse code

raise exception for missing '/' during mv, cp

When trying to mv/cp multiple files, or recursively, make sure that the
destination ends with ‘/‘. Otherwise, raise an exception.

Guy Gur-Ari authored on 2017/04/20 04:19:53
Showing 3 changed files
... ...
@@ -397,6 +397,32 @@ f.close()
397 397
 ## ====== Clean up local destination dir
398 398
 test_flushdir("Clean testsuite-out/", "testsuite-out")
399 399
 
400
+## ====== Moving things without trailing '/'
401
+os.system('dd if=/dev/urandom of=testsuite-out/urandom1.bin bs=1k count=1 > /dev/null 2>&1')
402
+os.system('dd if=/dev/urandom of=testsuite-out/urandom2.bin bs=1k count=1 > /dev/null 2>&1')
403
+test_s3cmd("Put multiple files", ['put', 'testsuite-out/urandom1.bin', 'testsuite-out/urandom2.bin', '%s/' % pbucket(1)],
404
+           must_find = ["%s/urandom1.bin" % pbucket(1), "%s/urandom2.bin" % pbucket(1)])
405
+
406
+test_s3cmd("Move without '/'", ['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir' % pbucket(1)],
407
+           retcode = 64,
408
+           must_find = ['Destination must be a directory'])
409
+
410
+test_s3cmd("Move recursive w/a '/'",
411
+           ['-r', 'mv', '%s/dir1' % pbucket(1), '%s/dir2' % pbucket(1)],
412
+           retcode = 64,
413
+           must_find = ['Destination must be a directory'])
414
+
415
+## ====== Moving multiple files into directory with trailing '/'
416
+must_find = ["'%s/urandom1.bin' -> '%s/dir/urandom1.bin'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir/urandom2.bin'" % (pbucket(1),pbucket(1))]
417
+must_not_find = ["'%s/urandom1.bin' -> '%s/dir'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir'" % (pbucket(1),pbucket(1))]
418
+test_s3cmd("Move multiple files",
419
+           ['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir/' % pbucket(1)],
420
+           must_find = must_find,
421
+           must_not_find = must_not_find)
422
+
423
+## ====== Clean up local destination dir
424
+test_flushdir("Clean testsuite-out/", "testsuite-out")
425
+
400 426
 ## ====== Sync from S3
401 427
 must_find = [ "'%s/xyz/binary/random-crap.md5' -> 'testsuite-out/xyz/binary/random-crap.md5'" % pbucket(1) ]
402 428
 if have_encoding:
... ...
@@ -393,14 +393,26 @@ f.close()
393 393
 ## ====== Clean up local destination dir
394 394
 test_flushdir("Clean testsuite-out/", "testsuite-out")
395 395
 
396
-## ====== Move multiple files into directory
397
-must_find = ["'%s/urandom1.bin' -> '%s/dir/urandom1.bin'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir/urandom2.bin'" % (pbucket(1),pbucket(1))]
398
-must_not_find = ["'%s/urandom1.bin' -> '%s/dir'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir'" % (pbucket(1),pbucket(1))]
396
+## ====== Moving things without trailing '/'
399 397
 os.system('dd if=/dev/urandom of=testsuite-out/urandom1.bin bs=1k count=1 > /dev/null 2>&1')
400 398
 os.system('dd if=/dev/urandom of=testsuite-out/urandom2.bin bs=1k count=1 > /dev/null 2>&1')
401 399
 test_s3cmd("Put multiple files", ['put', 'testsuite-out/urandom1.bin', 'testsuite-out/urandom2.bin', '%s/' % pbucket(1)],
402 400
            must_find = ["%s/urandom1.bin" % pbucket(1), "%s/urandom2.bin" % pbucket(1)])
403
-test_s3cmd("Move multiple files", ['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir' % pbucket(1)],
401
+
402
+test_s3cmd("Move without '/'", ['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir' % pbucket(1)],
403
+           retcode = 64,
404
+           must_find = ['Destination must be a directory'])
405
+
406
+test_s3cmd("Move recursive w/a '/'",
407
+           ['-r', 'mv', '%s/dir1' % pbucket(1), '%s/dir2' % pbucket(1)],
408
+           retcode = 64,
409
+           must_find = ['Destination must be a directory'])
410
+
411
+## ====== Moving multiple files into directory with trailing '/'
412
+must_find = ["'%s/urandom1.bin' -> '%s/dir/urandom1.bin'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir/urandom2.bin'" % (pbucket(1),pbucket(1))]
413
+must_not_find = ["'%s/urandom1.bin' -> '%s/dir'" % (pbucket(1),pbucket(1)), "'%s/urandom2.bin' -> '%s/dir'" % (pbucket(1),pbucket(1))]
414
+test_s3cmd("Move multiple files",
415
+           ['mv', '%s/urandom1.bin' % pbucket(1), '%s/urandom2.bin' % pbucket(1), '%s/dir/' % pbucket(1)],
404 416
            must_find = must_find,
405 417
            must_not_find = must_not_find)
406 418
 
... ...
@@ -806,14 +806,16 @@ def subcmd_cp_mv(args, process_fce, action_str, message):
806 806
 
807 807
     info(u"Summary: %d remote files to %s" % (remote_count, action_str))
808 808
 
809
+    if not destination_base.endswith('/'):
810
+        # Trying to mv dir1/ to dir2 will not pass a test in S3.FileLists,
811
+        # so we don't need to test for it here.
812
+        if len(remote_list) > 1 or cfg.recursive:
813
+           raise ParameterError("Destination must be a directory and end with '/' when acting on multiple sources.")
814
+
809 815
     if cfg.recursive:
810
-        if not destination_base.endswith("/"):
811
-            destination_base += "/"
812 816
         for key in remote_list:
813 817
             remote_list[key]['dest_name'] = destination_base + key
814 818
     else:
815
-        if len(remote_list) > 1 and not destination_base.endswith("/"):
816
-            destination_base += "/"
817 819
         for key in remote_list:
818 820
             if destination_base.endswith("/"):
819 821
                 remote_list[key]['dest_name'] = destination_base + key