comparison idavoll/test/test_storage.py @ 206:274a45d2a5ab

Implement root collection that includes all leaf nodes.
author Ralph Meijer <ralphm@ik.nu>
date Mon, 04 Aug 2008 13:47:10 +0000
parents b4bf0a5ce50d
children bb7103da9879
comparison
equal deleted inserted replaced
205:e6b710bf2b24 206:274a45d2a5ab
3 3
4 """ 4 """
5 Tests for L{idavoll.memory_storage} and L{idavoll.pgsql_storage}. 5 Tests for L{idavoll.memory_storage} and L{idavoll.pgsql_storage}.
6 """ 6 """
7 7
8 from zope.interface.verify import verifyObject
8 from twisted.trial import unittest 9 from twisted.trial import unittest
9 from twisted.words.protocols.jabber import jid 10 from twisted.words.protocols.jabber import jid
10 from twisted.internet import defer 11 from twisted.internet import defer
11 from twisted.words.xish import domish 12 from twisted.words.xish import domish
12 13
13 from wokkel import pubsub 14 from wokkel import pubsub
14 15
15 from idavoll import error 16 from idavoll import error, iidavoll
16 17
17 OWNER = jid.JID('owner@example.com') 18 OWNER = jid.JID('owner@example.com')
18 SUBSCRIBER = jid.JID('subscriber@example.com/Home') 19 SUBSCRIBER = jid.JID('subscriber@example.com/Home')
19 SUBSCRIBER_NEW = jid.JID('new@example.com/Home') 20 SUBSCRIBER_NEW = jid.JID('new@example.com/Home')
20 SUBSCRIBER_TO_BE_DELETED = jid.JID('to_be_deleted@example.com/Home') 21 SUBSCRIBER_TO_BE_DELETED = jid.JID('to_be_deleted@example.com/Home')
21 SUBSCRIBER_PENDING = jid.JID('pending@example.com/Home') 22 SUBSCRIBER_PENDING = jid.JID('pending@example.com/Home')
22 PUBLISHER = jid.JID('publisher@example.com') 23 PUBLISHER = jid.JID('publisher@example.com')
23 ITEM = domish.Element((pubsub.NS_PUBSUB, 'item'), pubsub.NS_PUBSUB) 24 ITEM = domish.Element((None, 'item'))
24 ITEM['id'] = 'current' 25 ITEM['id'] = 'current'
25 ITEM.addElement(('testns', 'test'), content=u'Test \u2083 item') 26 ITEM.addElement(('testns', 'test'), content=u'Test \u2083 item')
26 ITEM_NEW = domish.Element((pubsub.NS_PUBSUB, 'item'), pubsub.NS_PUBSUB) 27 ITEM_NEW = domish.Element((None, 'item'))
27 ITEM_NEW['id'] = 'new' 28 ITEM_NEW['id'] = 'new'
28 ITEM_NEW.addElement(('testns', 'test'), content=u'Test \u2083 item') 29 ITEM_NEW.addElement(('testns', 'test'), content=u'Test \u2083 item')
29 ITEM_UPDATED = domish.Element((pubsub.NS_PUBSUB, 'item'), pubsub.NS_PUBSUB) 30 ITEM_UPDATED = domish.Element((None, 'item'))
30 ITEM_UPDATED['id'] = 'current' 31 ITEM_UPDATED['id'] = 'current'
31 ITEM_UPDATED.addElement(('testns', 'test'), content=u'Test \u2084 item') 32 ITEM_UPDATED.addElement(('testns', 'test'), content=u'Test \u2084 item')
32 ITEM_TO_BE_DELETED = domish.Element((pubsub.NS_PUBSUB, 'item'), 33 ITEM_TO_BE_DELETED = domish.Element((None, 'item'))
33 pubsub.NS_PUBSUB)
34 ITEM_TO_BE_DELETED['id'] = 'to-be-deleted' 34 ITEM_TO_BE_DELETED['id'] = 'to-be-deleted'
35 ITEM_TO_BE_DELETED.addElement(('testns', 'test'), content=u'Test \u2083 item') 35 ITEM_TO_BE_DELETED.addElement(('testns', 'test'), content=u'Test \u2083 item')
36 36
37 def decode(object): 37 def decode(object):
38 if isinstance(object, str): 38 if isinstance(object, str):
51 d = self.s.getNode('pre-existing') 51 d = self.s.getNode('pre-existing')
52 d.addCallback(self._assignTestNode) 52 d.addCallback(self._assignTestNode)
53 return d 53 return d
54 54
55 55
56 def test_interfaceIStorage(self):
57 self.assertTrue(verifyObject(iidavoll.IStorage, self.s))
58
59
60 def test_interfaceINode(self):
61 self.assertTrue(verifyObject(iidavoll.INode, self.node))
62
63
64 def test_interfaceILeafNode(self):
65 self.assertTrue(verifyObject(iidavoll.ILeafNode, self.node))
66
67
56 def test_getNode(self): 68 def test_getNode(self):
57 return self.s.getNode('pre-existing') 69 return self.s.getNode('pre-existing')
58 70
59 71
60 def test_getNonExistingNode(self): 72 def test_getNonExistingNode(self):
70 82
71 return self.s.getNodeIds().addCallback(cb) 83 return self.s.getNodeIds().addCallback(cb)
72 84
73 85
74 def test_createExistingNode(self): 86 def test_createExistingNode(self):
75 d = self.s.createNode('pre-existing', OWNER) 87 config = self.s.getDefaultConfiguration('leaf')
88 config['pubsub#node_type'] = 'leaf'
89 d = self.s.createNode('pre-existing', OWNER, config)
76 self.assertFailure(d, error.NodeExists) 90 self.assertFailure(d, error.NodeExists)
77 return d 91 return d
78 92
79 93
80 def test_createNode(self): 94 def test_createNode(self):
81 def cb(void): 95 def cb(void):
82 d = self.s.getNode('new 1') 96 d = self.s.getNode('new 1')
83 return d 97 return d
84 98
85 d = self.s.createNode('new 1', OWNER) 99 config = self.s.getDefaultConfiguration('leaf')
100 config['pubsub#node_type'] = 'leaf'
101 d = self.s.createNode('new 1', OWNER, config)
86 d.addCallback(cb) 102 d.addCallback(cb)
87 return d 103 return d
88 104
89 105
90 def test_deleteNonExistingNode(self): 106 def test_deleteNonExistingNode(self):
113 return d 129 return d
114 130
115 131
116 def test_getSubscriptions(self): 132 def test_getSubscriptions(self):
117 def cb(subscriptions): 133 def cb(subscriptions):
118 self.assertIn(('pre-existing', SUBSCRIBER, 'subscribed'), subscriptions) 134 found = False
135 for subscription in subscriptions:
136 if (subscription.nodeIdentifier == 'pre-existing' and
137 subscription.subscriber == SUBSCRIBER and
138 subscription.state == 'subscribed'):
139 found = True
140 self.assertTrue(found)
119 141
120 d = self.s.getSubscriptions(SUBSCRIBER) 142 d = self.s.getSubscriptions(SUBSCRIBER)
121 d.addCallback(cb) 143 d.addCallback(cb)
122 return d 144 return d
123 145
190 212
191 def test_addSubscription(self): 213 def test_addSubscription(self):
192 def cb1(void): 214 def cb1(void):
193 return self.node.getSubscription(SUBSCRIBER_NEW) 215 return self.node.getSubscription(SUBSCRIBER_NEW)
194 216
195 def cb2(state): 217 def cb2(subscription):
196 self.assertEqual(state, 'pending') 218 self.assertEqual(subscription.state, 'pending')
197 219
198 d = self.node.addSubscription(SUBSCRIBER_NEW, 'pending') 220 d = self.node.addSubscription(SUBSCRIBER_NEW, 'pending', {})
199 d.addCallback(cb1) 221 d.addCallback(cb1)
200 d.addCallback(cb2) 222 d.addCallback(cb2)
201 return d 223 return d
202 224
203 225
204 def test_addExistingSubscription(self): 226 def test_addExistingSubscription(self):
205 d = self.node.addSubscription(SUBSCRIBER, 'pending') 227 d = self.node.addSubscription(SUBSCRIBER, 'pending', {})
206 self.assertFailure(d, error.SubscriptionExists) 228 self.assertFailure(d, error.SubscriptionExists)
207 return d 229 return d
208 230
209 231
210 def test_getSubscription(self): 232 def test_getSubscription(self):
211 def cb(subscriptions): 233 def cb(subscriptions):
212 self.assertEquals(subscriptions[0][1], 'subscribed') 234 self.assertEquals(subscriptions[0].state, 'subscribed')
213 self.assertEquals(subscriptions[1][1], 'pending') 235 self.assertEquals(subscriptions[1].state, 'pending')
214 self.assertEquals(subscriptions[2][1], None) 236 self.assertEquals(subscriptions[2], None)
215 237
216 d = defer.DeferredList([self.node.getSubscription(SUBSCRIBER), 238 d = defer.gatherResults([self.node.getSubscription(SUBSCRIBER),
217 self.node.getSubscription(SUBSCRIBER_PENDING), 239 self.node.getSubscription(SUBSCRIBER_PENDING),
218 self.node.getSubscription(OWNER)]) 240 self.node.getSubscription(OWNER)])
219 d.addCallback(cb) 241 d.addCallback(cb)
220 return d 242 return d
221 243
222 244
223 def test_removeSubscription(self): 245 def test_removeSubscription(self):
228 d = self.node.removeSubscription(OWNER) 250 d = self.node.removeSubscription(OWNER)
229 self.assertFailure(d, error.NotSubscribed) 251 self.assertFailure(d, error.NotSubscribed)
230 return d 252 return d
231 253
232 254
233 def test_getSubscribers(self): 255 def test_getNodeSubscriptions(self):
256 def extractSubscribers(subscriptions):
257 return [subscription.subscriber for subscription in subscriptions]
258
234 def cb(subscribers): 259 def cb(subscribers):
235 self.assertIn(SUBSCRIBER, subscribers) 260 self.assertIn(SUBSCRIBER, subscribers)
236 self.assertNotIn(SUBSCRIBER_PENDING, subscribers) 261 self.assertNotIn(SUBSCRIBER_PENDING, subscribers)
237 self.assertNotIn(OWNER, subscribers) 262 self.assertNotIn(OWNER, subscribers)
238 263
239 d = self.node.getSubscribers() 264 d = self.node.getSubscriptions('subscribed')
265 d.addCallback(extractSubscribers)
240 d.addCallback(cb) 266 d.addCallback(cb)
241 return d 267 return d
242 268
243 269
244 def test_isSubscriber(self): 270 def test_isSubscriber(self):
379 405
380 class MemoryStorageStorageTestCase(unittest.TestCase, StorageTests): 406 class MemoryStorageStorageTestCase(unittest.TestCase, StorageTests):
381 407
382 def setUp(self): 408 def setUp(self):
383 from idavoll.memory_storage import Storage, PublishedItem, LeafNode 409 from idavoll.memory_storage import Storage, PublishedItem, LeafNode
384 from idavoll.memory_storage import Subscription, defaultConfig 410 from idavoll.memory_storage import Subscription
411
412 defaultConfig = Storage.defaultConfig['leaf']
385 413
386 self.s = Storage() 414 self.s = Storage()
387 self.s._nodes['pre-existing'] = \ 415 self.s._nodes['pre-existing'] = \
388 LeafNode('pre-existing', OWNER, defaultConfig) 416 LeafNode('pre-existing', OWNER, defaultConfig)
389 self.s._nodes['to-be-deleted'] = \ 417 self.s._nodes['to-be-deleted'] = \
392 LeafNode('to-be-reconfigured', OWNER, defaultConfig) 420 LeafNode('to-be-reconfigured', OWNER, defaultConfig)
393 self.s._nodes['to-be-purged'] = \ 421 self.s._nodes['to-be-purged'] = \
394 LeafNode('to-be-purged', OWNER, None) 422 LeafNode('to-be-purged', OWNER, None)
395 423
396 subscriptions = self.s._nodes['pre-existing']._subscriptions 424 subscriptions = self.s._nodes['pre-existing']._subscriptions
397 subscriptions[SUBSCRIBER.full()] = Subscription('subscribed') 425 subscriptions[SUBSCRIBER.full()] = Subscription('pre-existing',
426 SUBSCRIBER,
427 'subscribed')
398 subscriptions[SUBSCRIBER_TO_BE_DELETED.full()] = \ 428 subscriptions[SUBSCRIBER_TO_BE_DELETED.full()] = \
399 Subscription('subscribed') 429 Subscription('pre-existing', SUBSCRIBER_TO_BE_DELETED,
430 'subscribed')
400 subscriptions[SUBSCRIBER_PENDING.full()] = \ 431 subscriptions[SUBSCRIBER_PENDING.full()] = \
401 Subscription('pending') 432 Subscription('pre-existing', SUBSCRIBER_PENDING,
433 'pending')
402 434
403 item = PublishedItem(ITEM_TO_BE_DELETED, PUBLISHER) 435 item = PublishedItem(ITEM_TO_BE_DELETED, PUBLISHER)
404 self.s._nodes['pre-existing']._items['to-be-deleted'] = item 436 self.s._nodes['pre-existing']._items['to-be-deleted'] = item
405 self.s._nodes['pre-existing']._itemlist.append(item) 437 self.s._nodes['pre-existing']._itemlist.append(item)
406 self.s._nodes['to-be-purged']._items['to-be-deleted'] = item 438 self.s._nodes['to-be-purged']._items['to-be-deleted'] = item
434 return self.dbpool.runInteraction(self.cleandb) 466 return self.dbpool.runInteraction(self.cleandb)
435 467
436 468
437 def init(self, cursor): 469 def init(self, cursor):
438 self.cleandb(cursor) 470 self.cleandb(cursor)
439 cursor.execute("""INSERT INTO nodes (node) VALUES ('pre-existing')""") 471 cursor.execute("""INSERT INTO nodes
472 (node, node_type, persist_items)
473 VALUES ('pre-existing', 'leaf', TRUE)""")
440 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-deleted')""") 474 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-deleted')""")
441 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-reconfigured')""") 475 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-reconfigured')""")
442 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-purged')""") 476 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-purged')""")
443 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", 477 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
444 OWNER.userhost()) 478 OWNER.userhost())
445 cursor.execute("""INSERT INTO affiliations 479 cursor.execute("""INSERT INTO affiliations
446 (node_id, entity_id, affiliation) 480 (node_id, entity_id, affiliation)
447 SELECT nodes.id, entities.id, 'owner' 481 SELECT node_id, entity_id, 'owner'
448 FROM nodes, entities 482 FROM nodes, entities
449 WHERE node='pre-existing' AND jid=%s""", 483 WHERE node='pre-existing' AND jid=%s""",
450 OWNER.userhost()) 484 OWNER.userhost())
451 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", 485 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
452 SUBSCRIBER.userhost()) 486 SUBSCRIBER.userhost())
453 cursor.execute("""INSERT INTO subscriptions 487 cursor.execute("""INSERT INTO subscriptions
454 (node_id, entity_id, resource, subscription) 488 (node_id, entity_id, resource, state)
455 SELECT nodes.id, entities.id, %s, 'subscribed' 489 SELECT node_id, entity_id, %s, 'subscribed'
456 FROM nodes, entities 490 FROM nodes, entities
457 WHERE node='pre-existing' AND jid=%s""", 491 WHERE node='pre-existing' AND jid=%s""",
458 (SUBSCRIBER.resource, 492 (SUBSCRIBER.resource,
459 SUBSCRIBER.userhost())) 493 SUBSCRIBER.userhost()))
460 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", 494 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
461 SUBSCRIBER_TO_BE_DELETED.userhost()) 495 SUBSCRIBER_TO_BE_DELETED.userhost())
462 cursor.execute("""INSERT INTO subscriptions 496 cursor.execute("""INSERT INTO subscriptions
463 (node_id, entity_id, resource, subscription) 497 (node_id, entity_id, resource, state)
464 SELECT nodes.id, entities.id, %s, 'subscribed' 498 SELECT node_id, entity_id, %s, 'subscribed'
465 FROM nodes, entities 499 FROM nodes, entities
466 WHERE node='pre-existing' AND jid=%s""", 500 WHERE node='pre-existing' AND jid=%s""",
467 (SUBSCRIBER_TO_BE_DELETED.resource, 501 (SUBSCRIBER_TO_BE_DELETED.resource,
468 SUBSCRIBER_TO_BE_DELETED.userhost())) 502 SUBSCRIBER_TO_BE_DELETED.userhost()))
469 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", 503 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
470 SUBSCRIBER_PENDING.userhost()) 504 SUBSCRIBER_PENDING.userhost())
471 cursor.execute("""INSERT INTO subscriptions 505 cursor.execute("""INSERT INTO subscriptions
472 (node_id, entity_id, resource, subscription) 506 (node_id, entity_id, resource, state)
473 SELECT nodes.id, entities.id, %s, 'pending' 507 SELECT node_id, entity_id, %s, 'pending'
474 FROM nodes, entities 508 FROM nodes, entities
475 WHERE node='pre-existing' AND jid=%s""", 509 WHERE node='pre-existing' AND jid=%s""",
476 (SUBSCRIBER_PENDING.resource, 510 (SUBSCRIBER_PENDING.resource,
477 SUBSCRIBER_PENDING.userhost())) 511 SUBSCRIBER_PENDING.userhost()))
478 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", 512 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
479 PUBLISHER.userhost()) 513 PUBLISHER.userhost())
480 cursor.execute("""INSERT INTO items 514 cursor.execute("""INSERT INTO items
481 (node_id, publisher, item, data, date) 515 (node_id, publisher, item, data, date)
482 SELECT nodes.id, %s, 'to-be-deleted', %s, 516 SELECT node_id, %s, 'to-be-deleted', %s,
483 now() - interval '1 day' 517 now() - interval '1 day'
484 FROM nodes 518 FROM nodes
485 WHERE node='pre-existing'""", 519 WHERE node='pre-existing'""",
486 (PUBLISHER.userhost(), 520 (PUBLISHER.userhost(),
487 ITEM_TO_BE_DELETED.toXml())) 521 ITEM_TO_BE_DELETED.toXml()))
488 cursor.execute("""INSERT INTO items (node_id, publisher, item, data) 522 cursor.execute("""INSERT INTO items (node_id, publisher, item, data)
489 SELECT nodes.id, %s, 'to-be-deleted', %s 523 SELECT node_id, %s, 'to-be-deleted', %s
490 FROM nodes 524 FROM nodes
491 WHERE node='to-be-purged'""", 525 WHERE node='to-be-purged'""",
492 (PUBLISHER.userhost(), 526 (PUBLISHER.userhost(),
493 ITEM_TO_BE_DELETED.toXml())) 527 ITEM_TO_BE_DELETED.toXml()))
494 cursor.execute("""INSERT INTO items (node_id, publisher, item, data) 528 cursor.execute("""INSERT INTO items (node_id, publisher, item, data)
495 SELECT nodes.id, %s, 'current', %s 529 SELECT node_id, %s, 'current', %s
496 FROM nodes 530 FROM nodes
497 WHERE node='pre-existing'""", 531 WHERE node='pre-existing'""",
498 (PUBLISHER.userhost(), 532 (PUBLISHER.userhost(),
499 ITEM.toXml())) 533 ITEM.toXml()))
500 534