Mercurial > libervia-pubsub
comparison src/test/test_storage.py @ 369:dabee42494ac
config file + cleaning:
- SàT Pubsub can now be configured using the same config file as SàT itself (i.e. sat.conf or .sat.conf), in the same locations (/etc, local dir, xdg dir).
Its options must be in the "pubsub" section
- options on command line override config options
- removed tap and http files which are not used anymore
- changed directory structure to put source in src, to be coherent with SàT and Libervia
- changed options name, db* become db_*, secret become xmpp_pwd
- an exception is raised if jid or xmpp_pwd is are not configured
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 02 Mar 2018 12:59:38 +0100 |
parents | sat_pubsub/test/test_storage.py@618a92080812 |
children | aa3a464df605 |
comparison
equal
deleted
inserted
replaced
368:618a92080812 | 369:dabee42494ac |
---|---|
1 #!/usr/bin/python | |
2 #-*- coding: utf-8 -*- | |
3 | |
4 # Copyright (c) 2003-2011 Ralph Meijer | |
5 # Copyright (c) 2012-2018 Jérôme Poisson | |
6 | |
7 | |
8 # This program is free software: you can redistribute it and/or modify | |
9 # it under the terms of the GNU Affero General Public License as published by | |
10 # the Free Software Foundation, either version 3 of the License, or | |
11 # (at your option) any later version. | |
12 | |
13 # This program is distributed in the hope that it will be useful, | |
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 # GNU Affero General Public License for more details. | |
17 | |
18 # You should have received a copy of the GNU Affero General Public License | |
19 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 # -- | |
21 | |
22 # This program is based on Idavoll (http://idavoll.ik.nu/), | |
23 # originaly written by Ralph Meijer (http://ralphm.net/blog/) | |
24 # It is sublicensed under AGPL v3 (or any later version) as allowed by the original | |
25 # license. | |
26 | |
27 # -- | |
28 | |
29 # Here is a copy of the original license: | |
30 | |
31 # Copyright (c) 2003-2011 Ralph Meijer | |
32 | |
33 # Permission is hereby granted, free of charge, to any person obtaining | |
34 # a copy of this software and associated documentation files (the | |
35 # "Software"), to deal in the Software without restriction, including | |
36 # without limitation the rights to use, copy, modify, merge, publish, | |
37 # distribute, sublicense, and/or sell copies of the Software, and to | |
38 # permit persons to whom the Software is furnished to do so, subject to | |
39 # the following conditions: | |
40 | |
41 # The above copyright notice and this permission notice shall be | |
42 # included in all copies or substantial portions of the Software. | |
43 | |
44 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
45 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
46 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
47 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
48 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
49 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
50 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
51 | |
52 | |
53 """ | |
54 Tests for L{idavoll.memory_storage} and L{idavoll.pgsql_storage}. | |
55 """ | |
56 | |
57 from zope.interface.verify import verifyObject | |
58 from twisted.trial import unittest | |
59 from twisted.words.protocols.jabber import jid | |
60 from twisted.internet import defer | |
61 from twisted.words.xish import domish | |
62 | |
63 from sat_pubsub import error, iidavoll, const | |
64 | |
65 OWNER = jid.JID('owner@example.com/Work') | |
66 SUBSCRIBER = jid.JID('subscriber@example.com/Home') | |
67 SUBSCRIBER_NEW = jid.JID('new@example.com/Home') | |
68 SUBSCRIBER_TO_BE_DELETED = jid.JID('to_be_deleted@example.com/Home') | |
69 SUBSCRIBER_PENDING = jid.JID('pending@example.com/Home') | |
70 PUBLISHER = jid.JID('publisher@example.com') | |
71 ITEM = domish.Element((None, 'item')) | |
72 ITEM['id'] = 'current' | |
73 ITEM.addElement(('testns', 'test'), content=u'Test \u2083 item') | |
74 ITEM_NEW = domish.Element((None, 'item')) | |
75 ITEM_NEW['id'] = 'new' | |
76 ITEM_NEW.addElement(('testns', 'test'), content=u'Test \u2083 item') | |
77 ITEM_UPDATED = domish.Element((None, 'item')) | |
78 ITEM_UPDATED['id'] = 'current' | |
79 ITEM_UPDATED.addElement(('testns', 'test'), content=u'Test \u2084 item') | |
80 ITEM_TO_BE_DELETED = domish.Element((None, 'item')) | |
81 ITEM_TO_BE_DELETED['id'] = 'to-be-deleted' | |
82 ITEM_TO_BE_DELETED.addElement(('testns', 'test'), content=u'Test \u2083 item') | |
83 | |
84 def decode(object): | |
85 if isinstance(object, str): | |
86 object = object.decode('utf-8') | |
87 return object | |
88 | |
89 | |
90 | |
91 class StorageTests: | |
92 | |
93 def _assignTestNode(self, node): | |
94 self.node = node | |
95 | |
96 | |
97 def setUp(self): | |
98 d = self.s.getNode('pre-existing') | |
99 d.addCallback(self._assignTestNode) | |
100 return d | |
101 | |
102 | |
103 def test_interfaceIStorage(self): | |
104 self.assertTrue(verifyObject(iidavoll.IStorage, self.s)) | |
105 | |
106 | |
107 def test_interfaceINode(self): | |
108 self.assertTrue(verifyObject(iidavoll.INode, self.node)) | |
109 | |
110 | |
111 def test_interfaceILeafNode(self): | |
112 self.assertTrue(verifyObject(iidavoll.ILeafNode, self.node)) | |
113 | |
114 | |
115 def test_getNode(self): | |
116 return self.s.getNode('pre-existing') | |
117 | |
118 | |
119 def test_getNonExistingNode(self): | |
120 d = self.s.getNode('non-existing') | |
121 self.assertFailure(d, error.NodeNotFound) | |
122 return d | |
123 | |
124 | |
125 def test_getNodeIDs(self): | |
126 def cb(nodeIdentifiers): | |
127 self.assertIn('pre-existing', nodeIdentifiers) | |
128 self.assertNotIn('non-existing', nodeIdentifiers) | |
129 | |
130 return self.s.getNodeIds().addCallback(cb) | |
131 | |
132 | |
133 def test_createExistingNode(self): | |
134 config = self.s.getDefaultConfiguration('leaf') | |
135 config['pubsub#node_type'] = 'leaf' | |
136 d = self.s.createNode('pre-existing', OWNER, config) | |
137 self.assertFailure(d, error.NodeExists) | |
138 return d | |
139 | |
140 | |
141 def test_createNode(self): | |
142 def cb(void): | |
143 d = self.s.getNode('new 1') | |
144 return d | |
145 | |
146 config = self.s.getDefaultConfiguration('leaf') | |
147 config['pubsub#node_type'] = 'leaf' | |
148 d = self.s.createNode('new 1', OWNER, config) | |
149 d.addCallback(cb) | |
150 return d | |
151 | |
152 | |
153 def test_createNodeChangingConfig(self): | |
154 """ | |
155 The configuration passed to createNode must be free to be changed. | |
156 """ | |
157 def cb(result): | |
158 node1, node2 = result | |
159 self.assertTrue(node1.getConfiguration()['pubsub#persist_items']) | |
160 | |
161 config = { | |
162 "pubsub#persist_items": True, | |
163 "pubsub#deliver_payloads": True, | |
164 "pubsub#send_last_published_item": 'on_sub', | |
165 "pubsub#node_type": 'leaf', | |
166 "pubsub#access_model": 'open', | |
167 const.OPT_PUBLISH_MODEL: const.VAL_PMODEL_OPEN | |
168 } | |
169 | |
170 def unsetPersistItems(_): | |
171 config["pubsub#persist_items"] = False | |
172 | |
173 d = defer.succeed(None) | |
174 d.addCallback(lambda _: self.s.createNode('new 1', OWNER, config)) | |
175 d.addCallback(unsetPersistItems) | |
176 d.addCallback(lambda _: self.s.createNode('new 2', OWNER, config)) | |
177 d.addCallback(lambda _: defer.gatherResults([ | |
178 self.s.getNode('new 1'), | |
179 self.s.getNode('new 2')])) | |
180 d.addCallback(cb) | |
181 return d | |
182 | |
183 | |
184 def test_deleteNonExistingNode(self): | |
185 d = self.s.deleteNode('non-existing') | |
186 self.assertFailure(d, error.NodeNotFound) | |
187 return d | |
188 | |
189 | |
190 def test_deleteNode(self): | |
191 def cb(void): | |
192 d = self.s.getNode('to-be-deleted') | |
193 self.assertFailure(d, error.NodeNotFound) | |
194 return d | |
195 | |
196 d = self.s.deleteNode('to-be-deleted') | |
197 d.addCallback(cb) | |
198 return d | |
199 | |
200 | |
201 def test_getAffiliations(self): | |
202 def cb(affiliations): | |
203 self.assertIn(('pre-existing', 'owner'), affiliations) | |
204 | |
205 d = self.s.getAffiliations(OWNER) | |
206 d.addCallback(cb) | |
207 return d | |
208 | |
209 | |
210 def test_getSubscriptions(self): | |
211 def cb(subscriptions): | |
212 found = False | |
213 for subscription in subscriptions: | |
214 if (subscription.nodeIdentifier == 'pre-existing' and | |
215 subscription.subscriber == SUBSCRIBER and | |
216 subscription.state == 'subscribed'): | |
217 found = True | |
218 self.assertTrue(found) | |
219 | |
220 d = self.s.getSubscriptions(SUBSCRIBER) | |
221 d.addCallback(cb) | |
222 return d | |
223 | |
224 | |
225 # Node tests | |
226 | |
227 def test_getType(self): | |
228 self.assertEqual(self.node.getType(), 'leaf') | |
229 | |
230 | |
231 def test_getConfiguration(self): | |
232 config = self.node.getConfiguration() | |
233 self.assertIn('pubsub#persist_items', config.iterkeys()) | |
234 self.assertIn('pubsub#deliver_payloads', config.iterkeys()) | |
235 self.assertEqual(config['pubsub#persist_items'], True) | |
236 self.assertEqual(config['pubsub#deliver_payloads'], True) | |
237 | |
238 | |
239 def test_setConfiguration(self): | |
240 def getConfig(node): | |
241 d = node.setConfiguration({'pubsub#persist_items': False}) | |
242 d.addCallback(lambda _: node) | |
243 return d | |
244 | |
245 def checkObjectConfig(node): | |
246 config = node.getConfiguration() | |
247 self.assertEqual(config['pubsub#persist_items'], False) | |
248 | |
249 def getNode(void): | |
250 return self.s.getNode('to-be-reconfigured') | |
251 | |
252 def checkStorageConfig(node): | |
253 config = node.getConfiguration() | |
254 self.assertEqual(config['pubsub#persist_items'], False) | |
255 | |
256 d = self.s.getNode('to-be-reconfigured') | |
257 d.addCallback(getConfig) | |
258 d.addCallback(checkObjectConfig) | |
259 d.addCallback(getNode) | |
260 d.addCallback(checkStorageConfig) | |
261 return d | |
262 | |
263 | |
264 def test_getMetaData(self): | |
265 metaData = self.node.getMetaData() | |
266 for key, value in self.node.getConfiguration().iteritems(): | |
267 self.assertIn(key, metaData.iterkeys()) | |
268 self.assertEqual(value, metaData[key]) | |
269 self.assertIn('pubsub#node_type', metaData.iterkeys()) | |
270 self.assertEqual(metaData['pubsub#node_type'], 'leaf') | |
271 | |
272 | |
273 def test_getAffiliation(self): | |
274 def cb(affiliation): | |
275 self.assertEqual(affiliation, 'owner') | |
276 | |
277 d = self.node.getAffiliation(OWNER) | |
278 d.addCallback(cb) | |
279 return d | |
280 | |
281 | |
282 def test_getNonExistingAffiliation(self): | |
283 def cb(affiliation): | |
284 self.assertEqual(affiliation, None) | |
285 | |
286 d = self.node.getAffiliation(SUBSCRIBER) | |
287 d.addCallback(cb) | |
288 return d | |
289 | |
290 | |
291 def test_addSubscription(self): | |
292 def cb1(void): | |
293 return self.node.getSubscription(SUBSCRIBER_NEW) | |
294 | |
295 def cb2(subscription): | |
296 self.assertEqual(subscription.state, 'pending') | |
297 | |
298 d = self.node.addSubscription(SUBSCRIBER_NEW, 'pending', {}) | |
299 d.addCallback(cb1) | |
300 d.addCallback(cb2) | |
301 return d | |
302 | |
303 | |
304 def test_addExistingSubscription(self): | |
305 d = self.node.addSubscription(SUBSCRIBER, 'pending', {}) | |
306 self.assertFailure(d, error.SubscriptionExists) | |
307 return d | |
308 | |
309 | |
310 def test_getSubscription(self): | |
311 def cb(subscriptions): | |
312 self.assertEquals(subscriptions[0].state, 'subscribed') | |
313 self.assertEquals(subscriptions[1].state, 'pending') | |
314 self.assertEquals(subscriptions[2], None) | |
315 | |
316 d = defer.gatherResults([self.node.getSubscription(SUBSCRIBER), | |
317 self.node.getSubscription(SUBSCRIBER_PENDING), | |
318 self.node.getSubscription(OWNER)]) | |
319 d.addCallback(cb) | |
320 return d | |
321 | |
322 | |
323 def test_removeSubscription(self): | |
324 return self.node.removeSubscription(SUBSCRIBER_TO_BE_DELETED) | |
325 | |
326 | |
327 def test_removeNonExistingSubscription(self): | |
328 d = self.node.removeSubscription(OWNER) | |
329 self.assertFailure(d, error.NotSubscribed) | |
330 return d | |
331 | |
332 | |
333 def test_getNodeSubscriptions(self): | |
334 def extractSubscribers(subscriptions): | |
335 return [subscription.subscriber for subscription in subscriptions] | |
336 | |
337 def cb(subscribers): | |
338 self.assertIn(SUBSCRIBER, subscribers) | |
339 self.assertNotIn(SUBSCRIBER_PENDING, subscribers) | |
340 self.assertNotIn(OWNER, subscribers) | |
341 | |
342 d = self.node.getSubscriptions('subscribed') | |
343 d.addCallback(extractSubscribers) | |
344 d.addCallback(cb) | |
345 return d | |
346 | |
347 | |
348 def test_isSubscriber(self): | |
349 def cb(subscribed): | |
350 self.assertEquals(subscribed[0][1], True) | |
351 self.assertEquals(subscribed[1][1], True) | |
352 self.assertEquals(subscribed[2][1], False) | |
353 self.assertEquals(subscribed[3][1], False) | |
354 | |
355 d = defer.DeferredList([self.node.isSubscribed(SUBSCRIBER), | |
356 self.node.isSubscribed(SUBSCRIBER.userhostJID()), | |
357 self.node.isSubscribed(SUBSCRIBER_PENDING), | |
358 self.node.isSubscribed(OWNER)]) | |
359 d.addCallback(cb) | |
360 return d | |
361 | |
362 | |
363 def test_storeItems(self): | |
364 def cb1(void): | |
365 return self.node.getItemsById("", False, ['new']) | |
366 | |
367 def cb2(result): | |
368 self.assertEqual(ITEM_NEW.toXml(), result[0].toXml()) | |
369 | |
370 d = self.node.storeItems([(const.VAL_AMODEL_DEFAULT, {}, ITEM_NEW)], PUBLISHER) | |
371 d.addCallback(cb1) | |
372 d.addCallback(cb2) | |
373 return d | |
374 | |
375 | |
376 def test_storeUpdatedItems(self): | |
377 def cb1(void): | |
378 return self.node.getItemsById("", False, ['current']) | |
379 | |
380 def cb2(result): | |
381 self.assertEqual(ITEM_UPDATED.toXml(), result[0].toXml()) | |
382 | |
383 d = self.node.storeItems([(const.VAL_AMODEL_DEFAULT, {}, ITEM_UPDATED)], PUBLISHER) | |
384 d.addCallback(cb1) | |
385 d.addCallback(cb2) | |
386 return d | |
387 | |
388 | |
389 def test_removeItems(self): | |
390 def cb1(result): | |
391 self.assertEqual(['to-be-deleted'], result) | |
392 return self.node.getItemsById("", False, ['to-be-deleted']) | |
393 | |
394 def cb2(result): | |
395 self.assertEqual(0, len(result)) | |
396 | |
397 d = self.node.removeItems(['to-be-deleted']) | |
398 d.addCallback(cb1) | |
399 d.addCallback(cb2) | |
400 return d | |
401 | |
402 | |
403 def test_removeNonExistingItems(self): | |
404 def cb(result): | |
405 self.assertEqual([], result) | |
406 | |
407 d = self.node.removeItems(['non-existing']) | |
408 d.addCallback(cb) | |
409 return d | |
410 | |
411 | |
412 def test_getItems(self): | |
413 def cb(result): | |
414 items = [item.toXml() for item in result] | |
415 self.assertIn(ITEM.toXml(), items) | |
416 d = self.node.getItems("", False) | |
417 d.addCallback(cb) | |
418 return d | |
419 | |
420 | |
421 def test_lastItem(self): | |
422 def cb(result): | |
423 self.assertEqual(1, len(result)) | |
424 self.assertEqual(ITEM.toXml(), result[0].toXml()) | |
425 | |
426 d = self.node.getItems("", False, 1) | |
427 d.addCallback(cb) | |
428 return d | |
429 | |
430 | |
431 def test_getItemsById(self): | |
432 def cb(result): | |
433 self.assertEqual(1, len(result)) | |
434 | |
435 d = self.node.getItemsById("", False, ['current']) | |
436 d.addCallback(cb) | |
437 return d | |
438 | |
439 | |
440 def test_getNonExistingItemsById(self): | |
441 def cb(result): | |
442 self.assertEqual(0, len(result)) | |
443 | |
444 d = self.node.getItemsById("", False, ['non-existing']) | |
445 d.addCallback(cb) | |
446 return d | |
447 | |
448 | |
449 def test_purge(self): | |
450 def cb1(node): | |
451 d = node.purge() | |
452 d.addCallback(lambda _: node) | |
453 return d | |
454 | |
455 def cb2(node): | |
456 return node.getItems("", False) | |
457 | |
458 def cb3(result): | |
459 self.assertEqual([], result) | |
460 | |
461 d = self.s.getNode('to-be-purged') | |
462 d.addCallback(cb1) | |
463 d.addCallback(cb2) | |
464 d.addCallback(cb3) | |
465 return d | |
466 | |
467 | |
468 def test_getNodeAffilatiations(self): | |
469 def cb1(node): | |
470 return node.getAffiliations() | |
471 | |
472 def cb2(affiliations): | |
473 affiliations = dict(((a[0].full(), a[1]) for a in affiliations)) | |
474 self.assertEquals(affiliations[OWNER.userhost()], 'owner') | |
475 | |
476 d = self.s.getNode('pre-existing') | |
477 d.addCallback(cb1) | |
478 d.addCallback(cb2) | |
479 return d | |
480 | |
481 | |
482 | |
483 class MemoryStorageStorageTestCase(unittest.TestCase, StorageTests): | |
484 | |
485 def setUp(self): | |
486 from sat_pubsub.memory_storage import Storage, PublishedItem, LeafNode | |
487 from sat_pubsub.memory_storage import Subscription | |
488 | |
489 defaultConfig = Storage.defaultConfig['leaf'] | |
490 | |
491 self.s = Storage() | |
492 self.s._nodes['pre-existing'] = \ | |
493 LeafNode('pre-existing', OWNER, defaultConfig) | |
494 self.s._nodes['to-be-deleted'] = \ | |
495 LeafNode('to-be-deleted', OWNER, None) | |
496 self.s._nodes['to-be-reconfigured'] = \ | |
497 LeafNode('to-be-reconfigured', OWNER, defaultConfig) | |
498 self.s._nodes['to-be-purged'] = \ | |
499 LeafNode('to-be-purged', OWNER, None) | |
500 | |
501 subscriptions = self.s._nodes['pre-existing']._subscriptions | |
502 subscriptions[SUBSCRIBER.full()] = Subscription('pre-existing', | |
503 SUBSCRIBER, | |
504 'subscribed') | |
505 subscriptions[SUBSCRIBER_TO_BE_DELETED.full()] = \ | |
506 Subscription('pre-existing', SUBSCRIBER_TO_BE_DELETED, | |
507 'subscribed') | |
508 subscriptions[SUBSCRIBER_PENDING.full()] = \ | |
509 Subscription('pre-existing', SUBSCRIBER_PENDING, | |
510 'pending') | |
511 | |
512 item = PublishedItem(ITEM_TO_BE_DELETED, PUBLISHER) | |
513 self.s._nodes['pre-existing']._items['to-be-deleted'] = item | |
514 self.s._nodes['pre-existing']._itemlist.append(item) | |
515 self.s._nodes['to-be-purged']._items['to-be-deleted'] = item | |
516 self.s._nodes['to-be-purged']._itemlist.append(item) | |
517 item = PublishedItem(ITEM, PUBLISHER) | |
518 self.s._nodes['pre-existing']._items['current'] = item | |
519 self.s._nodes['pre-existing']._itemlist.append(item) | |
520 | |
521 return StorageTests.setUp(self) | |
522 | |
523 | |
524 | |
525 class PgsqlStorageStorageTestCase(unittest.TestCase, StorageTests): | |
526 | |
527 dbpool = None | |
528 | |
529 def setUp(self): | |
530 from sat_pubsub.pgsql_storage import Storage | |
531 from twisted.enterprise import adbapi | |
532 if self.dbpool is None: | |
533 self.__class__.dbpool = adbapi.ConnectionPool('psycopg2', | |
534 database='pubsub_test', | |
535 cp_reconnect=True, | |
536 client_encoding='utf-8', | |
537 connection_factory=NamedTupleConnection, | |
538 ) | |
539 self.s = Storage(self.dbpool) | |
540 self.dbpool.start() | |
541 d = self.dbpool.runInteraction(self.init) | |
542 d.addCallback(lambda _: StorageTests.setUp(self)) | |
543 return d | |
544 | |
545 | |
546 def tearDown(self): | |
547 d = self.dbpool.runInteraction(self.cleandb) | |
548 return d.addCallback(lambda _: self.dbpool.close()) | |
549 | |
550 | |
551 def init(self, cursor): | |
552 self.cleandb(cursor) | |
553 cursor.execute("""INSERT INTO nodes | |
554 (node, node_type, persist_items) | |
555 VALUES ('pre-existing', 'leaf', TRUE)""") | |
556 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-deleted')""") | |
557 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-reconfigured')""") | |
558 cursor.execute("""INSERT INTO nodes (node) VALUES ('to-be-purged')""") | |
559 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", | |
560 (OWNER.userhost(),)) | |
561 cursor.execute("""INSERT INTO affiliations | |
562 (node_id, entity_id, affiliation) | |
563 SELECT node_id, entity_id, 'owner' | |
564 FROM nodes, entities | |
565 WHERE node='pre-existing' AND jid=%s""", | |
566 (OWNER.userhost(),)) | |
567 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", | |
568 (SUBSCRIBER.userhost(),)) | |
569 cursor.execute("""INSERT INTO subscriptions | |
570 (node_id, entity_id, resource, state) | |
571 SELECT node_id, entity_id, %s, 'subscribed' | |
572 FROM nodes, entities | |
573 WHERE node='pre-existing' AND jid=%s""", | |
574 (SUBSCRIBER.resource, | |
575 SUBSCRIBER.userhost())) | |
576 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", | |
577 (SUBSCRIBER_TO_BE_DELETED.userhost(),)) | |
578 cursor.execute("""INSERT INTO subscriptions | |
579 (node_id, entity_id, resource, state) | |
580 SELECT node_id, entity_id, %s, 'subscribed' | |
581 FROM nodes, entities | |
582 WHERE node='pre-existing' AND jid=%s""", | |
583 (SUBSCRIBER_TO_BE_DELETED.resource, | |
584 SUBSCRIBER_TO_BE_DELETED.userhost())) | |
585 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", | |
586 (SUBSCRIBER_PENDING.userhost(),)) | |
587 cursor.execute("""INSERT INTO subscriptions | |
588 (node_id, entity_id, resource, state) | |
589 SELECT node_id, entity_id, %s, 'pending' | |
590 FROM nodes, entities | |
591 WHERE node='pre-existing' AND jid=%s""", | |
592 (SUBSCRIBER_PENDING.resource, | |
593 SUBSCRIBER_PENDING.userhost())) | |
594 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", | |
595 (PUBLISHER.userhost(),)) | |
596 cursor.execute("""INSERT INTO items | |
597 (node_id, publisher, item, data, created) | |
598 SELECT node_id, %s, 'to-be-deleted', %s, | |
599 now() - interval '1 day' | |
600 FROM nodes | |
601 WHERE node='pre-existing'""", | |
602 (PUBLISHER.userhost(), | |
603 ITEM_TO_BE_DELETED.toXml())) | |
604 cursor.execute("""INSERT INTO items (node_id, publisher, item, data) | |
605 SELECT node_id, %s, 'to-be-deleted', %s | |
606 FROM nodes | |
607 WHERE node='to-be-purged'""", | |
608 (PUBLISHER.userhost(), | |
609 ITEM_TO_BE_DELETED.toXml())) | |
610 cursor.execute("""INSERT INTO items (node_id, publisher, item, data) | |
611 SELECT node_id, %s, 'current', %s | |
612 FROM nodes | |
613 WHERE node='pre-existing'""", | |
614 (PUBLISHER.userhost(), | |
615 ITEM.toXml())) | |
616 | |
617 | |
618 def cleandb(self, cursor): | |
619 cursor.execute("""DELETE FROM nodes WHERE node in | |
620 ('non-existing', 'pre-existing', 'to-be-deleted', | |
621 'new 1', 'new 2', 'new 3', 'to-be-reconfigured', | |
622 'to-be-purged')""") | |
623 cursor.execute("""DELETE FROM entities WHERE jid=%s""", | |
624 (OWNER.userhost(),)) | |
625 cursor.execute("""DELETE FROM entities WHERE jid=%s""", | |
626 (SUBSCRIBER.userhost(),)) | |
627 cursor.execute("""DELETE FROM entities WHERE jid=%s""", | |
628 (SUBSCRIBER_NEW.userhost(),)) | |
629 cursor.execute("""DELETE FROM entities WHERE jid=%s""", | |
630 (SUBSCRIBER_TO_BE_DELETED.userhost(),)) | |
631 cursor.execute("""DELETE FROM entities WHERE jid=%s""", | |
632 (SUBSCRIBER_PENDING.userhost(),)) | |
633 cursor.execute("""DELETE FROM entities WHERE jid=%s""", | |
634 (PUBLISHER.userhost(),)) | |
635 | |
636 | |
637 try: | |
638 import psycopg2 | |
639 psycopg2 | |
640 from psycopg2.extras import NamedTupleConnection | |
641 except ImportError: | |
642 PgsqlStorageStorageTestCase.skip = "psycopg2 not available" |