Ejemplo n.º 1
0
    def test_storage_single_put_get_delete(self):
        """Exercise storing and getting a single object"""
        collection = 'foo'
        wbo_data = { 
            "id": "abcd-1", 
            "sortindex": 1, 
            "payload": simplejson.dumps({ 'foo':1, 'bar':2 }),
            "modified": WBO.get_time_now()
        }
        auth_header = self.build_auth_header()
        storage_url = '/sync/1.0/%s/storage/%s/%s' % ( 
            self.USER_NAME, collection, wbo_data['id'] 
        )

        resp = self.app.get(storage_url, headers=auth_header, status=404)

        resp = self.app.put(storage_url, headers=auth_header, status=400,
            params="THIS IS NOT JSON")
        self.assertEqual('400 Bad Request', resp.status)

        resp = self.app.put(storage_url, headers=auth_header, 
            params=simplejson.dumps(wbo_data))
        self.assertEqual('200 OK', resp.status)
        self.assert_(WBO.get_time_now() >= float(resp.body))

        resp = self.app.get(storage_url, headers=auth_header)
        resp_wbo_data = simplejson.loads(resp.body)
        self.assertEqual(wbo_data['payload'], resp_wbo_data['payload'])

        resp = self.app.delete(storage_url, headers=auth_header)
        self.assertEqual('200 OK', resp.status)
        self.assert_(WBO.get_time_now() >= float(resp.body))

        resp = self.app.get(storage_url, headers=auth_header, status=404)
Ejemplo n.º 2
0
    def test_item_validation(self):
        """Exercise WBO data validation"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)
        too_long_id = ''.join('x' for x in range(100))

        self.assert_('invalid id' in WBO.validate({ 'id': '' }))
        self.assert_('invalid id' in WBO.validate({ 'id': 'foo/bar' }))
        self.assert_('invalid id' in WBO.validate({ 'id': too_long_id }))
        self.assert_('invalid id' not in WBO.validate({ 'id': 'abcd' }))

        self.assert_('invalid collection' in WBO.validate({ }))
        self.assert_('invalid collection' in 
            WBO.validate({ 'collection': Collection(name=too_long_id, profile=p) }))

        self.assert_('invalid predecessorid' in 
            WBO.validate({ 'collection':c, 'predecessorid': too_long_id }))
        self.assert_('invalid predecessorid' in 
            WBO.validate({ 'collection':c, 'predecessorid': 'abcdef' }))

        w = WBO(
            parent=c, collection=c, wbo_id='abcdef', 
            modified=WBO.get_time_now(), payload='test'
        )
        w.put()

        self.assert_('invalid predecessorid' not in 
            WBO.validate({ 'collection':c, 'predecessorid': 'abcdef' }))

        self.assert_('invalid predecessorid' in 
            WBO.validate({ 'collection':c, 'predecessorid': too_long_id }))
        self.assert_('invalid predecessorid' in 
            WBO.validate({ 'collection':c, 'predecessorid': 'defghi' }))

        w = WBO(
            parent=c, collection=c, wbo_id='defghi', 
            modified=WBO.get_time_now(), payload='test'
        )
        w.put()

        self.assert_('invalid predecessorid' not in 
            WBO.validate({ 'collection':c, 'predecessorid': 'abcdef' }))

        self.assert_('invalid modified date' in WBO.validate({ 'modified': 'abc' }))
        self.assert_('no modification date' in WBO.validate({ }))
        self.assert_('no modification date' in WBO.validate({ 'modified': '' }))

        self.assert_('invalid sortindex' in WBO.validate({ 'sortindex': 'abcd' }))
        self.assert_('invalid sortindex' in WBO.validate({ 'sortindex': -1000000000 }))
        self.assert_('invalid sortindex' in WBO.validate({ 'sortindex': 1000000000 }))

        self.assert_('payload needs to be json-encoded' in
            WBO.validate({ 'payload': 'abcd' }))
        self.assert_('payload too large' in 
            WBO.validate({ 'payload': 'x'.join('x' for x in range(500000)) }))
Ejemplo n.º 3
0
    def test_retrieval_by_id(self):
        """Exercise collection retrieval with a single ID"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        wbo_id = '1234'

        w = WBO(wbo_id=wbo_id,
                parent=c,
                collection=c,
                modified=WBO.get_time_now(),
                sortindex=1000,
                payload='payload-%s' % wbo_id,
                payload_size=9)
        w.put()

        url = '/sync/1.0/%s/storage/%s?id=%s' % (p.user_name, c.name, w.wbo_id)

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        self.log.debug('RESPONSE %s' % resp.body)
        self.assertEqual(w.wbo_id, result_data[0])

        url = '/sync/1.0/%s/storage/%s?id=%s&full=1' % (p.user_name, c.name,
                                                        w.wbo_id)

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        self.log.debug('RESPONSE %s' % resp.body)
        self.assertEqual(w.payload, result_data[0]['payload'])
Ejemplo n.º 4
0
    def test_retrieval_by_multiple_ids(self):
        """Exercise collection retrieval with multiple IDs"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        wbos = [ 
            WBO(wbo_id='%s' % wbo_id, parent=c, collection=c,
                modified=WBO.get_time_now(), sortindex=1000, payload='payload-%s' %
                wbo_id, payload_size=9
        ) for wbo_id in range(10) ]

        for w in wbos: w.put()

        wbo_ids = [w.wbo_id for w in wbos]

        url = '/sync/1.0/%s/storage/%s?ids=%s' % (
            p.user_name, c.name, ','.join(wbo_ids)
        )

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        wbo_ids.sort()
        result_data.sort()
        self.assertEqual(wbo_ids, result_data)
        self.assertEqual(len(wbo_ids), int(resp.headers['X-Weave-Records']))

        url = '/sync/1.0/%s/storage/%s?ids=%s&full=1' % (
            p.user_name, c.name, ','.join(wbo_ids)
        )

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        result_data.sort(lambda a,b: cmp(a['id'], b['id']))
        for idx in range(len(wbos)):
            self.assertEqual(wbos[idx].payload, result_data[idx]['payload'])
        self.assertEqual(len(wbo_ids), int(resp.headers['X-Weave-Records']))
Ejemplo n.º 5
0
    def test_retrieval_by_id(self):
        """Exercise collection retrieval with a single ID"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        wbo_id = '1234'

        w = WBO(wbo_id=wbo_id, parent=c, collection=c,
            modified=WBO.get_time_now(), sortindex=1000, 
            payload='payload-%s' % wbo_id, payload_size=9)
        w.put()

        url = '/sync/1.0/%s/storage/%s?id=%s' % (
            p.user_name, c.name, w.wbo_id
        )

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        self.log.debug('RESPONSE %s' % resp.body)
        self.assertEqual(w.wbo_id, result_data[0])

        url = '/sync/1.0/%s/storage/%s?id=%s&full=1' % (
            p.user_name, c.name, w.wbo_id
        )

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        self.log.debug('RESPONSE %s' % resp.body)
        self.assertEqual(w.payload, result_data[0]['payload'])
Ejemplo n.º 6
0
 def delete(self, user_name, collection_name, wbo_id):
     """Delete an item from the collection"""
     collection = Collection.get_by_profile_and_name(
         self.request.profile, collection_name)
     wbo = WBO.get_by_collection_and_wbo_id(collection, wbo_id)
     if not wbo: return self.error(404)
     wbo.delete()
     self.response.out.write('%s' % WBO.get_time_now())
Ejemplo n.º 7
0
 def delete(self, user_name, collection_name):
     """Bulk deletion of WBOs from a collection"""
     collection = Collection.get_by_profile_and_name(
         self.request.profile, collection_name)
     params = self.normalize_retrieval_parameters()
     params['wbo'] = True
     out = collection.retrieve(**params)
     db.delete(out)
     return WBO.get_time_now()
Ejemplo n.º 8
0
 def delete(self, user_name, collection_name, wbo_id):
     """Delete an item from the collection"""
     collection = Collection.get_by_profile_and_name(
         self.request.profile, collection_name
     )
     wbo = WBO.get_by_collection_and_wbo_id(collection, wbo_id)
     if not wbo: return self.error(404)
     wbo.delete()
     self.response.out.write('%s' % WBO.get_time_now())
Ejemplo n.º 9
0
 def delete(self, user_name, collection_name):
     """Bulk deletion of WBOs from a collection"""
     collection = Collection.get_by_profile_and_name(
         self.request.profile, collection_name
     )
     params = self.normalize_retrieval_parameters()
     params['wbo'] = True
     out = collection.retrieve(**params)
     db.delete(out)
     return WBO.get_time_now()
Ejemplo n.º 10
0
    def test_storage_single_put_get_delete(self):
        """Exercise storing and getting a single object"""
        collection = 'foo'
        wbo_data = {
            "id": "abcd-1",
            "sortindex": 1,
            "payload": simplejson.dumps({
                'foo': 1,
                'bar': 2
            }),
            "modified": WBO.get_time_now()
        }
        auth_header = self.build_auth_header()
        storage_url = '/sync/1.0/%s/storage/%s/%s' % (
            self.USER_NAME, collection, wbo_data['id'])

        resp = self.app.get(storage_url, headers=auth_header, status=404)

        resp = self.app.put(storage_url,
                            headers=auth_header,
                            status=400,
                            params="THIS IS NOT JSON")
        self.assertEqual('400 Bad Request', resp.status)

        resp = self.app.put(storage_url,
                            headers=auth_header,
                            params=simplejson.dumps(wbo_data))
        self.assertEqual('200 OK', resp.status)
        self.assert_(WBO.get_time_now() >= float(resp.body))

        resp = self.app.get(storage_url, headers=auth_header)
        resp_wbo_data = simplejson.loads(resp.body)
        self.assertEqual(wbo_data['payload'], resp_wbo_data['payload'])

        resp = self.app.delete(storage_url, headers=auth_header)
        self.assertEqual('200 OK', resp.status)
        self.assert_(WBO.get_time_now() >= float(resp.body))

        resp = self.app.get(storage_url, headers=auth_header, status=404)
Ejemplo n.º 11
0
    def build_wbo_parents_and_predecessors(self):
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        id_sets = dict([(kind, set([w[kind] for w in self.wbo_values]))
                        for kind in ('parentid', 'predecessorid')])

        for kind, id_set in id_sets.items():
            for wbo_id in id_set:
                w = WBO(parent=c,
                        collection=c,
                        modified=WBO.get_time_now(),
                        wbo_id=wbo_id,
                        payload=simplejson.dumps({'random': 'xxx'}))
                w.put()
Ejemplo n.º 12
0
    def test_bulk_update(self):
        """Exercise bulk collection update"""
        (p, c, ah)  = (self.profile, self.collection, self.auth_header)
        auth_header = self.build_auth_header()
        storage_url = '/sync/1.0/%s/storage/%s' % (p.user_name, c.name)

        self.build_wbo_parents_and_predecessors()

        bulk_data = [
            { 'id': '' },
            { 'id': 'foo/bar', 'sortindex': 'abcd' },
            { 'id': 'a-1000',  'sortindex':-1000000000 },
            { 'id': 'a-1001',  'sortindex': 1000000000 },
            { 'id': 'a-1002',  'parentid': 'notfound' },
            { 'id': 'a-1003',  'predecessorid': 'notfound' },
            { 'id': 'a-1004',  'payload': 'invalid' },
        ]
        bulk_data.extend(self.wbo_values)

        self.log.debug("DATA %s" % simplejson.dumps(bulk_data))

        resp = self.app.post(
            storage_url, headers=auth_header, 
            params=simplejson.dumps(bulk_data)
        )
        self.assertEqual('200 OK', resp.status)
        result_data = simplejson.loads(resp.body)

        self.log.debug("RESULT %s" % resp.body)

        self.assert_(WBO.get_time_now() >= float(result_data['modified']))

        expected_ids = [ w['id'] for w in self.wbo_values ]
        self.assertEqual(expected_ids, result_data['success'])
        
        expected_failures = {
            "": ["invalid id"], 
            "a-1004": ["payload needs to be json-encoded"], 
            "a-1003": ["invalid predecessorid"], 
            "a-1002": ["invalid parentid"], 
            "a-1001": ["invalid sortindex"], 
            "a-1000": ["invalid sortindex"], 
            "foo/bar": ["invalid id", "invalid sortindex"]
        }
        self.assertEqual(expected_failures, result_data['failed'])

        stored_ids = [ w.wbo_id for w in WBO.all() ]
        for wbo_id in expected_ids:
            self.assert_(wbo_id in stored_ids)
Ejemplo n.º 13
0
    def build_wbo_parents_and_predecessors(self):
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        id_sets = dict([
            (kind, set([ w[kind] for w in self.wbo_values ]))
            for kind in ('parentid', 'predecessorid')
        ])

        for kind, id_set in id_sets.items():
            for wbo_id in id_set:
                w = WBO(
                    parent=c, collection=c,
                    modified = WBO.get_time_now(), 
                    wbo_id   = wbo_id, 
                    payload  = simplejson.dumps({'random':'xxx'})
                )
                w.put()
Ejemplo n.º 14
0
    def test_deletion_by_multiple_ids(self):
        """Exercise bulk deletion with a set of IDs"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)
        wbos = self.build_wbo_set()

        wbo_ids = [w.wbo_id for w in wbos]
        to_delete_ids = wbo_ids[0:len(wbo_ids) / 2]

        url = '/sync/1.0/%s/storage/%s?ids=%s' % (p.user_name, c.name,
                                                  ','.join(to_delete_ids))

        resp = self.app.delete(url, headers=ah)
        self.assertEqual('200 OK', resp.status)
        self.assert_(WBO.get_time_now() >= float(resp.body))

        result_ids = [w.wbo_id for w in WBO.all()]
        for wbo_id in to_delete_ids:
            self.assert_(wbo_id not in result_ids)
Ejemplo n.º 15
0
    def test_deletion_by_multiple_ids(self):
        """Exercise bulk deletion with a set of IDs"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)
        wbos = self.build_wbo_set()

        wbo_ids = [w.wbo_id for w in wbos]
        to_delete_ids = wbo_ids[0:len(wbo_ids)/2]
        
        url = '/sync/1.0/%s/storage/%s?ids=%s' % (
            p.user_name, c.name, ','.join(to_delete_ids)
        )

        resp = self.app.delete(url, headers=ah)
        self.assertEqual('200 OK', resp.status)
        self.assert_(WBO.get_time_now() >= float(resp.body))

        result_ids = [w.wbo_id for w in WBO.all()]
        for wbo_id in to_delete_ids:
            self.assert_(wbo_id not in result_ids)
Ejemplo n.º 16
0
    def build_wbo_set(self, num_wbos=15):
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        self.build_wbo_parents_and_predecessors()

        wbos = []
        for values in self.wbo_values:
            w = WBO(parent=c,
                    collection=c,
                    modified=WBO.get_time_now(),
                    wbo_id=values['id'],
                    parentid=values['parentid'],
                    predecessorid=values['predecessorid'],
                    sortindex=values['sortindex'],
                    payload=values['payload'])
            w.put()
            wbos.append(w)
            time.sleep(0.1)  # HACK: Delay to ensure modified stamps vary

        return wbos
Ejemplo n.º 17
0
    def test_retrieval_by_index_above_and_below(self):
        """Exercise collection retrieval on sortindex range"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        wbo_sortindexes = (-100, -10, -1, 0, 1, 10, 23, 100, 999, 1000, 9999)

        wbos = []
        for idx in range(len(wbo_sortindexes)):
            sortindex = wbo_sortindexes[idx]
            wbo_id = '%s' % idx
            w = WBO(wbo_id=wbo_id,
                    parent=c,
                    collection=c,
                    modified=WBO.get_time_now(),
                    sortindex=sortindex,
                    payload='payload-%s' % wbo_id,
                    payload_size=9)
            w.put()
            self.log.debug("WBO      %s" % simplejson.dumps(w.to_dict()))
            wbos.append(w)

        # TODO: Try a variety of ranges here?
        (index_above, index_below) = (-10, 1000)

        expected_ids = [
            w.wbo_id for w in wbos
            if index_above < w.sortindex and w.sortindex < index_below
        ]

        url = '/sync/1.0/%s/storage/%s?index_above=%s&index_below=%s' % (
            p.user_name, c.name, index_above, index_below)
        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)

        expected_ids.sort()
        result_data.sort()

        self.log.debug("URL      %s" % url)
        self.log.debug("EXPECTED %s" % simplejson.dumps(expected_ids))
        self.log.debug("RESULT   %s" % resp.body)
        self.assertEqual(expected_ids, result_data)
Ejemplo n.º 18
0
    def build_wbo_set(self, num_wbos=15):
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        self.build_wbo_parents_and_predecessors()

        wbos = []
        for values in self.wbo_values:
            w = WBO(
                parent=c, collection=c,
                modified=WBO.get_time_now(), 
                wbo_id        = values['id'], 
                parentid      = values['parentid'],
                predecessorid = values['predecessorid'],
                sortindex     = values['sortindex'], 
                payload       = values['payload']
            )
            w.put()
            wbos.append(w)
            time.sleep(0.1) # HACK: Delay to ensure modified stamps vary

        return wbos
Ejemplo n.º 19
0
    def test_retrieval_by_index_above_and_below(self):
        """Exercise collection retrieval on sortindex range"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        wbo_sortindexes = ( -100, -10, -1, 0, 1, 10, 23, 100, 999, 1000, 9999 )

        wbos = [ ]
        for idx in range(len(wbo_sortindexes)):
            sortindex = wbo_sortindexes[idx]
            wbo_id = '%s' % idx
            w = WBO(wbo_id=wbo_id, parent=c, collection=c,
                modified=WBO.get_time_now(), 
                sortindex=sortindex, 
                payload='payload-%s' % wbo_id, payload_size=9)
            w.put()
            self.log.debug("WBO      %s" % simplejson.dumps(w.to_dict()))
            wbos.append(w)

        # TODO: Try a variety of ranges here?
        (index_above, index_below) = (-10, 1000)

        expected_ids = [
            w.wbo_id for w in wbos
            if index_above < w.sortindex and w.sortindex < index_below
        ]

        url = '/sync/1.0/%s/storage/%s?index_above=%s&index_below=%s' % (
            p.user_name, c.name, index_above, index_below
        )
        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)

        expected_ids.sort()
        result_data.sort()

        self.log.debug("URL      %s" % url)
        self.log.debug("EXPECTED %s" % simplejson.dumps(expected_ids))
        self.log.debug("RESULT   %s" % resp.body)
        self.assertEqual(expected_ids, result_data)
Ejemplo n.º 20
0
    def test_retrieval_by_multiple_ids(self):
        """Exercise collection retrieval with multiple IDs"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)

        wbos = [
            WBO(wbo_id='%s' % wbo_id,
                parent=c,
                collection=c,
                modified=WBO.get_time_now(),
                sortindex=1000,
                payload='payload-%s' % wbo_id,
                payload_size=9) for wbo_id in range(10)
        ]

        for w in wbos:
            w.put()

        wbo_ids = [w.wbo_id for w in wbos]

        url = '/sync/1.0/%s/storage/%s?ids=%s' % (p.user_name, c.name,
                                                  ','.join(wbo_ids))

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        wbo_ids.sort()
        result_data.sort()
        self.assertEqual(wbo_ids, result_data)
        self.assertEqual(len(wbo_ids), int(resp.headers['X-Weave-Records']))

        url = '/sync/1.0/%s/storage/%s?ids=%s&full=1' % (p.user_name, c.name,
                                                         ','.join(wbo_ids))

        resp = self.app.get(url, headers=ah)
        result_data = simplejson.loads(resp.body)
        result_data.sort(lambda a, b: cmp(a['id'], b['id']))
        for idx in range(len(wbos)):
            self.assertEqual(wbos[idx].payload, result_data[idx]['payload'])
        self.assertEqual(len(wbo_ids), int(resp.headers['X-Weave-Records']))
Ejemplo n.º 21
0
 def initialize(self, req, resp):
     webapp.RequestHandler.initialize(self, req, resp)
     self.log = logging.getLogger()
     self.response.headers['X-Weave-Timestamp'] = str(WBO.get_time_now())
Ejemplo n.º 22
0
    def test_collection_counts_and_timestamps(self):
        """Exercise collection counts and timestamps"""
        profile = Profile(user_name = 'tester-1', user_id='8675309', password = '******')
        profile.put()

        auth_header = self.build_auth_header(
            profile.user_name, profile.password
        )

        expected_count_all = 0
        expected_counts = {
            'clients':2, 'crypto':0, 'forms':6, 'history':0, 'keys':10,
            'meta':12, 'bookmarks':14, 'prefs':16, 'tabs':18, 'passwords':20,
            'foo':12, 'bar':14, 'baz':16
        }
        expected_dates = {}

        # Insert objects with random contents to satisfy the expected counts
        for collection_name, curr_count in expected_counts.items():
            base_url = '/sync/1.0/%s/storage/%s' % (
                profile.user_name, collection_name
            )
            for i in range(curr_count):
                resp = self.put_random_wbo(base_url, auth_header)
                expected_dates[collection_name] = float(resp.body)
                expected_count_all += 1

        # Ensure the counts match expected
        resp = self.app.get(
            '/sync/1.0/%s/info/collection_counts' % (profile.user_name),
            headers=auth_header
        )
        resp_data = simplejson.loads(resp.body)
        self.assertEqual(expected_counts, resp_data)

        # Ensure all timestamps are same or newer than expected.
        resp = self.app.get(
            '/sync/1.0/%s/info/collections' % (profile.user_name),
            headers=auth_header
        )
        resp_data = simplejson.loads(resp.body)
        for k,v in expected_dates.items():
            self.assert_(k in resp_data)
            self.assert_(resp_data[k] >= expected_dates[k])

        # Verify the count of all objects after creating
        result_count = WBO.all().count()
        self.assertEqual(expected_count_all, result_count)

        # Delete each collection and verify the count after
        for collection_name, curr_count in expected_counts.items():
            url = '/sync/1.0/%s/storage/%s' % (
                profile.user_name, collection_name
            )
            resp = self.app.delete(url, headers=auth_header)
            self.assert_(WBO.get_time_now() >= float(resp.body))

            expected_count_all -= curr_count
            result_count = WBO.all().count()
            self.assertEqual(expected_count_all, result_count)

        # No WBOs should be left after all collections deleted.
        result_count = WBO.all().count()
        self.assertEqual(0, result_count)
Ejemplo n.º 23
0
    def test_item_validation(self):
        """Exercise WBO data validation"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)
        too_long_id = ''.join('x' for x in range(100))

        self.assert_('invalid id' in WBO.validate({'id': ''}))
        self.assert_('invalid id' in WBO.validate({'id': 'foo/bar'}))
        self.assert_('invalid id' in WBO.validate({'id': too_long_id}))
        self.assert_('invalid id' not in WBO.validate({'id': 'abcd'}))

        self.assert_('invalid collection' in WBO.validate({}))
        self.assert_('invalid collection' in WBO.validate(
            {'collection': Collection(name=too_long_id, profile=p)}))

        self.assert_('invalid predecessorid' in WBO.validate(
            {
                'collection': c,
                'predecessorid': too_long_id
            }))
        self.assert_(
            'invalid predecessorid' in WBO.validate({
                'collection': c,
                'predecessorid': 'abcdef'
            }))

        w = WBO(parent=c,
                collection=c,
                wbo_id='abcdef',
                modified=WBO.get_time_now(),
                payload='test')
        w.put()

        self.assert_('invalid predecessorid' not in WBO.validate(
            {
                'collection': c,
                'predecessorid': 'abcdef'
            }))

        self.assert_('invalid predecessorid' in WBO.validate(
            {
                'collection': c,
                'predecessorid': too_long_id
            }))
        self.assert_(
            'invalid predecessorid' in WBO.validate({
                'collection': c,
                'predecessorid': 'defghi'
            }))

        w = WBO(parent=c,
                collection=c,
                wbo_id='defghi',
                modified=WBO.get_time_now(),
                payload='test')
        w.put()

        self.assert_('invalid predecessorid' not in WBO.validate(
            {
                'collection': c,
                'predecessorid': 'abcdef'
            }))

        self.assert_(
            'invalid modified date' in WBO.validate({'modified': 'abc'}))
        self.assert_('no modification date' in WBO.validate({}))
        self.assert_('no modification date' in WBO.validate({'modified': ''}))

        self.assert_(
            'invalid sortindex' in WBO.validate({'sortindex': 'abcd'}))
        self.assert_(
            'invalid sortindex' in WBO.validate({'sortindex': -1000000000}))
        self.assert_(
            'invalid sortindex' in WBO.validate({'sortindex': 1000000000}))

        self.assert_('payload needs to be json-encoded' in WBO.validate(
            {'payload': 'abcd'}))
        self.assert_('payload too large' in WBO.validate(
            {'payload': 'x'.join('x' for x in range(500000))}))
Ejemplo n.º 24
0
    def test_bulk_update(self):
        """Exercise bulk collection update"""
        (p, c, ah) = (self.profile, self.collection, self.auth_header)
        auth_header = self.build_auth_header()
        storage_url = '/sync/1.0/%s/storage/%s' % (p.user_name, c.name)

        self.build_wbo_parents_and_predecessors()

        bulk_data = [
            {
                'id': ''
            },
            {
                'id': 'foo/bar',
                'sortindex': 'abcd'
            },
            {
                'id': 'a-1000',
                'sortindex': -1000000000
            },
            {
                'id': 'a-1001',
                'sortindex': 1000000000
            },
            {
                'id': 'a-1002',
                'parentid': 'notfound'
            },
            {
                'id': 'a-1003',
                'predecessorid': 'notfound'
            },
            {
                'id': 'a-1004',
                'payload': 'invalid'
            },
        ]
        bulk_data.extend(self.wbo_values)

        self.log.debug("DATA %s" % simplejson.dumps(bulk_data))

        resp = self.app.post(storage_url,
                             headers=auth_header,
                             params=simplejson.dumps(bulk_data))
        self.assertEqual('200 OK', resp.status)
        result_data = simplejson.loads(resp.body)

        self.log.debug("RESULT %s" % resp.body)

        self.assert_(WBO.get_time_now() >= float(result_data['modified']))

        expected_ids = [w['id'] for w in self.wbo_values]
        self.assertEqual(expected_ids, result_data['success'])

        expected_failures = {
            "": ["invalid id"],
            "a-1004": ["payload needs to be json-encoded"],
            "a-1003": ["invalid predecessorid"],
            "a-1002": ["invalid parentid"],
            "a-1001": ["invalid sortindex"],
            "a-1000": ["invalid sortindex"],
            "foo/bar": ["invalid id", "invalid sortindex"]
        }
        self.assertEqual(expected_failures, result_data['failed'])

        stored_ids = [w.wbo_id for w in WBO.all()]
        for wbo_id in expected_ids:
            self.assert_(wbo_id in stored_ids)
Ejemplo n.º 25
0
    def test_collection_counts_and_timestamps(self):
        """Exercise collection counts and timestamps"""
        profile = Profile(user_name='tester-1',
                          user_id='8675309',
                          password='******')
        profile.put()

        auth_header = self.build_auth_header(profile.user_name,
                                             profile.password)

        expected_count_all = 0
        expected_counts = {
            'clients': 2,
            'crypto': 0,
            'forms': 6,
            'history': 0,
            'keys': 10,
            'meta': 12,
            'bookmarks': 14,
            'prefs': 16,
            'tabs': 18,
            'passwords': 20,
            'foo': 12,
            'bar': 14,
            'baz': 16
        }
        expected_dates = {}

        # Insert objects with random contents to satisfy the expected counts
        for collection_name, curr_count in expected_counts.items():
            base_url = '/sync/1.0/%s/storage/%s' % (profile.user_name,
                                                    collection_name)
            for i in range(curr_count):
                resp = self.put_random_wbo(base_url, auth_header)
                expected_dates[collection_name] = float(resp.body)
                expected_count_all += 1

        # Ensure the counts match expected
        resp = self.app.get('/sync/1.0/%s/info/collection_counts' %
                            (profile.user_name),
                            headers=auth_header)
        resp_data = simplejson.loads(resp.body)
        self.assertEqual(expected_counts, resp_data)

        # Ensure all timestamps are same or newer than expected.
        resp = self.app.get('/sync/1.0/%s/info/collections' %
                            (profile.user_name),
                            headers=auth_header)
        resp_data = simplejson.loads(resp.body)
        for k, v in expected_dates.items():
            self.assert_(k in resp_data)
            self.assert_(resp_data[k] >= expected_dates[k])

        # Verify the count of all objects after creating
        result_count = WBO.all().count()
        self.assertEqual(expected_count_all, result_count)

        # Delete each collection and verify the count after
        for collection_name, curr_count in expected_counts.items():
            url = '/sync/1.0/%s/storage/%s' % (profile.user_name,
                                               collection_name)
            resp = self.app.delete(url, headers=auth_header)
            self.assert_(WBO.get_time_now() >= float(resp.body))

            expected_count_all -= curr_count
            result_count = WBO.all().count()
            self.assertEqual(expected_count_all, result_count)

        # No WBOs should be left after all collections deleted.
        result_count = WBO.all().count()
        self.assertEqual(0, result_count)
Ejemplo n.º 26
0
 def initialize(self, req, resp):
     webapp.RequestHandler.initialize(self, req, resp)
     self.log = logging.getLogger()
     self.response.headers['X-Weave-Timestamp'] = str(WBO.get_time_now())