def test(self): storage = Storage({}) t = storage.makeRef(Person('Tom', 3)) d = storage.makeRef(Person('Dick', 3)) storage['c'] = c = Collection(storage) c.add(t) c.add(d) self.assertEqual(len(c.values()), 2) del c self.assertEqual(storage.cache.values(), []) t.setAge(4) c = storage['c'] # The info for Tom in c has been updated. self.assertEqual(c.count(QTerm(':age', 'eq', 4)), 1) ti = c.values(QTerm(':name', 'eq', 'Tom'))[0] self.assertEqual(ti['age'], 4) c.discard(t) self.assertEqual(c.count(), 1) self.assertEqual(len(t.subscribers('*')), 0) d = c.open(QTerm(':name', 'eq', 'Dick')) self.assertEqual(d.age, 3)
def testRefEquality(self): v = Storage({}) ra1 = v.getRef('a') ra2 = v.getRef('a') rb = v.getRef('b') self.assertEqual(ra1, ra2) self.assertNotEqual(ra1, rb)
def testVersioning(self): s = Storage({}) s['v'] = V('info') # simulate a change of version. s.map_class = lambda c: c.replace('.V', '.NewV') v = s['v'] self.assertEqual(type(v), NewV) self.assertEqual(v.info, 'info-updated')
def testSubscribe(self): storage = Storage({}) t = storage.makeRef(Person('Tom', 3)) storage['c'] = c = Collection(storage) c.add(t) storage['s'] = s = Subscriber([]) c.subscribe('change', s.on) t.setAge(4) self.assertEqual(len(s.events), 1)
def testArgs(self): # Non-persistent. events = [] def cb(*args): events.append(args) p = Publisher() p.subscribe('done', cb, args=('x', 42)) p.notify('done', True) self.assertEqual(events, [('done', True, 'x', 42)]) # Persistent. store = {} storage = Storage(store) storage['sub'] = s = Subscriber([]) sid = p.subscribe('dusted', s.on, args=('hello', ), how=PERSISTENT) storage['pub'] = p del s, p p = storage['pub'] p.notify('dusted', 14) # FIXME: a tuple is converted to a list here. That's a # serializer bug. self.assertEqual(storage['sub'].events, [['dusted', 14, 'hello']]) p.unsubscribe('dusted', sid, how=PERSISTENT) p.notify('dusted', 15) self.assertEqual(len(storage['sub'].events), 1)
def testNames(self): vat = Storage({}) foo = vat.makeRef(Obj({})) ns = NameStore(vat, {}) foo['x'] = 'bar' ns.setn('foo', foo) foo1 = ns.getn('foo') self.assertEqual(foo1['x'], 'bar') # Can do it all in one.. ns.setn('time', Time()) self.assertEqual(ns.getn('time').time(), 'Tea-time') ns.getn('time')._erase() ns.deln('time')
def testUnnesting(self): store = Storage({}) data = Data({}) person = Person(data) store['person_data'] = data store['person'] = person del store.cache['person'] self.assertEqual(type(store['person'].env), Ref)
def test(self): s = Storage({}) s['a'] = TestObject({'name': 'Fred'}, [TestObject('sub', [])]) o = s['a'] del o.ref # breaks equality so have to remove first. self.assertEqual(o, TestObject({'name': 'Fred'}, [TestObject('sub', [])]))
def testFacetRef(self): vat = Storage({}) main_ref = vat.makeRef(TestData(24)) public = vat.makeRef(main_ref._getFacet('public')) self.assertEqual(public.get(), 24) self.assertRaises(AttributeError, getattr, public, 'set') # main_ref references a TestData instance self.assertEqual(type(main_ref._get()), TestData) # public references a facet Ref self.assertEqual(type(public._get()), Ref) self.assertEqual(public._get()._facet, 'public') # the facet Ref references an obj instance self.assertEqual(type(public._get()._get()), obj) # check facet is not lost in serialization. public._close() self.assertEqual(public._get()._facet, 'public')
def testSerializationErrors(self): # NOTE: Proxy storage requires an RPCStorageCtx. proxy_enc = encodes(Record('ref', {'path': 'p', 'node': 'n'})) unk_enc = encodes(Record('unknown', 3)) msg_enc = encodes(Record('@', 'xyz', 35)) s = Storage({'foo': proxy_enc, 'unk': unk_enc, 'msg': msg_enc}) #self.assertRaises(SerializationError, s.__getitem__, 'foo') self.assertRaises(SerializationError, s.__getitem__, 'unk') self.assertEqual(s['msg'], Record('@', 'xyz', 35)) class NoSer(object): pass self.assertRaises(SerializationError, s.__setitem__, 'nos', NoSer()) ns = NameStore(s, {}) self.assertRaises(NoSuchName, ns.getn, 'bimbo')
def testStoreAgainMakesRef(self): store = Storage({}) data = Data({}) store['a'] = data self.assertEqual(type(store['a']), Data) store['aref'] = data self.assertEqual(type(store['aref']), Ref) a = store['a'] a['foo'] = 42 self.assertEqual(store['aref']['foo'], 42) a.save() del a, data self.assertEqual(store.cache.values(), []) self.assertEqual(type(store['a']), Data) self.assertEqual(type(store['aref']), Ref) self.assertEqual(store['a']['foo'], 42)
def testCatchAllSubscriptions(self): # Persistent. store = {} storage = Storage(store) storage['pub'] = p = Publisher() storage['sub'] = s = Subscriber([]) sid = p.subscribe('*', s.on, args=('hello', ), how=PERSISTENT) del s, p p = storage['pub'] p.notify('dusted', 14) # FIXME: a tuple is converted to a list here. That's a # serializer bug. self.assertEqual(storage['sub'].events, [['dusted', 14, 'hello']]) p.unsubscribe('*', sid, how=PERSISTENT) p.notify('dusted', 15) self.assertEqual(len(storage['sub'].events), 1)
from serf.eventlet_thread import EventletThread from serf.rpc_handler import RPCHandler from serf.transport import Transport from serf.ws_transport import WSTransport from serf.fs_dict import FSDict from serf.storage import Storage from serf.tables.table import * from serf.tables.query import * SERF_NODE = '127.0.0.1:6506' thread = EventletThread() store = FSDict('/var/lib/serf/tables') storage = Storage(store) if 'table' not in storage: storage['table'] = Table() TABLE = storage['table'] JC_OPTS = dict(hooks=JC_HOOKS, safe=['serf.tables'], auto_proxy=True) def handle(transport): thread = EventletThread() thread.callFromThread = thread.call handler = RPCHandler(transport, {}, t_model=thread, jc_opts=JC_OPTS) handler.provide('table', TABLE) transport.handle() if __name__ == '__main__':
def __init__(self): self._storage = Storage(TestFS()) self._storage.resources['#env'] = weakref.proxy(self)
def testData(self): store = Storage({}) store['people/data/tom'] = Data({}) t_data = store['people/data/tom'] t_data['name'] = 'Tom' t_data['age'] = 14 self.assertEqual(t_data['name'], 'Tom') env = Ref(store, 'people/data/tom') store['people/obj/tom'] = Person(env) tom = store['people/obj/tom'] self.assertEqual(tom.description(), 'Tom age 14') tom.haveBirthday() self.assertEqual(t_data['age'], 15) store['people/data/gary'] = Data({}) g_data = store['people/data/gary'] g_data['name'] = 'Gary' g_data['age'] = 48 t_data['dad'] = g_data self.assertEqual(type(t_data['dad']), Ref) self.assertEqual(tom.dadsName(), 'Gary') with Capture() as c: fcat(tom) self.assertEqual(c.getvalue(), "Person(env=ref(path='people/data/tom'))\n") # We can store refs anywhere in data. A top-level Data object # which has come from the store can turn itself into a ref. g_data['kids'] = [t_data] self.assertEqual(type(g_data['kids'][0]), Ref) self.assertEqual(g_data['kids'][0]['name'], 'Tom') # We do not support deep references into data (e.g. g_data['kids']) # because they would be very breakable, and copying would upset # the normal language expectation of node sharing. self.assertRaises(ValueError, t_data.__setitem__, 'siblings', g_data['kids']) store['caps/time'] = Time() t_data['time'] = store.getRef('caps/time') self.assertEqual(type(store['caps/time']), Time) self.assertEqual(type(t_data['time']), Ref) self.assertEqual(tom.whatTime(), 'Tea-time') t_data.save() g_data.save() del t_data, g_data, tom self.assertEqual(store.cache.values(), []) t_data = store['people/data/tom'] g_data = store['people/data/gary'] tom = store['people/obj/tom'] self.assertEqual(t_data['name'], 'Tom') self.assertEqual(t_data['age'], 15) self.assertEqual(type(t_data['time']), Ref) self.assertEqual(t_data['time'].time(), 'Tea-time') tom.haveBirthday() self.assertEqual(g_data['kids'][0]['age'], 16)
RUN_CONSOLE = (__name__ == '__main__') SERVER = '127.0.0.1:6502' CLIENT = '127.0.0.1:6503' SSL = { 'certfile': os.path.join(codeDir(), 'data/host.cert'), 'keyfile': os.path.join(codeDir(), 'data/host.key') } store = FSDict(os.path.join(dataRoot(), 'client')) net = Transport(CLIENT, ssl=SSL) thread = EventletThread() s0 = Storage(store) v0 = RPCHandler(net, s0, t_model=thread) def wrap(x): return REPLProxy(x, thread) class ClientConsole(InteractiveConsole): def raw_input(self, prompt): sys.stdout.write(prompt) sys.stdout.flush() select.select([sys.stdin],[],[]) s = sys.stdin.readline() if not s: raise EOFError() return s.strip()
def testData(self): store = Storage({}) store['people/data/tom'] = Data({}) t_data = store['people/data/tom'] t_data['name'] = 'Tom' t_data['age'] = 14 self.assertEqual(t_data['name'], 'Tom') env = Ref(store, 'people/data/tom') store['people/obj/tom'] = Person(env) tom = store['people/obj/tom'] self.assertEqual(tom.description(), 'Tom age 14') tom.haveBirthday() self.assertEqual(t_data['age'], 15) store['people/data/gary'] = Data({}) g_data = store['people/data/gary'] g_data['name'] = 'Gary' g_data['age'] = 48 t_data['dad'] = g_data self.assertEqual(type(t_data['dad']), Ref) self.assertEqual(tom.dadsName(), 'Gary') with Capture() as c: fcat(tom) self.assertEqual(c.getvalue(), "Person(env=ref(path='people/data/tom'))\n") # We can store refs anywhere in data. A top-level Data object # which has come from the store can turn itself into a ref. g_data['kids'] = [t_data] self.assertEqual(type(g_data['kids'][0]), Ref) self.assertEqual(g_data['kids'][0]['name'], 'Tom') # We do not support deep references into data (e.g. g_data['kids']) # because they would be very breakable, and copying would upset # the normal language expectation of node sharing. self.assertRaises( ValueError, t_data.__setitem__, 'siblings', g_data['kids']) store['caps/time'] = Time() t_data['time'] = store.getRef('caps/time') self.assertEqual(type(store['caps/time']), Time) self.assertEqual(type(t_data['time']), Ref) self.assertEqual(tom.whatTime(), 'Tea-time') t_data.save() g_data.save() del t_data, g_data, tom self.assertEqual(store.cache.values(), []) t_data = store['people/data/tom'] g_data = store['people/data/gary'] tom = store['people/obj/tom'] self.assertEqual(t_data['name'], 'Tom') self.assertEqual(t_data['age'], 15) self.assertEqual(type(t_data['time']), Ref) self.assertEqual(t_data['time'].time(), 'Tea-time') tom.haveBirthday() self.assertEqual(g_data['kids'][0]['age'], 16)
RUN_CONSOLE = (__name__ == '__main__') SERVER = '127.0.0.1:6502' CLIENT = '127.0.0.1:6503' SSL = { 'certfile': os.path.join(codeDir(), 'data/host.cert'), 'keyfile': os.path.join(codeDir(), 'data/host.key') } store = FSDict(os.path.join(dataRoot(), 'client')) net = Transport(CLIENT, ssl=SSL) thread = EventletThread() s0 = Storage(store) v0 = RPCHandler(net, s0, t_model=thread) def wrap(x): return REPLProxy(x, thread) class ClientConsole(InteractiveConsole): def raw_input(self, prompt): sys.stdout.write(prompt) sys.stdout.flush() select.select([sys.stdin], [], []) s = sys.stdin.readline() if not s: raise EOFError()
def testPersistence(self): self._insertTestData() self.assertEqual(self.table.count(KeyRange(':age int')), 3) store = {} obj_store = Storage(store) obj_store['table'] = self.table self.sval = store['table'] def svalChanged(): self.assertNotEqual(self.sval, store['table']) self.sval = store['table'] self.table.insert([dict(name='Albert', age=37)]) svalChanged() self.table.set(4, dict(name='Fred', age=35, id='F1')) svalChanged() self.table.setKey(':id str', dict(name='Fred', age=36, id='F1')) svalChanged() kv = KeyValue(8, dict(name='Fred', age=64, id='F2')) self.table.setBatch([kv]) svalChanged() self.table.update(PKey(16), [FieldValue(':id', 'A1')]) svalChanged() items = [KeyValue(4, dict(birthday='Louise', years=36))] join = JoinSpec('birthday', 'name', 'str') values = [CopyField(':age', ':years')] self.table.updateIter(items, join, None, values) svalChanged() self.table.pop(PKey(8)) svalChanged() def toTup(kv): return kv.key, kv.value, kv.skey # Dump keys, values and skeys in form suitable for equality testing. p_dump = map(toTup, self.table.select()) s_dump = map(toTup, self.table.select(KeyRange(':age int'))) # NOTE: Table could have a reference cycle: for some reason # self.table = None is insufficient to cause it to be ejected # from the obj_store.cache which is a WeakValueDictionary. self.table = None obj_store.cache.clear() table = obj_store['table'] self.assertEqual(p_dump, map(toTup, table.select())) self.assertEqual(s_dump, map(toTup, table.select(KeyRange(':age int')))) table.remove() # different code-path from pop when removing all. svalChanged()
def test(self): storage = Storage({}) storage['s'] = s = Subscriber([]) storage['c'] = c = People(storage, {'name': 'Kids', 'area': 3056}) storage['t'] = t = Person({'name': 'Tom', 'age': 3}) # Subscriptions to a CollectionModel go to both # the underlying Table and Model. sid = c.subscribe('*', s.on, how=PERSISTENT) c.add(t) del s, c, t s = storage['s'] c = storage['c'] t = storage['t'] self.assertEqual(c.value()['name'], 'Kids') c.update({'name': 'Children'}) c.update({'area': 3057}) t.update({'age': 4}) # Check that the Collection has tracked the age change. self.assertEqual(len(c.values()), 1) self.assertEqual(c.values()[0]['age'], 4) # NOTE: for each update to the table we get 4 events, # 'change', 'change_r', 'key:x' and 'key_r:x'. Normally we # would use a more selective subscription but for the test # it is convenient to capture them all. # Here we expect 2*4 = 8 Table events, plus 3 from the # Model aspect of the CollectionModel. self.assertEqual(len(s.events), 11) changes = [i for e, i in s.events if e == 'change'] self.assertEqual(len(changes), 2) self.assertEqual(changes[0].old, None) self.assertEqual(changes[0].value['age'], 3) self.assertEqual(changes[1].old['age'], 3) self.assertEqual(changes[1].value['age'], 4) updates = [i for e, i in s.events if e == 'update'] self.assertEqual(len(updates), 2) self.assertTrue({'name': 'Children'} in updates) self.assertTrue({'area': 3057} in updates) info = [i for e, i in s.events if e == 'info'] self.assertEqual(info, [{'name': 'Children'}]) # Check that both Table and Model subscriptions # are properly removed via the one subscription id. c.unsubscribe('*', sid, how=PERSISTENT) c.update({'name': 'Playgroup'}) t.update({'age': 5}) self.assertEqual(len(s.events), 11) # no new events self.assertEqual(c.values()[0]['age'], 5) c.discard(t) self.assertEqual(len(c.values()), 0)