server/test/unittest_msplanner.py
changeset 1228 91ae10ffb611
parent 1122 9f37de24251f
child 1230 232e16835fff
equal deleted inserted replaced
1219:054bb575c013 1228:91ae10ffb611
   116                   
   116                   
   117 class PartPlanInformationTC(BaseMSPlannerTC):
   117 class PartPlanInformationTC(BaseMSPlannerTC):
   118 
   118 
   119     def _test(self, rql, *args):
   119     def _test(self, rql, *args):
   120         if len(args) == 3:
   120         if len(args) == 3:
   121             kwargs, sourcesvars, needsplit = args
   121             kwargs, sourcesterms, needsplit = args
   122         else:
   122         else:
   123             sourcesvars, needsplit = args
   123             sourcesterms, needsplit = args
   124             kwargs = None
   124             kwargs = None
   125         plan = self._prepare_plan(rql, kwargs)
   125         plan = self._prepare_plan(rql, kwargs)
   126         union = plan.rqlst
   126         union = plan.rqlst
   127         plan.preprocess(union)
   127         plan.preprocess(union)
   128         ppi = PartPlanInformation(plan, union.children[0])
   128         ppi = PartPlanInformation(plan, union.children[0])
   129         for sourcevars in ppi._sourcesvars.itervalues():
   129         for sourcevars in ppi._sourcesterms.itervalues():
   130             for var in sourcevars.keys():
   130             for var in sourcevars.keys():
   131                 solindices = sourcevars.pop(var)
   131                 solindices = sourcevars.pop(var)
   132                 sourcevars[var._ms_table_key()] = solindices
   132                 sourcevars[var._ms_table_key()] = solindices
   133         self.assertEquals(ppi._sourcesvars, sourcesvars)
   133         self.assertEquals(ppi._sourcesterms, sourcesterms)
   134         self.assertEquals(ppi.needsplit, needsplit)
   134         self.assertEquals(ppi.needsplit, needsplit)
   135 
   135 
   136         
   136         
   137     def test_simple_system_only(self):
   137     def test_simple_system_only(self):
   138         """retrieve entities only supported by the system source"""
   138         """retrieve entities only supported by the system source"""
   161     def test_simple_eid_invariant(self):
   161     def test_simple_eid_invariant(self):
   162         """retrieve EUser X from system source (eid is specified, can locate the entity)
   162         """retrieve EUser X from system source (eid is specified, can locate the entity)
   163         """
   163         """
   164         ueid = self.session.user.eid
   164         ueid = self.session.user.eid
   165         self._test('Any X WHERE X eid %(x)s', {'x': ueid},
   165         self._test('Any X WHERE X eid %(x)s', {'x': ueid},
   166                    {}, False)
   166                    {self.system: {'x': s[0]}}, False)
   167         
   167         
   168     def test_simple_invariant(self):
   168     def test_simple_invariant(self):
   169         """retrieve EUser X from system source only (X is invariant and in_group not supported by ldap source)
   169         """retrieve EUser X from system source only (X is invariant and in_group not supported by ldap source)
   170         """
   170         """
   171         self._test('Any X WHERE X is EUser, X in_group G, G name "users"',
   171         self._test('Any X WHERE X is EUser, X in_group G, G name "users"',
   239                    {self.system: {'X': solindexes}}, False)
   239                    {self.system: {'X': solindexes}}, False)
   240                    
   240                    
   241     def test_complex_optional(self):
   241     def test_complex_optional(self):
   242         ueid = self.session.user.eid
   242         ueid = self.session.user.eid
   243         self._test('Any U WHERE WF wf_info_for X, X eid %(x)s, WF owned_by U?, WF from_state FS', {'x': ueid},
   243         self._test('Any U WHERE WF wf_info_for X, X eid %(x)s, WF owned_by U?, WF from_state FS', {'x': ueid},
   244                    {self.system: {'WF': s[0], 'FS': s[0], 'U': s[0], 'from_state': s[0], 'owned_by': s[0], 'wf_info_for': s[0]}}, False)
   244                    {self.system: {'WF': s[0], 'FS': s[0], 'U': s[0],
   245 
   245                                   'from_state': s[0], 'owned_by': s[0], 'wf_info_for': s[0],
       
   246                                   'x': s[0]}},
       
   247                    False)
       
   248         
   246     def test_exists4(self):
   249     def test_exists4(self):
   247         """
   250         """
   248         State S could come from both rql source and system source,
   251         State S could come from both rql source and system source,
   249         but since X cannot come from the rql source, the solution
   252         but since X cannot come from the rql source, the solution
   250         {self.rql : 'S'} must be removed
   253         {self.rql : 'S'} must be removed
   267 
   270 
   268     def test_simplified_var(self):
   271     def test_simplified_var(self):
   269         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
   272         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
   270         self._test('Any U WHERE U in_group G, (G name IN ("managers", "logilab") OR (X require_permission P?, P name "bla", P require_group G)), X eid %(x)s, U eid %(u)s',
   273         self._test('Any U WHERE U in_group G, (G name IN ("managers", "logilab") OR (X require_permission P?, P name "bla", P require_group G)), X eid %(x)s, U eid %(u)s',
   271                    {'x': 999999, 'u': self.session.user.eid},
   274                    {'x': 999999, 'u': self.session.user.eid},
   272                    {self.system: {'P': s[0], 'G': s[0], 'X': s[0], 'require_permission': s[0], 'in_group': s[0], 'P': s[0], 'require_group': s[0]}}, False)
   275                    {self.system: {'P': s[0], 'G': s[0], 'X': s[0],
       
   276                                   'require_permission': s[0], 'in_group': s[0], 'P': s[0], 'require_group': s[0],
       
   277                                   'u': s[0]}},
       
   278                    False)
   273         
   279         
   274     def test_delete_relation1(self):
   280     def test_delete_relation1(self):
   275         ueid = self.session.user.eid
   281         ueid = self.session.user.eid
   276         self._test('Any X, Y WHERE X created_by Y, X eid %(x)s, NOT Y eid %(y)s',
   282         self._test('Any X, Y WHERE X created_by Y, X eid %(x)s, NOT Y eid %(y)s',
   277                    {'x': ueid, 'y': ueid},
   283                    {'x': ueid, 'y': ueid},
   278                    {self.system: {'Y': s[0], 'created_by': s[0]}}, False)
   284                    {self.system: {'Y': s[0], 'created_by': s[0], 'x': s[0]}}, False)
       
   285 
       
   286     def test_crossed_relation_eid_1_needattr(self):
       
   287         repo._type_source_cache[999999] = ('Note', 'system', 999999)
       
   288         ueid = self.session.user.eid
       
   289         self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T',
       
   290                    {'x': 999999,},
       
   291                    {self.rql: {'Y': s[0]}, self.system: {'Y': s[0], 'x': s[0]}}, True)
       
   292         
       
   293     def test_crossed_relation_eid_1_invariant(self):
       
   294         repo._type_source_cache[999999] = ('Note', 'system', 999999)
       
   295         self._test('Any Y WHERE X eid %(x)s, X multisource_crossed_rel Y',
       
   296                    {'x': 999999},
       
   297                    {self.system: {'Y': s[0], 'x': s[0]}}, False)
       
   298 
       
   299     def test_crossed_relation_eid_2_invariant(self):
       
   300         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
       
   301         self._test('Any Y WHERE X eid %(x)s, X multisource_crossed_rel Y',
       
   302                    {'x': 999999,},
       
   303                    {self.rql: {'Y': s[0], 'multisource_crossed_rel': s[0], 'x': s[0]},
       
   304                     self.system: {'Y': s[0], 'multisource_crossed_rel': s[0], 'x': s[0]}},
       
   305                    False)
       
   306 
       
   307     def test_version_crossed_depends_on_1(self):
       
   308         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
       
   309         self._test('Any X,AD,AE WHERE E eid %(x)s, E multisource_crossed_rel X, X in_state AD, AD name AE',
       
   310                    {'x': 999999},
       
   311                    {self.rql: {'X': s[0], 'AD': s[0], 'multisource_crossed_rel': s[0], 'x': s[0]},
       
   312                     self.system: {'X': s[0], 'AD': s[0], 'multisource_crossed_rel': s[0], 'x': s[0]}},
       
   313                    True)
   279                    
   314                    
   280 
   315 
   281         
   316         
   282 class MSPlannerTC(BaseMSPlannerTC):
   317 class MSPlannerTC(BaseMSPlannerTC):
   283     
   318     
  1140         # all states (eg from both sources) which are not related to entity with the
  1175         # all states (eg from both sources) which are not related to entity with the
  1141         # given eid. The "NOT X in_state S, X eid %(x)s" expression is necessarily true
  1176         # given eid. The "NOT X in_state S, X eid %(x)s" expression is necessarily true
  1142         # in the source where %(x)s is not coming from and will be removed during rql
  1177         # in the source where %(x)s is not coming from and will be removed during rql
  1143         # generation for the external source
  1178         # generation for the external source
  1144         self._test('Any SN WHERE NOT X in_state S, X eid %(x)s, S name SN',
  1179         self._test('Any SN WHERE NOT X in_state S, X eid %(x)s, S name SN',
  1145                    [('OneFetchStep', [('Any SN WHERE NOT 5 in_state S, S name SN, S is State', [{'S': 'State', 'SN': 'String'}])], 
  1180                    [('OneFetchStep', [('Any SN WHERE NOT 5 in_state S, S name SN, S is State',
       
  1181                                        [{'S': 'State', 'SN': 'String'}])], 
  1146                      None, None, [self.rql, self.system], {}, [])],
  1182                      None, None, [self.rql, self.system], {}, [])],
  1147                    {'x': ueid})
  1183                    {'x': ueid})
  1148 
  1184 
  1149     def test_not_relation_no_split_external(self):
  1185     def test_not_relation_no_split_external(self):
  1150         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1186         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1151         # similar to the above test but with an eid coming from the external source
  1187         # similar to the above test but with an eid coming from the external source.
       
  1188         # the same plan may be used, since we won't find any record in the system source
       
  1189         # linking 9999999 to a state 
  1152         self._test('Any SN WHERE NOT X in_state S, X eid %(x)s, S name SN',
  1190         self._test('Any SN WHERE NOT X in_state S, X eid %(x)s, S name SN',
  1153                    [('UnionStep', None, None,
  1191                    [('OneFetchStep', [('Any SN WHERE NOT 999999 in_state S, S name SN, S is State',
  1154                      [('OneFetchStep',
  1192                                        [{'S': 'State', 'SN': 'String'}])], 
  1155                        [('Any SN WHERE NOT 999999 in_state S, S name SN, S is State',
  1193                      None, None, [self.rql, self.system], {}, [])],
  1156                          [{'S': 'State', 'SN': 'String'}])],
       
  1157                        None, None, [self.rql], {},
       
  1158                        []),
       
  1159                       ('OneFetchStep',
       
  1160                        [('Any SN WHERE S name SN, S is State',
       
  1161                          [{'S': 'State', 'SN': 'String'}])],
       
  1162                        None, None, [self.system], {},
       
  1163                        [])]
       
  1164                      )],
       
  1165                    {'x': 999999})
  1194                    {'x': 999999})
  1166 
  1195 
  1167     def test_not_relation_need_split(self):
  1196     def test_not_relation_need_split(self):
  1168         ueid = self.session.user.eid
  1197         ueid = self.session.user.eid
  1169         self._test('Any SN WHERE NOT X in_state S, S name SN',
  1198         self._test('Any SN WHERE NOT X in_state S, S name SN',
  1170                    [('FetchStep', [('Any SN,S WHERE S name SN, S is State', [{'S': 'State', 'SN': 'String'}])],
  1199                    [('FetchStep', [('Any SN,S WHERE S name SN, S is State',
       
  1200                                     [{'S': 'State', 'SN': 'String'}])],
  1171                      [self.rql, self.system], None, {'S': 'table0.C1', 'S.name': 'table0.C0', 'SN': 'table0.C0'},
  1201                      [self.rql, self.system], None, {'S': 'table0.C1', 'S.name': 'table0.C0', 'SN': 'table0.C0'},
  1172                      []),
  1202                      []),
  1173                     ('FetchStep', [('Any X WHERE X is Note', [{'X': 'Note'}])],
  1203                     ('FetchStep', [('Any X WHERE X is Note', [{'X': 'Note'}])],
  1174                      [self.rql, self.system], None, {'X': 'table1.C0'},
  1204                      [self.rql, self.system], None, {'X': 'table1.C0'},
  1175                      []),
  1205                      []),
  1370 
  1400 
  1371     # external source w/ .cross_relations == ['multisource_crossed_rel'] ######
  1401     # external source w/ .cross_relations == ['multisource_crossed_rel'] ######
  1372     
  1402     
  1373     def test_crossed_relation_eid_1_invariant(self):
  1403     def test_crossed_relation_eid_1_invariant(self):
  1374         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1404         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1375         ueid = self.session.user.eid
       
  1376         self._test('Any Y WHERE X eid %(x)s, X multisource_crossed_rel Y',
  1405         self._test('Any Y WHERE X eid %(x)s, X multisource_crossed_rel Y',
  1377                    [('OneFetchStep', [('Any Y WHERE 999999 multisource_crossed_rel Y', [{u'Y': 'Note'}])],
  1406                    [('OneFetchStep', [('Any Y WHERE 999999 multisource_crossed_rel Y', [{u'Y': 'Note'}])],
  1378                       None, None, [self.system], {}, [])
  1407                       None, None, [self.system], {}, [])
  1379                     ],
  1408                     ],
  1380                    {'x': 999999,})
  1409                    {'x': 999999,})
  1381 
  1410 
  1382     def test_crossed_relation_eid_1_needattr(self):
  1411     def test_crossed_relation_eid_1_needattr(self):
  1383         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1412         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1384         ueid = self.session.user.eid
       
  1385         self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T',
  1413         self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T',
  1386                    [('FetchStep', [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])],
  1414                    [('FetchStep', [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])],
  1387                      [self.rql, self.system], None,
  1415                      [self.rql, self.system], None,
  1388                      {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'}, []),
  1416                      {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'}, []),
  1389                     ('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note',
  1417                     ('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note',
  1393                     ],
  1421                     ],
  1394                    {'x': 999999,})
  1422                    {'x': 999999,})
  1395 
  1423 
  1396     def test_crossed_relation_eid_2_invariant(self):
  1424     def test_crossed_relation_eid_2_invariant(self):
  1397         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1425         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1398         ueid = self.session.user.eid
       
  1399         self._test('Any Y WHERE X eid %(x)s, X multisource_crossed_rel Y',
  1426         self._test('Any Y WHERE X eid %(x)s, X multisource_crossed_rel Y',
  1400                    [('OneFetchStep', [('Any Y WHERE 999999 multisource_crossed_rel Y, Y is Note', [{'Y': 'Note'}])],
  1427                    [('OneFetchStep', [('Any Y WHERE 999999 multisource_crossed_rel Y, Y is Note', [{'Y': 'Note'}])],
  1401                       None, None, [self.rql, self.system], {}, [])
  1428                       None, None, [self.rql, self.system], {}, [])
  1402                     ],
  1429                     ],
  1403                    {'x': 999999,})
  1430                    {'x': 999999,})
  1404 
  1431 
  1405     def test_crossed_relation_eid_2_needattr(self):
  1432     def test_crossed_relation_eid_2_needattr_XXXFIXME(self):
  1406         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1433         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1407         ueid = self.session.user.eid
       
  1408         self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T',
  1434         self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T',
  1409                    [('FetchStep', [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])],
  1435                    [('FetchStep', [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])],
  1410                      [self.rql, self.system], None,
  1436                      [self.rql, self.system], None,
  1411                      {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'}, []),
  1437                      {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'}, []),
  1412                     ('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note',
  1438                     ('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note',
  1417                     ],
  1443                     ],
  1418                    {'x': 999999,})
  1444                    {'x': 999999,})
  1419 
  1445 
  1420     def test_crossed_relation_eid_not_1(self):
  1446     def test_crossed_relation_eid_not_1(self):
  1421         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1447         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1422         ueid = self.session.user.eid
       
  1423         self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y',
  1448         self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y',
  1424                    [('FetchStep', [('Any Y WHERE Y is Note', [{'Y': 'Note'}])],
  1449                    [('FetchStep', [('Any Y WHERE Y is Note', [{'Y': 'Note'}])],
  1425                      [self.rql, self.system], None, {'Y': 'table0.C0'}, []),
  1450                      [self.rql, self.system], None, {'Y': 'table0.C0'}, []),
  1426                     ('OneFetchStep', [('Any Y WHERE NOT 999999 multisource_crossed_rel Y, Y is Note',
  1451                     ('OneFetchStep', [('Any Y WHERE NOT 999999 multisource_crossed_rel Y, Y is Note',
  1427                                        [{'Y': 'Note'}])],
  1452                                        [{'Y': 'Note'}])],
  1429                      {'Y': 'table0.C0'},  [])],
  1454                      {'Y': 'table0.C0'},  [])],
  1430                    {'x': 999999,})
  1455                    {'x': 999999,})
  1431 
  1456 
  1432 #     def test_crossed_relation_eid_not_2(self):
  1457 #     def test_crossed_relation_eid_not_2(self):
  1433 #         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1458 #         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1434 #         ueid = self.session.user.eid
       
  1435 #         self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y',
  1459 #         self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y',
  1436 #                    [],
  1460 #                    [],
  1437 #                    {'x': 999999,})
  1461 #                    {'x': 999999,})
  1438 
  1462 
  1439     def test_crossed_relation_base(self):
  1463     def test_crossed_relation_base_XXXFIXME(self):
  1440         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1464         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1441         ueid = self.session.user.eid
       
  1442         self._test('Any X,Y,T WHERE X multisource_crossed_rel Y, Y type T, X type T',
  1465         self._test('Any X,Y,T WHERE X multisource_crossed_rel Y, Y type T, X type T',
  1443                    [('FetchStep', [('Any X,T WHERE X type T, X is Note', [{'T': 'String', 'X': 'Note'}])],
  1466                    [('FetchStep', [('Any X,T WHERE X type T, X is Note', [{'T': 'String', 'X': 'Note'}])],
  1444                      [self.rql, self.system], None,
  1467                      [self.rql, self.system], None,
  1445                      {'T': 'table0.C1', 'X': 'table0.C0', 'X.type': 'table0.C1'}, []),
  1468                      {'T': 'table0.C1', 'X': 'table0.C0', 'X.type': 'table0.C1'}, []),
  1446                     ('FetchStep',  [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])],
  1469                     ('FetchStep',  [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])],
  1766         repo._type_source_cache[999999] = ('EUser', 'ldapuser', 999999)
  1789         repo._type_source_cache[999999] = ('EUser', 'ldapuser', 999999)
  1767         self._test('Any X,AA,AB ORDERBY AA WHERE E eid %(x)s, E owned_by X, X login AA, X modification_date AB',
  1790         self._test('Any X,AA,AB ORDERBY AA WHERE E eid %(x)s, E owned_by X, X login AA, X modification_date AB',
  1768                    [('FetchStep',
  1791                    [('FetchStep',
  1769                      [('Any X,AA,AB WHERE X login AA, X modification_date AB, X is EUser',
  1792                      [('Any X,AA,AB WHERE X login AA, X modification_date AB, X is EUser',
  1770                        [{'AA': 'String', 'AB': 'Datetime', 'X': 'EUser'}])],
  1793                        [{'AA': 'String', 'AB': 'Datetime', 'X': 'EUser'}])],
  1771                      [self.ldap], None, {'AA': 'table0.C1', 'AB': 'table0.C2',
  1794                      [self.ldap, self.system], None, {'AA': 'table0.C1', 'AB': 'table0.C2',
  1772                                          'X': 'table0.C0', 'X.login': 'table0.C1', 'X.modification_date': 'table0.C2'},
  1795                                                       'X': 'table0.C0', 'X.login': 'table0.C1', 'X.modification_date': 'table0.C2'},
  1773                      []),
  1796                      []),
  1774                     ('OneFetchStep',
  1797                     ('OneFetchStep',
  1775                      [('Any X,AA,AB ORDERBY AA WHERE 999999 owned_by X, X login AA, X modification_date AB, X is EUser',
  1798                      [('Any X,AA,AB ORDERBY AA WHERE 999999 owned_by X, X login AA, X modification_date AB, X is EUser',
  1776                        [{'AA': 'String', 'AB': 'Datetime', 'X': 'EUser'}])],
  1799                        [{'AA': 'String', 'AB': 'Datetime', 'X': 'EUser'}])],
  1777                      None, None, [self.system], {'AA': 'table0.C1', 'AB': 'table0.C2',
  1800                      None, None, [self.system], {'AA': 'table0.C1', 'AB': 'table0.C2',
  1797     def test_nonregr12(self):
  1820     def test_nonregr12(self):
  1798         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1821         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1799         self._test('Any X ORDERBY Z DESC WHERE X modification_date Z, E eid %(x)s, E see_also X',
  1822         self._test('Any X ORDERBY Z DESC WHERE X modification_date Z, E eid %(x)s, E see_also X',
  1800                    [('FetchStep', [('Any X,Z WHERE X modification_date Z, X is Note',
  1823                    [('FetchStep', [('Any X,Z WHERE X modification_date Z, X is Note',
  1801                                     [{'X': 'Note', 'Z': 'Datetime'}])],
  1824                                     [{'X': 'Note', 'Z': 'Datetime'}])],
  1802                      [self.rql], None, {'X': 'table0.C0', 'X.modification_date': 'table0.C1', 'Z': 'table0.C1'},
  1825                      [self.rql, self.system], None, {'X': 'table0.C0', 'X.modification_date': 'table0.C1', 'Z': 'table0.C1'},
  1803                      []),
  1826                      []),
  1804                     ('AggrStep', 'Any X ORDERBY Z DESC',
  1827                     ('AggrStep', 'Any X ORDERBY Z DESC',
  1805                      None, None, 'table1', None,
  1828                      None, None, 'table1', None,
  1806                      [('FetchStep', [('Any X,Z WHERE X modification_date Z, 999999 see_also X, X is Bookmark',
  1829                      [('FetchStep', [('Any X,Z WHERE X modification_date Z, 999999 see_also X, X is Bookmark',
  1807                                       [{'X': 'Bookmark', 'Z': 'Datetime'}])],
  1830                                       [{'X': 'Bookmark', 'Z': 'Datetime'}])],
  1879 
  1902 
  1880 
  1903 
  1881 class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
  1904 class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
  1882     """test planner related feature on a 3-sources repository:
  1905     """test planner related feature on a 3-sources repository:
  1883     
  1906     
  1884     * 2 rql source supporting Card
  1907     * 2 rql sources supporting Card
  1885     """
  1908     """
  1886     repo = repo
  1909     repo = repo
  1887     
  1910     
  1888     def setUp(self):
  1911     def setUp(self):
  1889         #_QuerierTC.setUp(self)
       
  1890         self.o = repo.querier
  1912         self.o = repo.querier
  1891         self.session = repo._sessions.values()[0]
  1913         self.session = repo._sessions.values()[0]
  1892         self.pool = self.session.set_pool()
  1914         self.pool = self.session.set_pool()
  1893         self.schema = self.o.schema
  1915         self.schema = self.o.schema
  1894         self.sources = self.o._repo.sources
  1916         self.sources = self.o._repo.sources
  1901                                            {'uri': 'cards2'}))
  1923                                            {'uri': 'cards2'}))
  1902         repo.sources_by_uri['cards2'] = self.sources[-1]
  1924         repo.sources_by_uri['cards2'] = self.sources[-1]
  1903         self.rql2 = self.sources[-1]
  1925         self.rql2 = self.sources[-1]
  1904         do_monkey_patch()
  1926         do_monkey_patch()
  1905         self.planner = MSPlanner(self.o.schema, self.o._rqlhelper)
  1927         self.planner = MSPlanner(self.o.schema, self.o._rqlhelper)
  1906 
  1928         assert repo.sources_by_uri['cards2'].support_relation('multisource_crossed_rel')
       
  1929         assert 'multisource_crossed_rel' in repo.sources_by_uri['cards2'].cross_relations
       
  1930         assert repo.sources_by_uri['cards'].support_relation('multisource_crossed_rel')
       
  1931         assert 'multisource_crossed_rel' in repo.sources_by_uri['cards'].cross_relations
  1907     _test = test_plan
  1932     _test = test_plan
  1908         
  1933         
  1909     def tearDown(self):
  1934     def tearDown(self):
  1910         undo_monkey_patch()
  1935         undo_monkey_patch()
  1911         del self.sources[-1]
  1936         del self.sources[-1]
  1926                        [{'X': 'Card', 'XT': 'String'}])],
  1951                        [{'X': 'Card', 'XT': 'String'}])],
  1927                      None, None, [self.system],
  1952                      None, None, [self.system],
  1928                      {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'},
  1953                      {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'},
  1929                      [])],
  1954                      [])],
  1930                    {'t': 999999})
  1955                    {'t': 999999})
  1931  
  1956 
       
  1957     def test_version_depends_on(self):
       
  1958         self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
       
  1959         self._test('Any X,AD,AE WHERE E eid %(x)s, E migrated_from X, X in_state AD, AD name AE',
       
  1960                    [('FetchStep', [('Any X,AD,AE WHERE X in_state AD, AD name AE, AD is State, X is Note',
       
  1961                                     [{'AD': 'State', 'AE': 'String', 'X': 'Note'}])],
       
  1962                      [self.rql, self.rql2, self.system],
       
  1963                      None, {'AD': 'table0.C1', 'AD.name': 'table0.C2',
       
  1964                             'AE': 'table0.C2', 'X': 'table0.C0'},
       
  1965                      []),
       
  1966                     ('OneFetchStep', [('Any X,AD,AE WHERE 999999 migrated_from X, AD name AE, AD is State, X is Note',
       
  1967                                        [{'AD': 'State', 'AE': 'String', 'X': 'Note'}])],
       
  1968                      None, None, [self.system],
       
  1969                      {'AD': 'table0.C1', 'AD.name': 'table0.C2', 'AE': 'table0.C2', 'X': 'table0.C0'},
       
  1970                      [])],
       
  1971                    {'x': 999999})
       
  1972 
       
  1973     def test_version_crossed_depends_on_1(self):
       
  1974         self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
       
  1975         self._test('Any X,AD,AE WHERE E eid %(x)s, E multisource_crossed_rel X, X in_state AD, AD name AE',
       
  1976                        [('FetchStep', [('Any X,AD,AE WHERE X in_state AD, AD name AE, AD is State, X is Note',
       
  1977                                         [{'AD': 'State', 'AE': 'String', 'X': 'Note'}])],
       
  1978                          [self.rql, self.rql2, self.system],
       
  1979                          None, {'AD': 'table0.C1', 'AD.name': 'table0.C2',
       
  1980                                 'AE': 'table0.C2', 'X': 'table0.C0'},
       
  1981                          []),
       
  1982                         ('FetchStep', [('Any X WHERE 999999 multisource_crossed_rel X, X is Note',
       
  1983                                         [{'X': 'Note'}])],
       
  1984                          [self.rql, self.system], None, {'X': 'table1.C0'},
       
  1985                          []),
       
  1986                         ('OneFetchStep', [('Any X,AD,AE WHERE AD name AE, AD is State, X is Note, X identity A',
       
  1987                                            [{'A': 'Note', 'AD': 'State', 'AE': 'String', 'X': 'Note'}])],
       
  1988                          None, None, [self.system],
       
  1989                          {'A': 'table0.C0', 'AD': 'table0.C1', 'AD.name': 'table0.C2',
       
  1990                           'AE': 'table0.C2', 'X': 'table1.C0'},
       
  1991                          [])],
       
  1992                        {'x': 999999})
       
  1993 
       
  1994     def test_version_crossed_depends_on_2_XXXFIXME(self):
       
  1995         self.repo._type_source_cache[999999] = ('Note', 'system', 999999)
       
  1996         self._test('Any X,AD,AE WHERE E eid %(x)s, E multisource_crossed_rel X, X in_state AD, AD name AE',
       
  1997                    [],
       
  1998                    {'x': 999999})
       
  1999 
       
  2000     def test_version_crossed_depends_on_3_XXXFIXME(self):
       
  2001         self._test('Any X,AD,AE WHERE E multisource_crossed_rel X, X in_state AD, AD name AE, E is Note',
       
  2002                    [])
       
  2003 
       
  2004 
  1932 if __name__ == '__main__':
  2005 if __name__ == '__main__':
  1933     from logilab.common.testlib import unittest_main
  2006     from logilab.common.testlib import unittest_main
  1934     unittest_main()
  2007     unittest_main()