Revision 0c6ab9df

b/snf-pithos-app/pithos/api/functions.py
590 590
    try:
591 591
        request.backend.delete_container(
592 592
            request.user_uniq, v_account, v_container,
593
            until, delimiter=delimiter)
593
            until, delimiter=delimiter, listing_limit=settings.API_LIST_LIMIT)
594 594
    except NotAllowedError:
595 595
        raise faults.Forbidden('Not allowed')
596 596
    except ItemNotExists:
......
1037 1037
            version_id = copy_or_move_object(
1038 1038
                request, src_account, src_container, src_name,
1039 1039
                v_account, v_container, v_object,
1040
                move=True, delimiter=delimiter)
1040
                move=True, delimiter=delimiter,
1041
                listing_limit=settings.API_LIST_LIMIT)
1041 1042
        else:
1042 1043
            try:
1043 1044
                src_container, src_name = split_container_object_string(
......
1047 1048
            version_id = copy_or_move_object(
1048 1049
                request, src_account, src_container, src_name,
1049 1050
                v_account, v_container, v_object,
1050
                move=False, delimiter=delimiter)
1051
                move=False, delimiter=delimiter,
1052
                listing_limit=settings.API_LIST_LIMIT)
1051 1053
        response = HttpResponse(status=201)
1052 1054
        response['X-Object-Version'] = version_id
1053 1055
        return response
......
1229 1231

  
1230 1232
    version_id = copy_or_move_object(request, v_account, v_container, v_object,
1231 1233
                                     dest_account, dest_container, dest_name,
1232
                                     move=False, delimiter=delimiter)
1234
                                     move=False, delimiter=delimiter,
1235
                                     listing_limit=settings.API_LIST_LIMIT)
1233 1236
    response = HttpResponse(status=201)
1234 1237
    response['X-Object-Version'] = version_id
1235 1238
    return response
......
1524 1527
    try:
1525 1528
        request.backend.delete_object(
1526 1529
            request.user_uniq, v_account, v_container,
1527
            v_object, until, delimiter=delimiter)
1530
            v_object, until, delimiter=delimiter,
1531
            listing_limit=settings.API_LIST_LIMIT)
1528 1532
    except NotAllowedError:
1529 1533
        raise faults.Forbidden('Not allowed')
1530 1534
    except ItemNotExists:
b/snf-pithos-app/pithos/api/test/containers.py
933 933
        r = self.delete(url)
934 934
        self.assertEqual(r.status_code, 404)
935 935

  
936
    @pithos_test_settings(API_LIST_LIMIT=10)
936 937
    def test_delete_contents(self):
937 938
        folder = self.create_folder('c1')[0]
938
        descendant = strnextling(folder)
939
        self.upload_object('c1', descendant)
939
        for i in range(11):
940
            descendant = '%s_%d' % (strnextling(folder), i)
941
            self.upload_object('c1', descendant)
940 942
        self.create_folder('c1', '%s/%s' % (folder, get_random_data(5)))[0]
941 943

  
942
        self.delete('%s?delimiter=/' % join_urls(
944
        r = self.delete('%s?delimiter=/' % join_urls(
943 945
            self.pithos_path, self.user, 'c1'))
946
        self.assertEqual(r.status_code, 204)
944 947
        self.assertEqual([], self.list_objects('c1'))
945 948
        self.assertTrue('c1' in self.list_containers(format=None))
b/snf-pithos-app/pithos/api/test/objects.py
41 41
from pithos.api.test import (PithosAPITest, pithos_settings,
42 42
                             AssertMappingInvariant, AssertUUidInvariant,
43 43
                             TEST_BLOCK_SIZE, TEST_HASH_ALGORITHM,
44
                             DATE_FORMATS)
44
                             DATE_FORMATS, pithos_test_settings)
45 45
from pithos.api.test.util import (md5_hash, merkle, strnextling,
46 46
                                  get_random_data, get_random_name)
47 47

  
......
924 924
                         get_random_name(), self.object))
925 925
        self.assertEqual(r.status_code, 404)
926 926

  
927
    @pithos_test_settings(API_LIST_LIMIT=10)
927 928
    def test_copy_dir(self):
928 929
        folder = self.create_folder(self.container)[0]
929 930
        subfolder = self.create_folder(
930 931
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
931 932
        objects = [subfolder]
932 933
        append = objects.append
933
        append(self.upload_object(self.container,
934
                                  '%s/%s' % (folder, get_random_name()),
935
                                  depth='1')[0])
936
        append(self.upload_object(self.container,
937
                                  '%s/%s' % (subfolder, get_random_name()),
938
                                  depth='2')[0])
934
        for i in range(11):
935
            append(self.upload_object(self.container,
936
                                      '%s/%d' % (folder, i),
937
                                      depth='1')[0])
939 938
        other = self.upload_object(self.container, strnextling(folder))[0]
940 939

  
941 940
        # copy dir
......
1006 1005
        r = self.head(url)
1007 1006
        self.assertEqual(r.status_code, 404)
1008 1007

  
1008
    @pithos_test_settings(API_LIST_LIMIT=10)
1009 1009
    def test_move_dir(self):
1010 1010
        folder = self.create_folder(self.container)[0]
1011 1011
        subfolder = self.create_folder(
1012 1012
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
1013 1013
        objects = [subfolder]
1014 1014
        append = objects.append
1015
        append(self.upload_object(self.container,
1016
                                  '%s/%s' % (folder, get_random_name()),
1017
                                  depth='1')[0])
1018
        append(self.upload_object(self.container,
1019
                                  '%s/%s' % (subfolder, get_random_name()),
1020
                                  depth='1')[0])
1015
        for i in range(11):
1016
            append(self.upload_object(self.container,
1017
                                      '%s/%d' % (folder, i),
1018
                                      depth='1')[0])
1021 1019
        other = self.upload_object(self.container, strnextling(folder))[0]
1022 1020

  
1023 1021
        # move dir
......
1212 1210
            self.assertTrue('X-Object-Hash' in r)
1213 1211
            self.assertEqual(r['X-Object-Hash'], self.etag)
1214 1212

  
1215
                        # assert source object still exists
1213
            # assert source object still exists
1216 1214
            url = join_urls(self.pithos_path, self.user, self.container,
1217 1215
                            self.object)
1218 1216
            r = self.head(url)
......
1229 1227
            self.assertTrue('X-Object-Hash' in r)
1230 1228
            self.assertEqual(r['X-Object-Hash'], self.etag)
1231 1229

  
1230
    @pithos_test_settings(API_LIST_LIMIT=10)
1231
    def test_copy_dir_contents(self):
1232
        folder = self.create_folder(self.container)[0]
1233
        subfolder = self.create_folder(
1234
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
1235
        objects = [subfolder]
1236
        append = objects.append
1237
        for i in range(11):
1238
            append(self.upload_object(self.container,
1239
                                      '%s/%d' % (folder, i),
1240
                                      depth='1')[0])
1241
        other = self.upload_object(self.container, strnextling(folder))[0]
1242

  
1243
        # copy dir
1244
        url = join_urls(self.pithos_path, self.user, self.container,
1245
                        folder)
1246
        copy_folder = self.create_folder(self.container)[0]
1247
        r = self.copy('%s?delimiter=/' % url,
1248
                      HTTP_X_OBJECT_META_TEST='testcopy',
1249
                      HTTP_DESTINATION='/%s/%s' % (self.container,
1250
                                                   copy_folder))
1251
        self.assertEqual(r.status_code, 201)
1252

  
1253
        for obj in objects:
1254
            # assert object exists
1255
            url = join_urls(self.pithos_path, self.user, self.container,
1256
                            obj.replace(folder, copy_folder))
1257
            r = self.head(url)
1258
            self.assertEqual(r.status_code, 200)
1259

  
1260
        # assert other has not been created under copy folder
1261
        url = join_urls(self.pithos_path, self.user, self.container,
1262
                        '%s/%s' % (copy_folder,
1263
                                   other.replace(folder, copy_folder)))
1264
        r = self.head(url)
1265
        self.assertEqual(r.status_code, 404)
1266

  
1232 1267
    def test_copy_to_other_account(self):
1233 1268
        # create a container under alice account
1234 1269
        cname = self.create_container(user='alice')[0]
......
1347 1382
        r = self.head(url)
1348 1383
        self.assertEqual(r.status_code, 404)
1349 1384

  
1385
    @pithos_test_settings(API_LIST_LIMIT=10)
1386
    def test_move_dir_contents(self):
1387
        folder = self.create_folder(self.container)[0]
1388
        subfolder = self.create_folder(
1389
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
1390
        objects = [subfolder]
1391
        append = objects.append
1392
        for i in range(11):
1393
            append(self.upload_object(self.container,
1394
                                      '%s/%d' % (folder, i),
1395
                                      depth='1')[0])
1396
        other = self.upload_object(self.container, strnextling(folder))[0]
1397

  
1398
        # copy dir
1399
        url = join_urls(self.pithos_path, self.user, self.container, folder)
1400
        copy_folder = self.create_folder(self.container)[0]
1401
        r = self.move('%s?delimiter=/' % url,
1402
                      HTTP_X_OBJECT_META_TEST='testcopy',
1403
                      HTTP_DESTINATION='/%s/%s' % (self.container,
1404
                                                   copy_folder))
1405
        self.assertEqual(r.status_code, 201)
1406

  
1407
        for obj in objects:
1408
            # assert object exists
1409
            url = join_urls(self.pithos_path, self.user, self.container,
1410
                            obj.replace(folder, copy_folder))
1411
            r = self.head(url)
1412
            self.assertEqual(r.status_code, 200)
1413

  
1414
        # assert other has not been created under copy folder
1415
        url = join_urls(self.pithos_path, self.user, self.container,
1416
                        '%s/%s' % (copy_folder,
1417
                                   other.replace(folder, copy_folder)))
1418
        r = self.head(url)
1419
        self.assertEqual(r.status_code, 404)
1420

  
1350 1421
    def test_move_to_other_container(self):
1351 1422
        # move object to other container (not existing)
1352 1423
        cname = get_random_name()
......
1920 1991
        r = self.delete(url)
1921 1992
        self.assertEqual(r.status_code, 404)
1922 1993

  
1994
    @pithos_test_settings(API_LIST_LIMIT=10)
1923 1995
    def test_delete_dir(self):
1924 1996
        folder = self.create_folder(self.container)[0]
1925 1997
        subfolder = self.create_folder(
1926 1998
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
1927 1999
        objects = [subfolder]
1928 2000
        append = objects.append
1929
        append(self.upload_object(self.container,
1930
                                  '%s/%s' % (folder, get_random_name()),
1931
                                  depth='1')[0])
1932
        append(self.upload_object(self.container,
1933
                                  '%s/%s' % (subfolder, get_random_name()),
1934
                                  depth='2')[0])
2001
        for i in range(11):
2002
            append(self.upload_object(self.container,
2003
                                      '%s/%d' % (folder, i),
2004
                                      depth='1')[0])
1935 2005
        other = self.upload_object(self.container, strnextling(folder))[0]
1936 2006

  
1937 2007
        # move dir
b/snf-pithos-app/pithos/api/util.py
482 482

  
483 483
def copy_or_move_object(request, src_account, src_container, src_name,
484 484
                        dest_account, dest_container, dest_name,
485
                        move=False, delimiter=None):
485
                        move=False, delimiter=None, listing_limit=None):
486 486
    """Copy or move an object."""
487 487

  
488 488
    if 'ignore_content_type' in request.GET and 'CONTENT_TYPE' in request.META:
......
494 494
            version_id = request.backend.move_object(
495 495
                request.user_uniq, src_account, src_container, src_name,
496 496
                dest_account, dest_container, dest_name,
497
                content_type, 'pithos', meta, False, permissions, delimiter)
497
                content_type, 'pithos', meta, False, permissions, delimiter,
498
                listing_limit=listing_limit)
498 499
        else:
499 500
            version_id = request.backend.copy_object(
500 501
                request.user_uniq, src_account, src_container, src_name,
501 502
                dest_account, dest_container, dest_name,
502 503
                content_type, 'pithos', meta, False, permissions,
503
                src_version, delimiter)
504
                src_version, delimiter, listing_limit=listing_limit)
504 505
    except NotAllowedError:
505 506
        raise faults.Forbidden('Not allowed')
506 507
    except (ItemNotExists, VersionNotExists):
b/snf-pithos-backend/pithos/backends/modular.py
683 683
    @debug_method
684 684
    @backend_method
685 685
    def delete_container(self, user, account, container, until=None, prefix='',
686
                         delimiter=None):
686
                         delimiter=None, listing_limit=None):
687 687
        """Delete/purge the container with the given name."""
688 688

  
689 689
        self._can_write_container(user, account, container)
......
731 731
            src_names = self._list_objects_no_limit(
732 732
                user, account, container, prefix='', delimiter=None,
733 733
                virtual=False, domain=None, keys=[], shared=False, until=None,
734
                size_range=None, all_props=True, public=False)
734
                size_range=None, all_props=True, public=False,
735
                listing_limit=listing_limit)
735 736
            paths = []
736 737
            for t in src_names:
737 738
                path = '/'.join((account, container, t[0]))
......
820 821

  
821 822
    def _list_objects_no_limit(self, user, account, container, prefix,
822 823
                               delimiter, virtual, domain, keys, shared, until,
823
                               size_range, all_props, public):
824
                               size_range, all_props, public,
825
                               listing_limit=10000):
824 826
        objects = []
825 827
        while True:
826
            marker = objects[-1] if objects else None
827
            limit = 10000
828
            marker = objects[-1][0] if objects else None
829
            limit = listing_limit
828 830
            l = self._list_objects(
829 831
                user, account, container, prefix, delimiter, marker, limit,
830 832
                virtual, domain, keys, shared, until, size_range, all_props,
......
1207 1209
                     dest_account, dest_container, dest_name, type,
1208 1210
                     dest_domain=None, dest_meta=None, replace_meta=False,
1209 1211
                     permissions=None, src_version=None, is_move=False,
1210
                     delimiter=None):
1212
                     delimiter=None, listing_limit=10000):
1211 1213

  
1212 1214
        report_size_change = not is_move
1213 1215
        dest_meta = dest_meta or {}
......
1249 1251
            src_names = self._list_objects_no_limit(
1250 1252
                user, src_account, src_container, prefix, delimiter=None,
1251 1253
                virtual=False, domain=None, keys=[], shared=False, until=None,
1252
                size_range=None, all_props=True, public=False)
1254
                size_range=None, all_props=True, public=False,
1255
                listing_limit=listing_limit)
1253 1256
            src_names.sort(key=lambda x: x[2])  # order by nodes
1254 1257
            paths = [elem[0] for elem in src_names]
1255 1258
            nodes = [elem[2] for elem in src_names]
......
1284 1287
    def copy_object(self, user, src_account, src_container, src_name,
1285 1288
                    dest_account, dest_container, dest_name, type, domain,
1286 1289
                    meta=None, replace_meta=False, permissions=None,
1287
                    src_version=None, delimiter=None):
1290
                    src_version=None, delimiter=None, listing_limit=None):
1288 1291
        """Copy an object's data and metadata."""
1289 1292

  
1290 1293
        meta = meta or {}
1291 1294
        dest_version_id = self._copy_object(
1292 1295
            user, src_account, src_container, src_name, dest_account,
1293 1296
            dest_container, dest_name, type, domain, meta, replace_meta,
1294
            permissions, src_version, False, delimiter)
1297
            permissions, src_version, False, delimiter,
1298
            listing_limit=listing_limit)
1295 1299
        return dest_version_id
1296 1300

  
1297 1301
    @debug_method
......
1299 1303
    def move_object(self, user, src_account, src_container, src_name,
1300 1304
                    dest_account, dest_container, dest_name, type, domain,
1301 1305
                    meta=None, replace_meta=False, permissions=None,
1302
                    delimiter=None):
1306
                    delimiter=None, listing_limit=None):
1303 1307
        """Move an object's data and metadata."""
1304 1308

  
1305 1309
        meta = meta or {}
......
1308 1312
        dest_version_id = self._move_object(
1309 1313
            user, src_account, src_container, src_name, dest_account,
1310 1314
            dest_container, dest_name, type, domain, meta, replace_meta,
1311
            permissions, None, delimiter=delimiter)
1315
            permissions, None, delimiter=delimiter,
1316
            listing_limit=listing_limit)
1312 1317
        return dest_version_id
1313 1318

  
1314 1319
    def _delete_object(self, user, account, container, name, until=None,
1315
                       delimiter=None, report_size_change=True):
1320
                       delimiter=None, report_size_change=True,
1321
                       listing_limit=None):
1316 1322
        if user != account:
1317 1323
            raise NotAllowedError
1318 1324

  
......
1377 1383
            src_names = self._list_objects_no_limit(
1378 1384
                user, account, container, prefix, delimiter=None,
1379 1385
                virtual=False, domain=None, keys=[], shared=False, until=None,
1380
                size_range=None, all_props=True, public=False)
1386
                size_range=None, all_props=True, public=False,
1387
                listing_limit=listing_limit)
1381 1388
            paths = []
1382 1389
            for t in src_names:
1383 1390
                path = '/'.join((account, container, t[0]))
......
1409 1416
    @debug_method
1410 1417
    @backend_method
1411 1418
    def delete_object(self, user, account, container, name, until=None,
1412
                      prefix='', delimiter=None):
1419
                      prefix='', delimiter=None, listing_limit=None):
1413 1420
        """Delete/purge an object."""
1414 1421

  
1415
        self._delete_object(user, account, container, name, until, delimiter)
1422
        self._delete_object(user, account, container, name, until, delimiter,
1423
                            listing_limit=listing_limit)
1416 1424

  
1417 1425
    @debug_method
1418 1426
    @backend_method

Also available in: Unified diff