Пример #1
0
    def test_delete_container(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test'
        self.assertEqual(backend.create_account(account_id), account_id)
        name = 'c'
        mtime = Timestamp(time()).normal

        # initial container
        backend.update_container(account_id, name, mtime, 0, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        # delete event
        sleep(.00001)
        dtime = Timestamp(time()).normal
        backend.update_container(account_id, name, 0, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertFalse(
            self.conn.exists('container:%s:%s' % (account_id, name)))

        # same event
        backend.update_container(account_id, name, 0, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertFalse(
            self.conn.exists('container:%s:%s' % (account_id, name)))
Пример #2
0
    def test_account_container_reset(self):
        data = {
            'name': 'foo',
            'mtime': Timestamp(time()).normal,
            'objects': 12,
            'bytes': 42
        }
        data = json.dumps(data)
        resp = self.app.post('/v1.0/account/container/update',
                             data=data,
                             query_string={'id': self.account_id})

        data = {'name': 'foo', 'mtime': Timestamp(time()).normal}
        data = json.dumps(data)
        resp = self.app.post('/v1.0/account/container/reset',
                             data=data,
                             query_string={'id': self.account_id})
        self.assertEqual(resp.status_code, 204)

        data = {'prefix': 'foo'}
        data = json.dumps(data)
        resp = self.app.post('/v1.0/account/containers',
                             data=data,
                             query_string={'id': self.account_id})
        resp = self.json_loads(resp.data)
        for container in resp["listing"]:
            name, nb_objects, nb_bytes, _ = container
            if name == 'foo':
                self.assertEqual(nb_objects, 0)
                self.assertEqual(nb_bytes, 0)
                return
        self.fail("No container foo")
Пример #3
0
    def test_utf8_container(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test'
        self.assertEqual(backend.create_account(account_id), account_id)
        name = u'La fête à la maison'
        mtime = Timestamp(time()).normal

        # create container
        backend.update_container(account_id, name, mtime, 0, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(unicode(res[0], 'utf8'), name)

        # ensure it appears in listing
        listing = backend.list_containers(account_id,
                                          marker='',
                                          delimiter='',
                                          limit=100)
        self.assertIn(name, [entry[0] for entry in listing])

        # delete container
        sleep(.00001)
        dtime = Timestamp(time()).normal
        backend.update_container(account_id, name, 0, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertTrue(
            self.conn.ttl('container:%s:%s' % (account_id, name)) >= 1)

        # ensure it has been removed
        with ExpectedException(Conflict):
            backend.update_container(account_id, name, 0, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertTrue(
            self.conn.ttl('container:%s:%s' % (account_id, name)) >= 1)
Пример #4
0
    def test_update_after_container_deletion(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test-%06x' % int(time())
        self.assertEqual(backend.create_account(account_id), account_id)

        # Container create event, sent immediately after creation
        backend.update_container(account_id, 'c1',
                                 Timestamp(time()).normal, None, None, None)

        # Container update event
        backend.update_container(account_id, 'c1',
                                 Timestamp(time()).normal, None, 3, 30)
        info = backend.info_account(account_id)
        self.assertEqual(info['containers'], 1)
        self.assertEqual(info['objects'], 3)
        self.assertEqual(info['bytes'], 30)

        # Container is flushed, but the event is deferred
        flush_timestamp = Timestamp(time()).normal

        sleep(.00001)
        # Container delete event, sent immediately after deletion
        backend.update_container(account_id, 'c1', None,
                                 Timestamp(time()).normal, None, None)

        # Deferred container update event (with lower timestamp)
        backend.update_container(account_id, 'c1', flush_timestamp, None, 0, 0)
        info = backend.info_account(account_id)
        self.assertEqual(info['containers'], 0)
        self.assertEqual(info['objects'], 0)
        self.assertEqual(info['bytes'], 0)
Пример #5
0
    def test_info_account(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test'
        self.assertEqual(backend.create_account(account_id), account_id)
        info = backend.info_account(account_id)
        self.assertEqual(info['id'], account_id)
        self.assertEqual(info['bytes'], 0)
        self.assertEqual(info['objects'], 0)
        self.assertEqual(info['containers'], 0)
        self.assertTrue(info['ctime'])

        # first container
        backend.update_container(account_id, 'c1',
                                 Timestamp(time()).normal, 0, 1, 1)
        info = backend.info_account(account_id)
        self.assertEqual(info['containers'], 1)
        self.assertEqual(info['objects'], 1)
        self.assertEqual(info['bytes'], 1)

        # second container
        sleep(.00001)
        backend.update_container(account_id, 'c2',
                                 Timestamp(time()).normal, 0, 0, 0)
        info = backend.info_account(account_id)
        self.assertEqual(info['containers'], 2)
        self.assertEqual(info['objects'], 1)
        self.assertEqual(info['bytes'], 1)

        # update second container
        sleep(.00001)
        backend.update_container(account_id, 'c2',
                                 Timestamp(time()).normal, 0, 1, 1)
        info = backend.info_account(account_id)
        self.assertEqual(info['containers'], 2)
        self.assertEqual(info['objects'], 2)
        self.assertEqual(info['bytes'], 2)

        # delete first container
        sleep(.00001)
        backend.update_container(account_id, 'c1', 0,
                                 Timestamp(time()).normal, 0, 0)
        info = backend.info_account(account_id)
        self.assertEqual(info['containers'], 1)
        self.assertEqual(info['objects'], 1)
        self.assertEqual(info['bytes'], 1)

        # delete second container
        sleep(.00001)
        backend.update_container(account_id, 'c2', 0,
                                 Timestamp(time()).normal, 0, 0)
        info = backend.info_account(account_id)
        self.assertEqual(info['containers'], 0)
        self.assertEqual(info['objects'], 0)
        self.assertEqual(info['bytes'], 0)
Пример #6
0
    def update_container(self,
                         account_id,
                         name,
                         mtime,
                         dtime,
                         object_count,
                         bytes_used,
                         autocreate_account=None,
                         autocreate_container=True):
        conn = self.conn
        if not account_id or not name:
            raise BadRequest("Missing account or container")

        if autocreate_account is None:
            autocreate_account = self.autocreate

        if mtime is None:
            mtime = '0'
        else:
            mtime = Timestamp(float(mtime)).normal
        if dtime is None:
            dtime = '0'
        else:
            dtime = Timestamp(float(dtime)).normal
        if object_count is None:
            object_count = 0
        if bytes_used is None:
            bytes_used = 0

        keys = [
            account_id,
            AccountBackend.ckey(account_id, name),
            ("containers:%s" % (account_id)), ("account:%s" % (account_id))
        ]
        args = [
            name, mtime, dtime, object_count, bytes_used, autocreate_account,
            Timestamp(time()).normal, EXPIRE_TIME, autocreate_container
        ]
        try:
            self.script_update_container(keys=keys, args=args, client=conn)
        except redis.exceptions.ResponseError as exc:
            if str(exc) == "no_account":
                raise NotFound("Account %s not found" % account_id)
            if str(exc) == "no_container":
                raise NotFound("Container %s not found" % name)
            elif str(exc) == "no_update_needed":
                raise Conflict("No update needed, "
                               "event older than last container update")
            else:
                raise

        return name
Пример #7
0
    def test_refresh_account(self):
        backend = AccountBackend({}, self.conn)
        account_id = random_str(16)
        account_key = 'account:%s' % account_id

        self.assertEqual(backend.create_account(account_id), account_id)

        total_bytes = 0
        total_objects = 0

        # 10 containers with bytes and objects
        for i in range(10):
            name = "container%d" % i
            mtime = Timestamp(time()).normal
            nb_bytes = random.randrange(100)
            total_bytes += nb_bytes
            nb_objets = random.randrange(100)
            total_objects += nb_objets
            backend.update_container(account_id, name, mtime, 0, nb_objets,
                                     nb_bytes)

        # change values
        self.conn.hset(account_key, 'bytes', 1)
        self.conn.hset(account_key, 'objects', 2)
        self.assertEqual(self.conn.hget(account_key, 'bytes'), '1')
        self.assertEqual(self.conn.hget(account_key, 'objects'), '2')

        backend.refresh_account(account_id)
        self.assertEqual(self.conn.hget(account_key, 'bytes'),
                         str(total_bytes))
        self.assertEqual(self.conn.hget(account_key, 'objects'),
                         str(total_objects))
Пример #8
0
    def update_container(self, account_id, name, mtime, dtime, object_count,
                         bytes_used):
        conn = self.conn
        if not account_id or not name:
            raise NotFound("Missing account or container")

        if mtime is None:
            mtime = '0'
        if dtime is None:
            dtime = '0'
        if object_count is None:
            object_count = 0
        if bytes_used is None:
            bytes_used = 0

        keys = [
            account_id,
            AccountBackend.ckey(account_id, name),
            ("containers:%s" % (account_id)), ("account:%s" % (account_id))
        ]
        args = [
            name, mtime, dtime, object_count, bytes_used, self.autocreate,
            Timestamp(time()).normal, EXPIRE_TIME
        ]
        try:
            self.script_update_container(keys=keys, args=args, client=conn)
        except redis.exceptions.ResponseError as e:
            if str(e) == "no_account":
                raise NotFound(account_id)
            elif str(e) == "no_update_needed":
                raise Conflict("No updated needed")
            else:
                raise e

        return name
Пример #9
0
    def test_account_flush(self):
        data = {
            'name': 'foo',
            'mtime': Timestamp(time()).normal,
            'objects': 12,
            'bytes': 42
        }
        data = json.dumps(data)
        resp = self.app.post('/v1.0/account/container/update',
                             data=data,
                             query_string={'id': self.account_id})

        resp = self.app.post('/v1.0/account/flush',
                             query_string={'id': self.account_id})
        self.assertEqual(resp.status_code, 204)

        resp = self.app.post('/v1.0/account/show',
                             query_string={'id': self.account_id})
        resp = self.json_loads(resp.data)
        self.assertEqual(resp["bytes"], 0)
        self.assertEqual(resp["objects"], 0)

        resp = self.app.post('/v1.0/account/containers',
                             query_string={'id': self.account_id})
        resp = self.json_loads(resp.data)
        self.assertEqual(len(resp["listing"]), 0)
Пример #10
0
    def test_flush_account(self):
        backend = AccountBackend({}, self.conn)
        account_id = random_str(16)
        account_key = 'account:%s' % account_id

        self.assertEqual(backend.create_account(account_id), account_id)

        total_bytes = 0
        total_objects = 0

        # 10 containers with bytes and objects
        for i in range(10):
            name = "container%d" % i
            mtime = Timestamp(time()).normal
            nb_bytes = random.randrange(100)
            total_bytes += nb_bytes
            nb_objets = random.randrange(100)
            total_objects += nb_objets
            backend.update_container(account_id, name, mtime, 0, nb_objets,
                                     nb_bytes)

        self.assertEqual(self.conn.hget(account_key, 'bytes'),
                         str(total_bytes))
        self.assertEqual(self.conn.hget(account_key, 'objects'),
                         str(total_objects))

        backend.flush_account(account_id)
        self.assertEqual(self.conn.hget(account_key, 'bytes'), '0')
        self.assertEqual(self.conn.hget(account_key, 'objects'), '0')
        self.assertEqual(self.conn.zcard("containers:%s" % account_id), 0)
        self.assertEqual(self.conn.exists("container:test:*"), 0)
Пример #11
0
 def _gen_results(objects):
     for obj in objects:
         result = (obj['name'], obj['size'], obj['hash'],
                   obj['version'], obj['deleted'], obj['mime_type'],
                   Timestamp(obj['ctime']).isoformat, obj['policy'],
                   _format_props(obj.get('properties', {})))
         yield result
Пример #12
0
 def test_account_container_update(self):
     data = {
         'name': 'foo',
         'mtime': Timestamp(time()).normal,
         'objects': 0,
         'bytes': 0
     }
     data = json.dumps(data)
     resp = self.app.post('/v1.0/account/container/update',
                          data=data,
                          query_string={'id': self.account_id})
     self.assertEqual(resp.status_code, 200)
Пример #13
0
    def test_delete_container(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test'
        self.assertEqual(backend.create_account(account_id), account_id)
        name = 'c'
        old_mtime = Timestamp(time() - 1).normal
        mtime = Timestamp(time()).normal

        # initial container
        backend.update_container(account_id, name, mtime, 0, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        # delete event
        sleep(.00001)
        dtime = Timestamp(time()).normal
        backend.update_container(account_id, name, mtime, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertTrue(
            self.conn.ttl('container:%s:%s' % (account_id, name)) >= 1)

        # same event
        with ExpectedException(Conflict):
            backend.update_container(account_id, name, mtime, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertTrue(
            self.conn.ttl('container:%s:%s' % (account_id, name)) >= 1)

        # old event
        with ExpectedException(Conflict):
            backend.update_container(account_id, name, old_mtime, 0, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertTrue(
            self.conn.ttl('container:%s:%s' % (account_id, name)) >= 1)
Пример #14
0
    def create_account(self, account_id):
        conn = self.conn
        if not account_id:
            return None
        if conn.hget('accounts:', account_id):
            return None

        lock = acquire_lock_with_timeout(conn, 'account:%s' % account_id, 1)
        if not lock:
            return None

        pipeline = conn.pipeline(True)
        pipeline.hset('accounts:', account_id, 1)
        pipeline.hmset('account:%s' % account_id, {
            'id': account_id,
            'bytes': 0,
            'objects': 0,
            'ctime': Timestamp(time()).normal
        })
        pipeline.execute()
        release_lock(conn, 'account:%s' % account_id, lock)
        return account_id
Пример #15
0
    def test_list_containers(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test'

        backend.create_account(account_id)
        for cont1 in xrange(4):
            for cont2 in xrange(125):
                name = '%d-%04d' % (cont1, cont2)
                backend.update_container(account_id, name,
                                         Timestamp(time()).normal, 0, 0, 0)

        for cont in xrange(125):
            name = '2-0051-%04d' % cont
            backend.update_container(account_id, name,
                                     Timestamp(time()).normal, 0, 0, 0)

        for cont in xrange(125):
            name = '3-%04d-0049' % cont
            backend.update_container(account_id, name,
                                     Timestamp(time()).normal, 0, 0, 0)

        listing = backend.list_containers(account_id,
                                          marker='',
                                          delimiter='',
                                          limit=100)
        self.assertEqual(len(listing), 100)
        self.assertEqual(listing[0][0], '0-0000')
        self.assertEqual(listing[-1][0], '0-0099')

        listing = backend.list_containers(account_id,
                                          marker='',
                                          end_marker='0-0050',
                                          delimiter='',
                                          limit=100)
        self.assertEqual(len(listing), 50)
        self.assertEqual(listing[0][0], '0-0000')
        self.assertEqual(listing[-1][0], '0-0049')

        listing = backend.list_containers(account_id,
                                          marker='0-0099',
                                          delimiter='',
                                          limit=100)
        self.assertEqual(len(listing), 100)
        self.assertEqual(listing[0][0], '0-0100')
        self.assertEqual(listing[-1][0], '1-0074')

        listing = backend.list_containers(account_id,
                                          marker='1-0074',
                                          delimiter='',
                                          limit=55)
        self.assertEqual(len(listing), 55)
        self.assertEqual(listing[0][0], '1-0075')
        self.assertEqual(listing[-1][0], '2-0004')

        listing = backend.list_containers(account_id,
                                          marker='',
                                          prefix='0-01',
                                          delimiter='',
                                          limit=10)
        self.assertEqual(len(listing), 10)
        self.assertEqual(listing[0][0], '0-0100')
        self.assertEqual(listing[-1][0], '0-0109')

        listing = backend.list_containers(account_id,
                                          marker='',
                                          prefix='0-01',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 10)
        self.assertEqual(listing[0][0], '0-0100')
        self.assertEqual(listing[-1][0], '0-0109')

        listing = backend.list_containers(account_id,
                                          marker='',
                                          prefix='0-',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 10)
        self.assertEqual(listing[0][0], '0-0000')
        self.assertEqual(listing[-1][0], '0-0009')

        listing = backend.list_containers(account_id,
                                          marker='',
                                          prefix='',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 4)
        self.assertEqual([c[0] for c in listing], ['0-', '1-', '2-', '3-'])

        listing = backend.list_containers(account_id,
                                          marker='2-',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 1)
        self.assertEqual([c[0] for c in listing], ['3-'])

        listing = backend.list_containers(account_id,
                                          marker='',
                                          prefix='2',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 1)
        self.assertEqual([c[0] for c in listing], ['2-'])

        listing = backend.list_containers(account_id,
                                          marker='2-0050',
                                          prefix='2-',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 10)
        self.assertEqual(listing[0][0], '2-0051')
        self.assertEqual(listing[1][0], '2-0051-')
        self.assertEqual(listing[2][0], '2-0052')
        self.assertEqual(listing[-1][0], '2-0059')

        listing = backend.list_containers(account_id,
                                          marker='3-0045',
                                          prefix='3-',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 10)
        self.assertEqual([c[0] for c in listing], [
            '3-0045-', '3-0046', '3-0046-', '3-0047', '3-0047-', '3-0048',
            '3-0048-', '3-0049', '3-0049-', '3-0050'
        ])

        name = '3-0049-'
        backend.update_container(account_id, name,
                                 Timestamp(time()).normal, 0, 0, 0)
        listing = backend.list_containers(account_id,
                                          marker='3-0048',
                                          limit=10)
        self.assertEqual(len(listing), 10)
        self.assertEqual([c[0] for c in listing], [
            '3-0048-0049', '3-0049', '3-0049-', '3-0049-0049', '3-0050',
            '3-0050-0049', '3-0051', '3-0051-0049', '3-0052', '3-0052-0049'
        ])

        listing = backend.list_containers(account_id,
                                          marker='3-0048',
                                          prefix='3-',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 10)
        self.assertEqual([c[0] for c in listing], [
            '3-0048-', '3-0049', '3-0049-', '3-0050', '3-0050-', '3-0051',
            '3-0051-', '3-0052', '3-0052-', '3-0053'
        ])

        listing = backend.list_containers(account_id,
                                          prefix='3-0049-',
                                          delimiter='-',
                                          limit=10)
        self.assertEqual(len(listing), 2)
        self.assertEqual([c[0] for c in listing], ['3-0049-', '3-0049-0049'])
Пример #16
0
    def test_update_container(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test'
        self.assertEqual(backend.create_account(account_id), account_id)

        # initial container
        name = '"{<container \'&\' name>}"'
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # same event
        backend.update_container(account_id, name, mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # New event
        sleep(.00001)
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # Old event
        old_mtime = Timestamp(time() - 1).normal
        backend.update_container(account_id, name, old_mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # Old delete event
        dtime = Timestamp(time() - 1).normal
        backend.update_container(account_id, name, 0, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)
        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # New delete event
        sleep(.00001)
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, 0, mtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertFalse(
            self.conn.exists('container:%s:%s' % (account_id, name)))

        # New event
        sleep(.00001)
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, mtime, 0, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)
        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)
Пример #17
0
    def test_update_container(self):
        backend = AccountBackend({}, self.conn)
        account_id = 'test'
        self.assertEqual(backend.create_account(account_id), account_id)

        # initial container
        name = '"{<container \'&\' name>}"'
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # same event
        with ExpectedException(Conflict):
            backend.update_container(account_id, name, mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # New event
        sleep(.00001)
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # Old event
        old_mtime = Timestamp(time() - 1).normal
        with ExpectedException(Conflict):
            backend.update_container(account_id, name, old_mtime, 0, 0, 0)

        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)

        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # Old delete event
        dtime = Timestamp(time() - 1).normal
        with ExpectedException(Conflict):
            backend.update_container(account_id, name, 0, dtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)
        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)

        # New delete event
        sleep(.00001)
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, 0, mtime, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(len(res), 0)
        self.assertTrue(
            self.conn.ttl('container:%s:%s' % (account_id, name)) >= 1)

        # New event
        sleep(.00001)
        mtime = Timestamp(time()).normal
        backend.update_container(account_id, name, mtime, 0, 0, 0)
        res = self.conn.zrangebylex('containers:%s' % account_id, '-', '+')
        self.assertEqual(res[0], name)
        self.assertEqual(
            self.conn.hget('container:%s:%s' % (account_id, name), 'mtime'),
            mtime)
        # ensure ttl has been removed
        self.assertEqual(self.conn.ttl('container:%s:%s' % (account_id, name)),
                         -1)
Пример #18
0
    def update_container(self, account_id, name, mtime, dtime, object_count,
                         bytes_used):
        conn = self.conn
        if not account_id or not name:
            return None
        _account_id = conn.hget('account:%s' % account_id, 'id')

        if not _account_id:
            if self.autocreate:
                self.create_account(account_id)
            else:
                return None

        lock = acquire_lock_with_timeout(
            conn, 'container:%s:%s' % (account_id, name), 1)
        if not lock:
            return None

        data = conn.hgetall('container:%s:%s' % (account_id, name))

        record = {
            'name': name,
            'mtime': mtime,
            'dtime': dtime,
            'objects': object_count,
            'bytes': bytes_used
        }
        deleted = False
        if data:
            data['mtime'] = Timestamp(data['mtime'])
            data['dtime'] = Timestamp(data['dtime'])

            for r in ['name', 'mtime', 'dtime', 'objects', 'bytes']:
                if record[r] is None and data[r] is not None:
                    record[r] = data[r]
            if data['mtime'] > record['mtime']:
                record['mtime'] = data['mtime']
            if data['dtime'] > record['dtime']:
                record['dtime'] = data['dtime']

        if record['dtime'] > record['mtime']:
            deleted = True

        if not deleted:
            incr_bytes_used = int_value(record.get('bytes'), 0) -\
                int_value(data.get('bytes'), 0)
            incr_object_count = int_value(record.get('objects'), 0) -\
                int_value(data.get('objects'), 0)
        else:
            incr_bytes_used = -int_value(data.get('bytes'), 0)
            incr_object_count = -int_value(data.get('objects'), 0)

        record.update({'name': name, 'account_uid': account_id})

        # replace None values
        for r in ['bytes', 'objects', 'mtime', 'dtime']:
            if record[r] is None:
                record[r] = 0

        ct = {str(name): 0}
        pipeline = conn.pipeline(True)
        if deleted:
            pipeline.delete('container:%s:%s' % (account_id, name))
            pipeline.zrem('containers:%s' % account_id, str(name))
        else:
            pipeline.hmset('container:%s:%s' % (account_id, name), record)
            pipeline.zadd('containers:%s' % account_id, **ct)
        if incr_object_count:
            pipeline.hincrby('account:%s' % account_id, 'objects',
                             incr_object_count)
        if incr_bytes_used:
            pipeline.hincrby('account:%s' % account_id, 'bytes',
                             incr_bytes_used)
        pipeline.execute()
        release_lock(conn, 'container:%s:%s' % (account_id, name), lock)
        return name
Пример #19
0
    def update_container(self, account_id, name, mtime, dtime, object_count,
                         bytes_used):
        conn = self.conn
        if not account_id or not name:
            return None
        _account_id = conn.hget('account:%s' % account_id, 'id')

        if not _account_id:
            if self.autocreate:
                self.create_account(account_id)
            else:
                return None

        lock = acquire_lock_with_timeout(conn,
                                         AccountBackend.ckey(account_id, name),
                                         1)
        if not lock:
            return None

        data = conn.hgetall(AccountBackend.ckey(account_id, name))

        record = {
            'name': name,
            'mtime': mtime or dtime,
            'dtime': dtime,
            'objects': object_count,
            'bytes': bytes_used
        }
        if data:
            data['mtime'] = Timestamp(data['mtime'])
            data['dtime'] = Timestamp(data['dtime'])

            for r in ['name', 'mtime', 'dtime', 'objects', 'bytes']:
                if record[r] is None and data[r] is not None:
                    record[r] = data[r]
            if data['mtime'] > record['mtime']:
                record['mtime'] = data['mtime']
            if data['dtime'] > record['dtime']:
                record['dtime'] = data['dtime']

        deleted = record['dtime'] >= record['mtime']

        if not deleted:
            incr_bytes_used = int_value(record.get('bytes'), 0) -\
                int_value(data.get('bytes'), 0)
            incr_object_count = int_value(record.get('objects'), 0) -\
                int_value(data.get('objects'), 0)
        elif record.get('mtime') > data.get('mtime'):
            incr_bytes_used = -int_value(data.get('bytes'), 0)
            incr_object_count = -int_value(data.get('objects'), 0)
        else:
            # The event has been delayed, the container has already
            # been deleted, and the object and bytes statistics have
            # already been reported to the account.
            incr_bytes_used = 0
            incr_object_count = 0

        record.update({'name': name, 'account_uid': account_id})

        # replace None values
        for r in ['bytes', 'objects', 'mtime', 'dtime']:
            if record[r] is None:
                record[r] = 0

        ct = {name: 0}
        pipeline = conn.pipeline(True)
        pipeline.hmset(AccountBackend.ckey(account_id, name), record)
        if deleted:
            pipeline.expire(AccountBackend.ckey(account_id, name), EXPIRE_TIME)
            pipeline.zrem('containers:%s' % account_id, name)
        else:
            pipeline.persist(AccountBackend.ckey(account_id, name))
            pipeline.zadd('containers:%s' % account_id, **ct)
        if incr_object_count:
            pipeline.hincrby('account:%s' % account_id, 'objects',
                             incr_object_count)
        if incr_bytes_used:
            pipeline.hincrby('account:%s' % account_id, 'bytes',
                             incr_bytes_used)
        pipeline.execute()
        release_lock(conn, AccountBackend.ckey(account_id, name), lock)
        return name