def test___delitem___w_remaining_object(self): from persistent.interfaces import UPTODATE from persistent._compat import _b cache = self._makeOne() remains = self._makePersist(state=UPTODATE) uptodate = self._makePersist(state=UPTODATE) REMAINS = _b('remains') UPTODATE = _b('uptodate') cache[REMAINS] = remains cache[UPTODATE] = uptodate del cache[UPTODATE] self.assertTrue(cache.get(UPTODATE, self) is self) self.assertTrue(cache.get(REMAINS, self) is remains)
def test___setitem___duplicate_oid_same_obj(self): from persistent._compat import _b KEY = _b('original') cache = self._makeOne() original = self._makePersist() cache[KEY] = original cache[KEY] = original
def test_new_ghost_obj_already_in_cache(self): from persistent._compat import _b KEY = _b('123') cache = self._makeOne() candidate = self._makePersist(oid=None, jar=None) cache[KEY] = candidate self.assertRaises(KeyError, cache.new_ghost, KEY, candidate)
def test_lruitems(self): from persistent.interfaces import UPTODATE from persistent._compat import _b cache = self._makeOne() ONE = _b('one') TWO = _b('two') THREE = _b('three') cache[ONE] = self._makePersist(oid='one', state=UPTODATE) cache[TWO] = self._makePersist(oid='two', state=UPTODATE) cache[THREE] = self._makePersist(oid='three', state=UPTODATE) items = cache.lru_items() self.assertEqual(_len(items), 3) self.assertEqual(items[0][0], ONE) self.assertEqual(items[1][0], TWO) self.assertEqual(items[2][0], THREE)
def test_invalidate_hit_multiple_mixed(self): from persistent.interfaces import GHOST from persistent.interfaces import UPTODATE from persistent._compat import _b KEY = _b('123') KEY2 = _b('456') cache = self._makeOne() c1 = self._makePersist(oid=KEY, jar=cache.jar, state=GHOST) cache[KEY] = c1 c2 = self._makePersist(oid=KEY2, jar=cache.jar, state=UPTODATE) cache[KEY2] = c2 self.assertEqual(cache.ringlen(), 1) cache.invalidate([KEY, KEY2]) self.assertEqual(cache.ringlen(), 0) self.assertEqual(c1._p_state, GHOST) self.assertEqual(c2._p_state, GHOST)
def test___setitem___duplicate_oid_same_obj(self): from persistent._compat import _b KEY = _b('original') cache = self._makeOne() original = self._makePersist(oid=KEY) cache[KEY] = original cache[KEY] = original
def test_set__p_changed_w_broken_jar(self): # When an object is modified, it registers with its data manager. # If that registration fails, the exception is propagated and the # object stays in the up-to-date state. # It shouldn't change to the modified state, because it won't # be saved when the transaction commits. from persistent._compat import _b class P(self._getTargetClass()): def __init__(self): self.x = 0 def inc(self): self.x += 1 p = P() p._p_oid = _b('1') p._p_jar = self._makeBrokenJar() self.assertEqual(p._p_state, 0) self.assertEqual(p._p_jar.called, 0) def _try(): p._p_changed = 1 self.assertRaises(NotImplementedError, _try) self.assertEqual(p._p_jar.called, 1) self.assertEqual(p._p_state, 0)
def test_new_ghost_obj_already_has_jar(self): from persistent._compat import _b class Dummy(object): _p_oid = None _p_jar = object() cache = self._makeOne() candidate = self._makePersist(oid=None, jar=object()) self.assertRaises(ValueError, cache.new_ghost, _b('123'), candidate)
def test_ctor_target_wo_jar(self): from persistent._compat import _b target = _makeTarget() wref = self._makeOne(target) self.assertTrue(wref._v_ob is target) self.assertEqual(wref.oid, _b('OID')) self.assertTrue(wref.dm is None) self.assertFalse('database_name' in wref.__dict__)
def test_invalidate_hit_multiple_non_ghost(self): from persistent.interfaces import UPTODATE from persistent.interfaces import GHOST from persistent._compat import _b KEY = _b('123') KEY2 = _b('456') cache = self._makeOne() c1 = self._makePersist(oid=KEY, jar=cache.jar, state=UPTODATE) cache[KEY] = c1 c2 = self._makePersist(oid=KEY2, jar=cache.jar, state=UPTODATE) cache[KEY2] = c2 self.assertEqual(cache.ringlen(), 2) # These should be in the opposite order of how they were # added to the ring to ensure ring traversal works cache.invalidate([KEY2, KEY]) self.assertEqual(cache.ringlen(), 0) self.assertEqual(c1._p_state, GHOST) self.assertEqual(c2._p_state, GHOST)
def test_ctor_target_w_jar(self): from persistent._compat import _b target = _makeTarget() target._p_jar = jar = _makeJar() wref = self._makeOne(target) self.assertTrue(wref._v_ob is target) self.assertEqual(wref.oid, _b('OID')) self.assertTrue(wref.dm is jar) self.assertEqual(wref.database_name, 'testing')
def test_mru_ghost(self): from persistent.interfaces import UPTODATE from persistent.interfaces import GHOST from persistent._compat import _b ONE = _b('one') TWO = _b('two') THREE = _b('three') cache = self._makeOne() cache[ONE] = self._makePersist(oid='one', state=UPTODATE) two = cache[TWO] = self._makePersist(oid='two', state=GHOST) cache[THREE] = self._makePersist(oid='three', state=UPTODATE) cache.mru(TWO) self.assertEqual(cache.ringlen(), 2) items = cache.lru_items() self.assertEqual(_len(items), 2) self.assertEqual(items[0][0], ONE) self.assertEqual(items[1][0], THREE)
def test_invalidate_hit_pclass(self): from persistent._compat import _b KEY = _b('123') class Pclass(object): _p_oid = KEY _p_jar = None cache = self._makeOne() cache[KEY] = Pclass self.assertTrue(cache.persistent_classes[KEY] is Pclass) cache.invalidate(KEY) self.assertFalse(KEY in cache.persistent_classes)
def test_new_ghost_success_already_ghost(self): from persistent.interfaces import GHOST from persistent._compat import _b KEY = _b('123') cache = self._makeOne() candidate = self._makePersist(oid=None, jar=None) cache.new_ghost(KEY, candidate) self.assertTrue(cache.get(KEY) is candidate) self.assertEqual(candidate._p_oid, KEY) self.assertEqual(candidate._p_jar, cache.jar) self.assertEqual(candidate._p_state, GHOST)
def test_invalidate_hit_pclass(self): from persistent._compat import _b KEY = _b('123') class Pclass(object): _p_oid = None _p_jar = None cache = self._makeOne() cache[KEY] = Pclass self.assertTrue(cache.persistent_classes[KEY] is Pclass) cache.invalidate(KEY) self.assertFalse(KEY in cache.persistent_classes)
def test_invalidate_hit_single_ghost(self): from persistent.interfaces import GHOST from persistent._compat import _b KEY = _b('123') cache = self._makeOne() candidate = self._makePersist(oid='123', jar=cache.jar, state=GHOST) cache[KEY] = candidate self.assertEqual(cache.ringlen(), 0) cache.invalidate(KEY) self.assertEqual(cache.ringlen(), 0) self.assertEqual(candidate._p_state, GHOST)
def test___delitem___w_normal_object(self): from persistent.interfaces import UPTODATE from persistent._compat import _b KEY = _b('uptodate') cache = self._makeOne() uptodate = self._makePersist(state=UPTODATE) cache[KEY] = uptodate del cache[KEY] self.assertTrue(cache.get(KEY, self) is self)
def test___delitem___nonesuch_raises_KeyError(self): from persistent._compat import _b cache = self._makeOne() original = self._makePersist() try: del cache[_b('nonesuch')] except KeyError: pass else: self.fail("Didn't raise KeyError with nonesuch OID.")
def test_reify_hit_single_non_ghost(self): from persistent.interfaces import UPTODATE from persistent._compat import _b KEY = _b('123') cache = self._makeOne() candidate = self._makePersist(oid=KEY, jar=cache.jar, state=UPTODATE) cache[KEY] = candidate self.assertEqual(cache.ringlen(), 1) cache.reify(KEY) self.assertEqual(cache.ringlen(), 1) self.assertEqual(candidate._p_state, UPTODATE)
def test___delitem___w_ghost(self): from persistent.interfaces import GHOST from persistent._compat import _b cache = self._makeOne() ghost = self._makePersist(state=GHOST) KEY = _b('ghost') cache[KEY] = ghost del cache[KEY] self.assertTrue(cache.get(KEY, self) is self)
def _makePersist(self, state=None, oid='foo', jar=_marker): from persistent.interfaces import GHOST from persistent._compat import _b if state is None: state = GHOST if jar is _marker: jar = DummyConnection() persist = DummyPersistent() persist._p_state = state persist._p_oid = _b(oid) persist._p_jar = jar return persist
def test_new_ghost_w_pclass_ghost(self): from persistent._compat import _b KEY = _b('123') class Pclass(object): _p_oid = None _p_jar = None cache = self._makeOne() cache.new_ghost(KEY, Pclass) self.assertTrue(cache.get(KEY) is Pclass) self.assertTrue(cache.persistent_classes[KEY] is Pclass) self.assertEqual(Pclass._p_oid, KEY) self.assertEqual(Pclass._p_jar, cache.jar)
def test___setstate___empty(self): from persistent.wref import WeakRef from persistent._compat import _b jar = _makeJar() KEY = _b('KEY') KEY2 = _b('KEY2') KEY3 = _b('KEY3') VALUE = _b('VALUE') VALUE2 = _b('VALUE2') VALUE3 = _b('VALUE3') key = jar[KEY] = _makeTarget(oid=KEY) key._p_jar = jar kref = WeakRef(key) value = jar[VALUE] = _makeTarget(oid=VALUE) value._p_jar = jar key2 = _makeTarget(oid=KEY2) key2._p_jar = jar # not findable kref2 = WeakRef(key2) del kref2._v_ob # force a miss value2 = jar[VALUE2] = _makeTarget(oid=VALUE2) value2._p_jar = jar key3 = jar[KEY3] = _makeTarget(oid=KEY3) # findable key3._p_jar = jar kref3 = WeakRef(key3) del kref3._v_ob # force a miss, but win in the lookup value3 = jar[VALUE3] = _makeTarget(oid=VALUE3) value3._p_jar = jar pwkd = self._makeOne(None) pwkd.__setstate__( {'data': [(kref, value), (kref2, value2), (kref3, value3)]}) self.assertTrue(pwkd[key] is value) self.assertTrue(pwkd.get(key2) is None) self.assertTrue(pwkd[key3] is value3)
def test___setstate___empty(self): from persistent.wref import WeakRef from persistent._compat import _b jar = _makeJar() KEY = _b('KEY') KEY2 = _b('KEY2') KEY3 = _b('KEY3') VALUE = _b('VALUE') VALUE2 = _b('VALUE2') VALUE3 = _b('VALUE3') key = jar[KEY] = _makeTarget(oid=KEY) key._p_jar = jar kref = WeakRef(key) value = jar[VALUE] = _makeTarget(oid=VALUE) value._p_jar = jar key2 = _makeTarget(oid=KEY2) key2._p_jar = jar # not findable kref2 = WeakRef(key2) del kref2._v_ob # force a miss value2 = jar[VALUE2] = _makeTarget(oid=VALUE2) value2._p_jar = jar key3 = jar[KEY3] = _makeTarget(oid=KEY3) # findable key3._p_jar = jar kref3 = WeakRef(key3) del kref3._v_ob # force a miss, but win in the lookup value3 = jar[VALUE3] = _makeTarget(oid=VALUE3) value3._p_jar = jar pwkd = self._makeOne(None) pwkd.__setstate__({'data': [(kref, value), (kref2, value2), (kref3, value3)]}) self.assertTrue(pwkd[key] is value) self.assertTrue(pwkd.get(key2) is None) self.assertTrue(pwkd[key3] is value3)
def test___setitem___mismatch_key_oid(self): from persistent.interfaces import UPTODATE from persistent._compat import _b KEY = _b('uptodate') cache = self._makeOne() uptodate = self._makePersist(state=UPTODATE) try: cache[KEY] = uptodate except ValueError: pass else: self.fail("Didn't raise ValueError when the key didn't match the OID")
def test___delitem___w_persistent_class(self): from persistent._compat import _b KEY = _b('pclass') cache = self._makeOne() class pclass(object): _p_oid = KEY cache = self._makeOne() cache[KEY] = pclass del cache[KEY] self.assertTrue(cache.get(KEY, self) is self) self.assertFalse(KEY in cache.persistent_classes) self.assertEqual(cache.ringlen(), 0)
def test___delitem___w_persistent_class(self): from persistent._compat import _b KEY = _b('pclass') cache = self._makeOne() class pclass(object): pass cache = self._makeOne() cache[KEY] = pclass del cache[KEY] self.assertTrue(cache.get(KEY, self) is self) self.assertFalse(KEY in cache.persistent_classes) self.assertEqual(cache.ringlen(), 0)
def test___setitem___duplicate_oid_raises_KeyError(self): from persistent._compat import _b KEY = _b('original') cache = self._makeOne() original = self._makePersist() cache[KEY] = original duplicate = self._makePersist() try: cache[KEY] = duplicate except KeyError: pass else: self.fail("Didn't raise KeyError with duplicate OID.")
def test_reify_hit_single_ghost(self): from persistent.interfaces import GHOST from persistent._compat import _b KEY = _b('123') from persistent.interfaces import UPTODATE cache = self._makeOne() candidate = self._makePersist(oid=KEY, jar=cache.jar, state=GHOST) cache[KEY] = candidate self.assertEqual(cache.ringlen(), 0) cache.reify(KEY) self.assertEqual(cache.ringlen(), 1) items = cache.lru_items() self.assertEqual(items[0][0], KEY) self.assertTrue(items[0][1] is candidate) self.assertEqual(candidate._p_state, UPTODATE)
def _makeTarget(oid='OID', **kw): from persistent import Persistent from persistent._compat import _b class Derived(Persistent): def __hash__(self): return hash(self._p_oid) def __eq__(self, other): return self._p_oid == other._p_oid def __repr__(self): return 'Derived: %s' % self._p_oid derived = Derived() for k, v in kw.items(): setattr(derived, k, v) derived._p_oid = _b(oid) return derived
def test_incrgc_w_smaller_drain_resistance(self): from persistent.interfaces import UPTODATE from persistent._compat import _b cache = self._makeOne() cache.drain_resistance = 2 oids = [] for i in range(100): oid = _b('oid_%04d' % i) oids.append(oid) cache[oid] = self._makePersist(oid=oid, state=UPTODATE) self.assertEqual(cache.cache_non_ghost_count, 100) cache.incrgc() self.assertEqual(cache.cache_non_ghost_count, 10)
def test__p_activate_w_broken_jar(self): # Make sure that exceptions that occur inside the data manager's # ``setstate()`` method propagate out to the caller. from persistent._compat import _b class P(self._getTargetClass()): def __init__(self): self.x = 0 def inc(self): self.x += 1 p = P() p._p_oid = _b('1') p._p_jar = self._makeBrokenJar() p._p_deactivate() self.assertEqual(p._p_state, -1) self.assertRaises(NotImplementedError, p._p_activate) self.assertEqual(p._p_state, -1)
def test_minimize_turns_into_ghosts(self): import gc from persistent.interfaces import UPTODATE from persistent.interfaces import GHOST from persistent._compat import _b cache = self._makeOne() oid = _b('oid_%04d' % 1) obj = cache[oid] = self._makePersist(oid=oid, state=UPTODATE) self.assertEqual(cache.cache_non_ghost_count, 1) cache.minimize() gc.collect() # banish the ghosts who are no longer in the ring self.assertEqual(cache.cache_non_ghost_count, 0) self.assertEqual(obj._p_state, GHOST)
def test_new_ghost_obj_already_in_cache(self): from persistent._compat import _b KEY = _b('123') cache = self._makeOne() candidate = self._makePersist(oid=KEY) cache[KEY] = candidate # Now, normally we can't get in the cache without an oid and jar # (the C implementation doesn't allow it), so if we try to create # a ghost, we get the value error self.assertRaises(ValueError, cache.new_ghost, KEY, candidate) candidate._p_oid = None self.assertRaises(ValueError, cache.new_ghost, KEY, candidate) # if we're sneaky and remove the OID and jar, then we get the duplicate # key error candidate._p_jar = None self.assertRaises(KeyError, cache.new_ghost, KEY, candidate)
def test_debug_info_w_ghost(self): import gc from persistent.interfaces import GHOST from persistent._compat import _b KEY = _b('ghost') cache = self._makeOne() ghost = self._makePersist(state=GHOST) cache[KEY] = ghost info = cache.debug_info() self.assertEqual(len(info), 1) oid, refc, typ, state = info[0] self.assertEqual(oid, KEY) self.assertEqual(refc, len(gc.get_referents(ghost))) self.assertEqual(typ, 'DummyPersistent') self.assertEqual(state, GHOST)
def test___setitem___ghost(self): from persistent.interfaces import GHOST from persistent._compat import _b KEY = _b('ghost') cache = self._makeOne() ghost = self._makePersist(state=GHOST) cache[KEY] = ghost self.assertEqual(len(cache), 1) items = list(cache.items()) self.assertEqual(len(items), 1) self.assertEqual(_len(cache.klass_items()), 0) self.assertEqual(items[0][0], KEY) self.assertEqual(cache.ringlen(), 0) self.assertTrue(items[0][1] is ghost) self.assertTrue(cache[KEY] is ghost)