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