44 from cubicweb.dbapi import Connection |
44 from cubicweb.dbapi import Connection |
45 |
45 |
46 PyroRQLSource_get_connection = PyroRQLSource.get_connection |
46 PyroRQLSource_get_connection = PyroRQLSource.get_connection |
47 Connection_close = Connection.close |
47 Connection_close = Connection.close |
48 |
48 |
49 def setUpModule(*args): |
49 def pre_setup_database_extern(session, config): |
50 global repo2, cnx2, repo3, cnx3 |
50 session.execute('INSERT Card X: X title "C3: An external card", X wikiid "aaa"') |
51 cfg1 = ExternalSource1Configuration('data', apphome=TwoSourcesTC.datadir) |
51 session.execute('INSERT Card X: X title "C4: Ze external card", X wikiid "zzz"') |
52 repo2, cnx2 = init_test_database(config=cfg1) |
52 session.execute('INSERT Affaire X: X ref "AFFREF"') |
53 cfg2 = ExternalSource2Configuration('data', apphome=TwoSourcesTC.datadir) |
53 session.commit() |
54 repo3, cnx3 = init_test_database(config=cfg2) |
54 |
55 cnx3.request().create_entity('CWSource', name=u'extern', type=u'pyrorql', |
55 def pre_setup_database_multi(session, config): |
|
56 session.create_entity('CWSource', name=u'extern', type=u'pyrorql', |
56 config=EXTERN_SOURCE_CFG) |
57 config=EXTERN_SOURCE_CFG) |
57 cnx3.commit() |
58 session.commit() |
58 |
|
59 TestServerConfiguration.no_sqlite_wrap = True |
|
60 # hi-jack PyroRQLSource.get_connection to access existing connection (no |
|
61 # pyro connection) |
|
62 PyroRQLSource.get_connection = lambda x: x.uri == 'extern-multi' and cnx3 or cnx2 |
|
63 # also necessary since the repository is closing its initial connections |
|
64 # pool though we want to keep cnx2 valid |
|
65 Connection.close = lambda x: None |
|
66 |
|
67 def tearDownModule(*args): |
|
68 PyroRQLSource.get_connection = PyroRQLSource_get_connection |
|
69 Connection.close = Connection_close |
|
70 global repo2, cnx2, repo3, cnx3 |
|
71 repo2.shutdown() |
|
72 repo3.shutdown() |
|
73 del repo2, cnx2, repo3, cnx3 |
|
74 #del TwoSourcesTC.config.vreg |
|
75 #del TwoSourcesTC.config |
|
76 TestServerConfiguration.no_sqlite_wrap = False |
|
77 |
59 |
78 class TwoSourcesTC(CubicWebTC): |
60 class TwoSourcesTC(CubicWebTC): |
79 """Main repo -> extern-multi -> extern |
61 """Main repo -> extern-multi -> extern |
80 \-------------/ |
62 \-------------/ |
81 """ |
63 """ |
|
64 test_db_id= 'cw-server-multisources' |
|
65 tags = CubicWebTC.tags | Tags(('multisources')) |
|
66 |
82 @classmethod |
67 @classmethod |
83 def _refresh_repo(cls): |
68 def setUpClass(cls): |
84 super(TwoSourcesTC, cls)._refresh_repo() |
69 cls._cfg2 = ExternalSource1Configuration('data', apphome=TwoSourcesTC.datadir) |
85 cnx2.rollback() |
70 cls._cfg3 = ExternalSource2Configuration('data', apphome=TwoSourcesTC.datadir) |
86 refresh_repo(repo2) |
71 TestServerConfiguration.no_sqlite_wrap = True |
87 cnx3.rollback() |
72 # hi-jack PyroRQLSource.get_connection to access existing connection (no |
88 refresh_repo(repo3) |
73 # pyro connection) |
|
74 PyroRQLSource.get_connection = lambda x: x.uri == 'extern-multi' and cls.cnx3 or cls.cnx2 |
|
75 # also necessary since the repository is closing its initial connections |
|
76 # pool though we want to keep cnx2 valid |
|
77 Connection.close = lambda x: None |
|
78 |
|
79 @classmethod |
|
80 def tearDowncls(cls): |
|
81 PyroRQLSource.get_connection = PyroRQLSource_get_connection |
|
82 Connection.close = Connection_close |
|
83 cls.cnx2.close() |
|
84 cls.cnx3.close() |
|
85 TestServerConfiguration.no_sqlite_wrap = False |
|
86 |
|
87 |
|
88 @classmethod |
|
89 def _init_repo(cls): |
|
90 repo2_handler = get_test_db_handler(cls._cfg2) |
|
91 repo2_handler.build_db_cache('4cards-1affaire',pre_setup_func=pre_setup_database_extern) |
|
92 cls.repo2, cls.cnx2 = repo2_handler.get_repo_and_cnx('4cards-1affaire') |
|
93 |
|
94 repo3_handler = get_test_db_handler(cls._cfg3) |
|
95 repo3_handler.build_db_cache('multisource',pre_setup_func=pre_setup_database_multi) |
|
96 cls.repo3, cls.cnx3 = repo3_handler.get_repo_and_cnx('multisource') |
|
97 |
|
98 |
|
99 super(TwoSourcesTC, cls)._init_repo() |
89 |
100 |
90 def setUp(self): |
101 def setUp(self): |
91 CubicWebTC.setUp(self) |
102 CubicWebTC.setUp(self) |
|
103 self.addCleanup(self.cnx2.close) |
|
104 self.addCleanup(self.cnx3.close) |
92 do_monkey_patch() |
105 do_monkey_patch() |
93 |
106 |
94 def tearDown(self): |
107 def tearDown(self): |
95 for source in self.repo.sources[1:]: |
108 for source in self.repo.sources[1:]: |
96 self.repo.remove_source(source.uri) |
109 self.repo.remove_source(source.uri) |
97 CubicWebTC.tearDown(self) |
110 CubicWebTC.tearDown(self) |
|
111 self.cnx2.close() |
|
112 self.cnx3.close() |
98 undo_monkey_patch() |
113 undo_monkey_patch() |
99 |
114 |
100 def setup_database(self): |
115 @staticmethod |
101 cu = cnx2.cursor() |
116 def pre_setup_database(session, config): |
102 self.ec1 = cu.execute('INSERT Card X: X title "C3: An external card", X wikiid "aaa"')[0][0] |
117 for uri, src_config in [('extern', EXTERN_SOURCE_CFG), |
103 cu.execute('INSERT Card X: X title "C4: Ze external card", X wikiid "zzz"') |
|
104 self.aff1 = cu.execute('INSERT Affaire X: X ref "AFFREF"')[0][0] |
|
105 cnx2.commit() |
|
106 for uri, config in [('extern', EXTERN_SOURCE_CFG), |
|
107 ('extern-multi', ''' |
118 ('extern-multi', ''' |
108 pyro-ns-id = extern-multi |
119 pyro-ns-id = extern-multi |
109 cubicweb-user = admin |
120 cubicweb-user = admin |
110 cubicweb-password = gingkow |
121 cubicweb-password = gingkow |
111 mapping-file = extern_mapping.py |
122 mapping-file = extern_mapping.py |
112 ''')]: |
123 ''')]: |
113 self.request().create_entity('CWSource', name=unicode(uri), |
124 session.create_entity('CWSource', name=unicode(uri), |
114 type=u'pyrorql', |
125 type=u'pyrorql', |
115 config=unicode(config)) |
126 config=unicode(src_config)) |
116 self.commit() |
127 session.commit() |
117 # trigger discovery |
128 # trigger discovery |
118 self.sexecute('Card X') |
129 session.execute('Card X') |
119 self.sexecute('Affaire X') |
130 session.execute('Affaire X') |
120 self.sexecute('State X') |
131 session.execute('State X') |
|
132 |
|
133 def setup_database(self): |
|
134 cu2 = self.cnx2.cursor() |
|
135 self.ec1 = cu2.execute('Any X WHERE X is Card, X title "C3: An external card", X wikiid "aaa"')[0][0] |
|
136 self.aff1 = cu2.execute('Any X WHERE X is Affaire, X ref "AFFREF"')[0][0] |
|
137 cu2.close() |
121 # add some entities |
138 # add some entities |
122 self.ic1 = self.sexecute('INSERT Card X: X title "C1: An internal card", X wikiid "aaai"')[0][0] |
139 self.ic1 = self.sexecute('INSERT Card X: X title "C1: An internal card", X wikiid "aaai"')[0][0] |
123 self.ic2 = self.sexecute('INSERT Card X: X title "C2: Ze internal card", X wikiid "zzzi"')[0][0] |
140 self.ic2 = self.sexecute('INSERT Card X: X title "C2: Ze internal card", X wikiid "zzzi"')[0][0] |
124 |
141 |
125 def test_eid_comp(self): |
142 def test_eid_comp(self): |
175 rset = cu.execute('Any X ORDERBY FTIRANK(X) WHERE X has_text "card"') |
192 rset = cu.execute('Any X ORDERBY FTIRANK(X) WHERE X has_text "card"') |
176 self.assertEqual(len(rset), 5, zip(rset.rows, rset.description)) |
193 self.assertEqual(len(rset), 5, zip(rset.rows, rset.description)) |
177 Connection_close(cnx.cnx) # cnx is a TestCaseConnectionProxy |
194 Connection_close(cnx.cnx) # cnx is a TestCaseConnectionProxy |
178 |
195 |
179 def test_synchronization(self): |
196 def test_synchronization(self): |
180 cu = cnx2.cursor() |
197 cu = self.cnx2.cursor() |
181 assert cu.execute('Any X WHERE X eid %(x)s', {'x': self.aff1}) |
198 assert cu.execute('Any X WHERE X eid %(x)s', {'x': self.aff1}) |
182 cu.execute('SET X ref "BLAH" WHERE X eid %(x)s', {'x': self.aff1}) |
199 cu.execute('SET X ref "BLAH" WHERE X eid %(x)s', {'x': self.aff1}) |
183 aff2 = cu.execute('INSERT Affaire X: X ref "AFFREUX"')[0][0] |
200 aff2 = cu.execute('INSERT Affaire X: X ref "AFFREUX"')[0][0] |
184 cnx2.commit() |
201 self.cnx2.commit() |
185 try: |
202 try: |
186 # force sync |
203 # force sync |
187 self.repo.sources_by_uri['extern'].synchronize(MTIME) |
204 self.repo.sources_by_uri['extern'].synchronize(MTIME) |
188 self.failUnless(self.sexecute('Any X WHERE X has_text "blah"')) |
205 self.failUnless(self.sexecute('Any X WHERE X has_text "blah"')) |
189 self.failUnless(self.sexecute('Any X WHERE X has_text "affreux"')) |
206 self.failUnless(self.sexecute('Any X WHERE X has_text "affreux"')) |
190 cu.execute('DELETE Affaire X WHERE X eid %(x)s', {'x': aff2}) |
207 cu.execute('DELETE Affaire X WHERE X eid %(x)s', {'x': aff2}) |
191 cnx2.commit() |
208 self.cnx2.commit() |
192 self.repo.sources_by_uri['extern'].synchronize(MTIME) |
209 self.repo.sources_by_uri['extern'].synchronize(MTIME) |
193 rset = self.sexecute('Any X WHERE X has_text "affreux"') |
210 rset = self.sexecute('Any X WHERE X has_text "affreux"') |
194 self.failIf(rset) |
211 self.failIf(rset) |
195 finally: |
212 finally: |
196 # restore state |
213 # restore state |
197 cu.execute('SET X ref "AFFREF" WHERE X eid %(x)s', {'x': self.aff1}) |
214 cu.execute('SET X ref "AFFREF" WHERE X eid %(x)s', {'x': self.aff1}) |
198 cnx2.commit() |
215 self.cnx2.commit() |
199 |
216 |
200 def test_simplifiable_var(self): |
217 def test_simplifiable_var(self): |
201 affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0] |
218 affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0] |
202 rset = self.sexecute('Any X,AA,AB WHERE E eid %(x)s, E in_state X, X name AA, X modification_date AB', |
219 rset = self.sexecute('Any X,AA,AB WHERE E eid %(x)s, E in_state X, X name AA, X modification_date AB', |
203 {'x': affeid}) |
220 {'x': affeid}) |
245 n2 = self.sexecute('INSERT Note X: X type "AFFREU"')[0][0] |
262 n2 = self.sexecute('INSERT Note X: X type "AFFREU"')[0][0] |
246 rset = self.sexecute('Any X,Y WHERE X is Note, Y is Affaire, X type T, Y ref T') |
263 rset = self.sexecute('Any X,Y WHERE X is Note, Y is Affaire, X type T, Y ref T') |
247 self.assertEqual(len(rset), 1, rset.rows) |
264 self.assertEqual(len(rset), 1, rset.rows) |
248 |
265 |
249 def test_attr_unification_2(self): |
266 def test_attr_unification_2(self): |
250 cu = cnx2.cursor() |
267 cu = self.cnx2.cursor() |
251 ec2 = cu.execute('INSERT Card X: X title "AFFREF"')[0][0] |
268 ec2 = cu.execute('INSERT Card X: X title "AFFREF"')[0][0] |
252 cnx2.commit() |
269 self.cnx2.commit() |
253 try: |
270 try: |
254 c1 = self.sexecute('INSERT Card C: C title "AFFREF"')[0][0] |
271 c1 = self.sexecute('INSERT Card C: C title "AFFREF"')[0][0] |
255 rset = self.sexecute('Any X,Y WHERE X is Card, Y is Affaire, X title T, Y ref T') |
272 rset = self.sexecute('Any X,Y WHERE X is Card, Y is Affaire, X title T, Y ref T') |
256 self.assertEqual(len(rset), 2, rset.rows) |
273 self.assertEqual(len(rset), 2, rset.rows) |
257 finally: |
274 finally: |
258 cu.execute('DELETE Card X WHERE X eid %(x)s', {'x': ec2}) |
275 cu.execute('DELETE Card X WHERE X eid %(x)s', {'x': ec2}) |
259 cnx2.commit() |
276 self.cnx2.commit() |
260 |
277 |
261 def test_attr_unification_neq_1(self): |
278 def test_attr_unification_neq_1(self): |
262 # XXX complete |
279 # XXX complete |
263 self.sexecute('Any X,Y WHERE X is Note, Y is Affaire, X creation_date D, Y creation_date > D') |
280 self.sexecute('Any X,Y WHERE X is Note, Y is Affaire, X creation_date D, Y creation_date > D') |
264 |
281 |
306 notstates = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s', |
323 notstates = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s', |
307 {'x': aff1})) |
324 {'x': aff1})) |
308 self.assertSetEqual(notstates, states) |
325 self.assertSetEqual(notstates, states) |
309 |
326 |
310 def test_absolute_url_base_url(self): |
327 def test_absolute_url_base_url(self): |
311 cu = cnx2.cursor() |
328 cu = self.cnx2.cursor() |
312 ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0] |
329 ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0] |
313 cnx2.commit() |
330 self.cnx2.commit() |
314 lc = self.sexecute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0) |
331 lc = self.sexecute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0) |
315 self.assertEqual(lc.absolute_url(), 'http://extern.org/card/eid/%s' % ceid) |
332 self.assertEqual(lc.absolute_url(), 'http://extern.org/card/eid/%s' % ceid) |
316 cu.execute('DELETE Card X WHERE X eid %(x)s', {'x':ceid}) |
333 cu.execute('DELETE Card X WHERE X eid %(x)s', {'x':ceid}) |
317 cnx2.commit() |
334 self.cnx2.commit() |
318 |
335 |
319 def test_absolute_url_no_base_url(self): |
336 def test_absolute_url_no_base_url(self): |
320 cu = cnx3.cursor() |
337 cu = self.cnx3.cursor() |
321 ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0] |
338 ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0] |
322 cnx3.commit() |
339 self.cnx3.commit() |
323 lc = self.sexecute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0) |
340 lc = self.sexecute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0) |
324 self.assertEqual(lc.absolute_url(), 'http://testing.fr/cubicweb/card/eid/%s' % lc.eid) |
341 self.assertEqual(lc.absolute_url(), 'http://testing.fr/cubicweb/card/eid/%s' % lc.eid) |
325 cu.execute('DELETE Card X WHERE X eid %(x)s', {'x':ceid}) |
342 cu.execute('DELETE Card X WHERE X eid %(x)s', {'x':ceid}) |
326 cnx3.commit() |
343 self.cnx3.commit() |
327 |
344 |
328 def test_crossed_relation_noeid_needattr(self): |
345 def test_crossed_relation_noeid_needattr(self): |
329 """http://www.cubicweb.org/ticket/1382452""" |
346 """http://www.cubicweb.org/ticket/1382452""" |
330 aff1 = self.sexecute('INSERT Affaire X: X ref "AFFREF"')[0][0] |
347 aff1 = self.sexecute('INSERT Affaire X: X ref "AFFREF"')[0][0] |
331 # link within extern source |
348 # link within extern source |