Esempio n. 1
0
    def test_validation(self):
        data = {'parentid': 'bigid' * 30}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)

        data = {'parentid': 'id', 'sortindex': 9999999999}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)

        data = {'parentid': 'id', 'sortindex': '9999.1'}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)
        self.assertTrue(wbo['sortindex'], 9999)

        data = {'parentid': 'id', 'sortindex': 'ok'}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)

        data = {'parentid':  33, 'sortindex': '12'}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)
        self.assertEquals(wbo['parentid'], '33')
        self.assertEquals(wbo['sortindex'], 12)

        for bad_ttl in ('bouh', -1, 31537000):
            data = {'parentid':  33, 'ttl': bad_ttl}
            wbo = WBO(data)
            result, failure = wbo.validate()
            self.assertFalse(result)

        data = {'parentid':  33, 'ttl': 3600}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)

        data = {'payload':  "X" * 30000}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)

        data = {'payload':  "X" * 300000}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)
Esempio n. 2
0
    def test_validation(self):
        data = {'parentid': 'bigid' * 30}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)

        data = {'parentid': 'id', 'sortindex': 9999999999}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)

        data = {'parentid': 'id', 'sortindex': '9999.1'}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)
        self.assertTrue(wbo['sortindex'], 9999)

        data = {'parentid': 'id', 'sortindex': 'ok'}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)

        data = {'parentid': 33, 'sortindex': '12'}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)
        self.assertEquals(wbo['parentid'], '33')
        self.assertEquals(wbo['sortindex'], 12)

        for bad_ttl in ('bouh', -1, 31537000):
            data = {'parentid': 33, 'ttl': bad_ttl}
            wbo = WBO(data)
            result, failure = wbo.validate()
            self.assertFalse(result)

        data = {'parentid': 33, 'ttl': 3600}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)

        data = {'payload': "X" * 30000}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertTrue(result)

        data = {'payload': "X" * 300000}
        wbo = WBO(data)
        result, failure = wbo.validate()
        self.assertFalse(result)
    def set_item(self, request):
        """Sets a single WBO object."""
        storage = self._get_storage(request)
        if storage.use_quota:
            left = self._check_quota(request)
        else:
            left = 0.

        user_id = request.user['userid']
        collection_name = request.sync_info['collection']
        item_id = request.sync_info['item']

        if self._was_modified(request, user_id, collection_name):
            raise HTTPPreconditionFailed(collection_name)

        try:
            data = json.loads(request.body)
        except ValueError:
            raise HTTPJsonBadRequest(WEAVE_MALFORMED_JSON)

        try:
            wbo = WBO(data)
        except ValueError:
            raise HTTPJsonBadRequest(WEAVE_INVALID_WBO)

        consistent, msg = wbo.validate()
        if not consistent:
            raise HTTPJsonBadRequest(WEAVE_INVALID_WBO)

        if self._has_modifiers(wbo):
            wbo['modified'] = request.server_time

        try:
            res = storage.set_item(user_id, collection_name, item_id,
                                   storage_time=request.server_time, **wbo)
        except StorageConflictError:
            raise HTTPJsonBadRequest(WEAVE_INVALID_WRITE)
        response = json_response(res)
        if storage.use_quota and left <= _ONE_MEG:
            response.headers['X-Weave-Quota-Remaining'] = str(left)
        return response
    def set_collection(self, request):
        """Sets a batch of WBO objects into a collection."""

        user_id = request.user['userid']
        collection_name = request.sync_info['collection']

        if self._was_modified(request, user_id, collection_name):
            raise HTTPPreconditionFailed(collection_name)

        try:
            wbos = json.loads(request.body)
        except ValueError:
            raise HTTPJsonBadRequest(WEAVE_MALFORMED_JSON)

        if not isinstance(wbos, (tuple, list)):
            # thats a batch of one
            try:
                id_ = str(wbos['id'])
            except (KeyError, TypeError):
                raise HTTPJsonBadRequest(WEAVE_INVALID_WBO)
            if '/' in id_:
                raise HTTPJsonBadRequest(WEAVE_INVALID_WBO)

            request.sync_info['item'] = id_
            return self.set_item(request)

        res = {'success': [], 'failed': {}}

        # Sanity-check each of the WBOs.
        # Limit the batch based on both count and payload size.
        kept_wbos = []
        total_bytes = 0
        for count, wbo in enumerate(wbos):
            try:
                wbo = WBO(wbo)
            except ValueError:
                res['failed'][''] = ['invalid wbo']
                continue

            if 'id' not in wbo:
                res['failed'][''] = ['invalid id']
                continue

            consistent, msg = wbo.validate()
            item_id = wbo['id']
            if not consistent:
                res['failed'][item_id] = [msg]
                continue

            if count >= self.batch_max_count:
                res['failed'][item_id] = ['retry wbo']
                continue
            if 'payload' in wbo:
                total_bytes += len(wbo['payload'])
            if total_bytes >= self.batch_max_bytes:
                res['failed'][item_id] = ['retry bytes']
                continue

            if self._has_modifiers(wbo):
                wbo['modified'] = request.server_time

            kept_wbos.append(wbo)

        storage = self._get_storage(request)
        if storage.use_quota:
            left = self._check_quota(request)
        else:
            left = 0.

        storage_time = request.server_time

        for wbos in batch(kept_wbos, size=self.batch_size):
            wbos = list(wbos)   # to avoid exhaustion
            try:
                storage.set_items(user_id, collection_name,
                                  wbos, storage_time=storage_time)

            except Exception, e:   # we want to swallow the 503 in that case
                # something went wrong
                self.logger.error('Could not set items')
                self.logger.error(str(e))
                for wbo in wbos:
                    res['failed'][wbo['id']] = "db error"
            else:
                res['success'].extend([wbo['id'] for wbo in wbos])