Beispiel #1
0
 def testExpandoNestedConstructor(self):
     p = model.Expando(foo=42, bar=model.Expando(hello='hello'))
     self.assertEqual(p.foo, 42)
     self.assertEqual(p.bar.hello, 'hello')
     pb = p._to_pb()
     q = model.Expando._from_pb(pb)
     self.assertEqual(q.foo, 42)
     self.assertEqual(q.bar.hello, 'hello')
Beispiel #2
0
 def testExpandoConstructor(self):
     p = model.Expando(foo=42, bar='hello')
     self.assertEqual(p.foo, 42)
     self.assertEqual(p.bar, 'hello')
     pb = p.ToPb()
     q = model.Expando()
     q.FromPb(pb)
     self.assertEqual(q.foo, 42)
     self.assertEqual(q.bar, 'hello')
Beispiel #3
0
 def testExpandoNested(self):
     p = model.Expando()
     nest = model.Expando()
     nest.foo = 42
     nest.bar = 'hello'
     p.nest = nest
     self.assertEqual(p.nest.foo, 42)
     self.assertEqual(p.nest.bar, 'hello')
     pb = p._to_pb()
     q = model.Expando._from_pb(pb)
     self.assertEqual(q.nest.foo, 42)
     self.assertEqual(q.nest.bar, 'hello')
Beispiel #4
0
 def foo():
   key1 = model.Key(flat=('Foo', 1))
   key2 = model.Key(flat=('Foo', 2))
   ent1 = model.Expando(key=key1, foo=42, bar='hello')
   ent2 = model.Expando(key=key2, foo=1, bar='world')
   k1, k2 = yield self.ctx.put(ent1), self.ctx.put(ent2)
   self.assertEqual(k1, key1)
   self.assertEqual(k2, key2)
   yield tasklets.sleep(0.01)  # Let other tasklet complete.
   keys = [k1.urlsafe(), k2.urlsafe()]
   results = memcache.get_multi(keys, key_prefix='NDB:')
   self.assertEqual(
     results,
     {key1.urlsafe(): self.ctx._conn.adapter.entity_to_pb(ent1),
      key2.urlsafe(): self.ctx._conn.adapter.entity_to_pb(ent2)})
Beispiel #5
0
 def foo():
     ents = [model.Expando() for i in range(10)]
     futs = [self.ctx.put(ent) for ent in ents]
     keys = yield futs
     futs = [self.ctx.get(key) for key in keys]
     ents2 = yield futs
     self.assertEqual(ents2, ents)
     raise tasklets.Return(keys)
Beispiel #6
0
 def foo():
   key1 = model.Key(flat=('Foo', 1))
   key2 = model.Key(flat=('Foo', 2))
   ent1 = model.Expando(key=key1, foo=42, bar='hello')
   ent2 = model.Expando(key=key2, foo=1, bar='world')
   key1a, key2a = yield self.ctx.put(ent1),  self.ctx.put(ent2)
   self.assertTrue(key1 in self.ctx._cache)  # Whitebox.
   self.assertTrue(key2 in self.ctx._cache)  # Whitebox.
   self.assertEqual(key1, key1a)
   self.assertEqual(key2, key2a)
   @tasklets.tasklet
   def callback(ent):
     return ent
   qry = query.Query(kind='Foo')
   results = yield self.ctx.map_query(qry, callback)
   self.assertEqual(results, [ent1, ent2])
   self.assertTrue(results[0] is ent1)
   self.assertTrue(results[1] is ent2)
Beispiel #7
0
 def testExpandoWrite(self):
     k = model.Key(flat=['Model', 42])
     p = model.Expando(key=k)
     p.k = k
     p.p = 42
     p.q = 'hello'
     p.d = 2.5
     pb = p.ToPb()
     self.assertEqual(str(pb), GOLDEN_PB)
Beispiel #8
0
        def foo():
            ent = model.Expando(key=key, bar=1)

            @tasklets.tasklet
            def callback():
                ctx = tasklets.get_context()
                key = yield ctx.put(ent)
                taskqueue.add(url='/', transactional=True)

            yield self.ctx.transaction(callback)
Beispiel #9
0
        def foo():
            ent = model.Expando(key=key, bar=1)

            @tasklets.tasklet
            def callback():
                ctx = tasklets.get_context()
                key = yield ent.put_async()
                raise model.Rollback()

            yield self.ctx.transaction(callback)
Beispiel #10
0
    def testExpandoRead(self):
        class Person(model.Model):
            name = model.StringProperty()
            city = model.StringProperty()

        p = Person(name='Guido', city='SF')
        pb = p.ToPb()
        q = model.Expando()
        q.FromPb(pb)
        self.assertEqual(q.name, 'Guido')
        self.assertEqual(q.city, 'SF')
Beispiel #11
0
 def foo():
     key1 = model.Key(flat=('Foo', 1))
     ent1 = model.Expando(key=key1, foo=42, bar='hello')
     key = yield self.ctx.put(ent1)
     self.assertTrue(key1 not in self.ctx._cache)  # Whitebox.
     a = yield self.ctx.get(key1)
     b = yield self.ctx.get(key1)
     self.assertTrue(a is not b)
     yield self.ctx.delete(key1)
     self.assertTrue(key not in self.ctx._cache)  # Whitebox.
     a = yield self.ctx.get(key1)
     self.assertTrue(a is None)
Beispiel #12
0
 def testExpandoWrite(self):
     k = model.Key(flat=['Model', 42])
     p = model.Expando(key=k)
     p.k = k
     p.p = 42
     p.q = 'hello'
     p.u = TESTUSER
     p.d = 2.5
     p.b = True
     p.xy = AMSTERDAM
     pb = p._to_pb()
     self.assertEqual(str(pb), GOLDEN_PB)
Beispiel #13
0
 def foo():
   key = model.Key(flat=('Foo', 1))
   ent = model.Expando(key=key, bar=1)
   yield self.ctx.put(ent)
   @tasklets.tasklet
   def callback():
     ctx = tasklets.get_context()
     self.assertTrue(key not in ctx._cache)  # Whitebox.
     e = yield key.get_async()
     self.assertTrue(key in ctx._cache)  # Whitebox.
     e.bar = 2
     yield e.put_async()
   yield self.ctx.transaction(callback)
   self.assertEqual(self.ctx._cache[key].bar, 2)
Beispiel #14
0
    def testContext_CachePolicyDisabledLater(self):
        # If the cache is disabled after an entity is stored in the cache,
        # further get() attempts *must not* return the result stored in cache.

        self.ctx.set_cache_policy(lambda key: True)
        key1 = model.Key(flat=('Foo', 1))
        ent1 = model.Expando(key=key1)
        self.ctx.put(ent1).get_result()

        # get() uses cache
        self.assertTrue(key1 in self.ctx._cache)  # Whitebox.
        self.assertEqual(self.ctx.get(key1).get_result(), ent1)

        # get() uses cache
        self.ctx._cache[key1] = None  # Whitebox.
        self.assertEqual(self.ctx.get(key1).get_result(), None)

        # get() doesn't use cache
        self.ctx.set_cache_policy(lambda key: False)
        self.assertEqual(self.ctx.get(key1).get_result(), ent1)
Beispiel #15
0
 def foo():
     key1 = model.Key(flat=('Foo', 1))
     ent1 = model.Expando(key=key1, foo=42, bar='hello')
     key = yield ctx.put(ent1)
     a = yield ctx.get(key1)
Beispiel #16
0
 def testBasicSetup1(self):
     ent = model.Expando()
     ent.foo = 'bar'
     rpc = self.conn.async_put(None, [ent])
     [key] = rpc.get_result()
     self.assertEqual(key, model.Key(flat=['Expando', 1]))
Beispiel #17
0
 def foo():
     # Foo class is declared in query_test, so let's get a unusual class name.
     key1 = model.Key(flat=('ThisModelClassDoesntExist', 1))
     ent1 = model.Expando(key=key1, foo=42, bar='hello')
     key = yield ctx.put(ent1)
     a = yield ctx.get(key1)
Beispiel #18
0
class ContextTests(test_utils.DatastoreTest):
    def setUp(self):
        super(ContextTests, self).setUp()
        self.set_up_eventloop()
        MyAutoBatcher.reset_log()
        self.ctx = context.Context(
            conn=model.make_connection(default_model=model.Expando),
            auto_batcher_class=MyAutoBatcher)

    def set_up_eventloop(self):
        if eventloop._EVENT_LOOP_KEY in os.environ:
            del os.environ[eventloop._EVENT_LOOP_KEY]
        self.ev = eventloop.get_event_loop()
        self.log = []

    def testContext_AutoBatcher_Get(self):
        @tasklets.tasklet
        def foo():
            key1 = model.Key(flat=['Foo', 1])
            key2 = model.Key(flat=['Foo', 2])
            key3 = model.Key(flat=['Foo', 3])
            fut1 = self.ctx.get(key1)
            fut2 = self.ctx.get(key2)
            fut3 = self.ctx.get(key3)
            ent1 = yield fut1
            ent2 = yield fut2
            ent3 = yield fut3
            raise tasklets.Return([ent1, ent2, ent3])

        ents = foo().get_result()
        self.assertEqual(ents, [None, None, None])
        self.assertEqual(len(MyAutoBatcher._log), 1)

    @tasklets.tasklet
    def create_entities(self):
        key0 = model.Key(flat=['Foo', None])
        ent1 = model.Model(key=key0)
        ent2 = model.Model(key=key0)
        ent3 = model.Model(key=key0)
        fut1 = self.ctx.put(ent1)
        fut2 = self.ctx.put(ent2)
        fut3 = self.ctx.put(ent3)
        key1 = yield fut1
        key2 = yield fut2
        key3 = yield fut3
        raise tasklets.Return([key1, key2, key3])

    def testContext_AutoBatcher_Put(self):
        keys = self.create_entities().get_result()
        self.assertEqual(len(keys), 3)
        self.assertTrue(None not in keys)
        self.assertEqual(len(MyAutoBatcher._log), 1)

    def testContext_AutoBatcher_Delete(self):
        @tasklets.tasklet
        def foo():
            key1 = model.Key(flat=['Foo', 1])
            key2 = model.Key(flat=['Foo', 2])
            key3 = model.Key(flat=['Foo', 3])
            fut1 = self.ctx.delete(key1)
            fut2 = self.ctx.delete(key2)
            fut3 = self.ctx.delete(key3)
            yield fut1
            yield fut2
            yield fut3

        foo().check_success()
        self.assertEqual(len(MyAutoBatcher._log), 1)

    def testContext_MultiRpc(self):
        # This test really tests the proper handling of MultiRpc by
        # queue_rpc() in eventloop.py.  It's easier to test from here, and
        # gives more assurance that it works.
        config = datastore_rpc.Configuration(max_get_keys=3,
                                             max_put_entities=3)
        self.ctx._conn = model.make_connection(config,
                                               default_model=model.Expando)

        @tasklets.tasklet
        def foo():
            ents = [model.Expando() for i in range(10)]
            futs = [self.ctx.put(ent) for ent in ents]
            keys = yield futs
            futs = [self.ctx.get(key) for key in keys]
            ents2 = yield futs
            self.assertEqual(ents2, ents)
            raise tasklets.Return(keys)

        keys = foo().get_result()
        print keys
        self.assertEqual(len(keys), 10)

    def testContext_Cache(self):
        @tasklets.tasklet
        def foo():
            key1 = model.Key(flat=('Foo', 1))
            ent1 = model.Expando(key=key1, foo=42, bar='hello')
            key = yield self.ctx.put(ent1)
            self.assertTrue(key1 in self.ctx._cache)  # Whitebox.
            a = yield self.ctx.get(key1)
            b = yield self.ctx.get(key1)
            self.assertTrue(a is b)
            yield self.ctx.delete(key1)
            self.assertTrue(self.ctx._cache[key] is None)  # Whitebox.
            a = yield self.ctx.get(key1)
            self.assertTrue(a is None)

        foo().check_success()

    def testContext_CachePolicy(self):
        def should_cache(key):
            return False

        @tasklets.tasklet
        def foo():
            key1 = model.Key(flat=('Foo', 1))
            ent1 = model.Expando(key=key1, foo=42, bar='hello')
            key = yield self.ctx.put(ent1)
            self.assertTrue(key1 not in self.ctx._cache)  # Whitebox.
            a = yield self.ctx.get(key1)
            b = yield self.ctx.get(key1)
            self.assertTrue(a is not b)
            yield self.ctx.delete(key1)
            self.assertTrue(key not in self.ctx._cache)  # Whitebox.
            a = yield self.ctx.get(key1)
            self.assertTrue(a is None)

        self.ctx.set_cache_policy(should_cache)
        foo().check_success()

    def testContext_CachePolicyDisabledLater(self):
        # If the cache is disabled after an entity is stored in the cache,
        # further get() attempts *must not* return the result stored in cache.

        self.ctx.set_cache_policy(lambda key: True)
        key1 = model.Key(flat=('Foo', 1))
        ent1 = model.Expando(key=key1)
        self.ctx.put(ent1).get_result()

        # get() uses cache
        self.assertTrue(key1 in self.ctx._cache)  # Whitebox.
        self.assertEqual(self.ctx.get(key1).get_result(), ent1)

        # get() uses cache
        self.ctx._cache[key1] = None  # Whitebox.
        self.assertEqual(self.ctx.get(key1).get_result(), None)

        # get() doesn't use cache
        self.ctx.set_cache_policy(lambda key: False)
        self.assertEqual(self.ctx.get(key1).get_result(), ent1)

    def testContext_Memcache(self):
        @tasklets.tasklet
        def foo():
            key1 = model.Key(flat=('Foo', 1))
            key2 = model.Key(flat=('Foo', 2))
            ent1 = model.Expando(key=key1, foo=42, bar='hello')
            ent2 = model.Expando(key=key2, foo=1, bar='world')
            k1, k2 = yield self.ctx.put(ent1), self.ctx.put(ent2)
            self.assertEqual(k1, key1)
            self.assertEqual(k2, key2)
            yield tasklets.sleep(0.01)  # Let other tasklet complete.
            keys = [k1.urlsafe(), k2.urlsafe()]
            results = memcache.get_multi(keys, key_prefix='NDB:')
            self.assertEqual(
                results, {
                    key1.urlsafe(): self.ctx._conn.adapter.entity_to_pb(ent1),
                    key2.urlsafe(): self.ctx._conn.adapter.entity_to_pb(ent2)
                })

        foo().check_success()

    def testContext_MemcachePolicy(self):
        badkeys = []

        def tracking_set_multi(*args, **kwds):
            try:
                res = save_set_multi(*args, **kwds)
                if badkeys and not res:
                    res = badkeys
                track.append((args, kwds, res, None))
                return res
            except Exception, err:
                track.append((args, kwds, None, err))
                raise

        @tasklets.tasklet
        def foo():
            k1, k2 = yield self.ctx.put(ent1), self.ctx.put(ent2)
            self.assertEqual(k1, key1)
            self.assertEqual(k2, key2)
            yield tasklets.sleep(0.01)  # Let other tasklet complete.

        key1 = model.Key('Foo', 1)
        key2 = model.Key('Foo', 2)
        ent1 = model.Expando(key=key1, foo=42, bar='hello')
        ent2 = model.Expando(key=key2, foo=1, bar='world')
        save_set_multi = memcache.set_multi
        try:
            memcache.set_multi = tracking_set_multi
            memcache.flush_all()

            track = []
            foo().check_success()
            self.assertEqual(len(track), 1)
            self.assertEqual(track[0][0], ({
                key1.urlsafe(): ent1._to_pb(),
                key2.urlsafe(): ent2._to_pb()
            }, ))
            self.assertEqual(track[0][1], {'key_prefix': 'NDB:', 'time': 0})
            memcache.flush_all()

            track = []
            self.ctx.set_memcache_policy(lambda key: False)
            foo().check_success()
            self.assertEqual(len(track), 0)
            memcache.flush_all()

            track = []
            self.ctx.set_memcache_policy(lambda key: key == key1)
            foo().check_success()
            self.assertEqual(len(track), 1)
            self.assertEqual(track[0][0], ({key1.urlsafe(): ent1._to_pb()}, ))
            self.assertEqual(track[0][1], {'key_prefix': 'NDB:', 'time': 0})
            memcache.flush_all()

            track = []
            self.ctx.set_memcache_policy(lambda key: True)
            self.ctx.set_memcache_timeout_policy(lambda key: key.id())
            foo().check_success()
            self.assertEqual(len(track), 2)
            self.assertEqual(track[0][0], ({key1.urlsafe(): ent1._to_pb()}, ))
            self.assertEqual(track[0][1], {'key_prefix': 'NDB:', 'time': 1})
            self.assertEqual(track[1][0], ({key2.urlsafe(): ent2._to_pb()}, ))
            self.assertEqual(track[1][1], {'key_prefix': 'NDB:', 'time': 2})
            memcache.flush_all()

            track = []
            badkeys = [key2.urlsafe()]
            self.ctx.set_memcache_timeout_policy(lambda key: 0)
            foo().check_success()
            self.assertEqual(len(track), 1)
            self.assertEqual(track[0][2], badkeys)
            memcache.flush_all()
        finally:
            memcache.set_multi = save_set_multi