server/test/unittest_msplanner.py
changeset 6139 f76599a96238
parent 6081 ede33e6400ab
parent 6131 087c5a168010
child 6225 a176e68b7d0d
equal deleted inserted replaced
6102:27c47d239739 6139:f76599a96238
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    14 # details.
    14 # details.
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    18 
       
    19 from logilab.common.decorators import clear_cache
       
    20 
    18 from cubicweb.devtools import init_test_database
    21 from cubicweb.devtools import init_test_database
    19 from cubicweb.devtools.repotest import BasePlannerTC, test_plan
    22 from cubicweb.devtools.repotest import BasePlannerTC, test_plan
    20 
    23 
    21 class _SetGenerator(object):
    24 class _SetGenerator(object):
    22     """singleton to easily create set using "s[0]" or "s[0,1,2]" for instance
    25     """singleton to easily create set using "s[0]" or "s[0,1,2]" for instance
    43 
    46 
    44 class FakeCardSource(AbstractSource):
    47 class FakeCardSource(AbstractSource):
    45     uri = 'ccc'
    48     uri = 'ccc'
    46     support_entities = {'Card': True, 'Note': True, 'State': True}
    49     support_entities = {'Card': True, 'Note': True, 'State': True}
    47     support_relations = {'in_state': True, 'multisource_rel': True, 'multisource_inlined_rel': True,
    50     support_relations = {'in_state': True, 'multisource_rel': True, 'multisource_inlined_rel': True,
    48                          'multisource_crossed_rel': True}
    51                          'multisource_crossed_rel': True,}
    49     dont_cross_relations = set(('fiche', 'state_of'))
    52     dont_cross_relations = set(('fiche', 'state_of'))
    50     cross_relations = set(('multisource_crossed_rel',))
    53     cross_relations = set(('multisource_crossed_rel',))
    51 
    54 
    52     def syntax_tree_search(self, *args, **kwargs):
    55     def syntax_tree_search(self, *args, **kwargs):
    53         return []
    56         return []
   362 class MSPlannerTC(BaseMSPlannerTC):
   365 class MSPlannerTC(BaseMSPlannerTC):
   363 
   366 
   364     def setUp(self):
   367     def setUp(self):
   365         BaseMSPlannerTC.setUp(self)
   368         BaseMSPlannerTC.setUp(self)
   366         self.planner = MSPlanner(self.o.schema, self.repo.vreg.rqlhelper)
   369         self.planner = MSPlanner(self.o.schema, self.repo.vreg.rqlhelper)
       
   370         for cached in ('rel_type_sources', 'can_cross_relation', 'is_multi_sources_relation'):
       
   371             clear_cache(self.repo, cached)
   367 
   372 
   368     _test = test_plan
   373     _test = test_plan
   369 
   374 
   370     def test_simple_system_only(self):
   375     def test_simple_system_only(self):
   371         """retrieve entities only supported by the system source
   376         """retrieve entities only supported by the system source
  1024                     ('FetchStep',
  1029                     ('FetchStep',
  1025                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
  1030                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
  1026                      [self.cards, self.system], None, {'X': 'table1.C0', 'X.title': 'table1.C1', 'XT': 'table1.C1'}, []),
  1031                      [self.cards, self.system], None, {'X': 'table1.C0', 'X.title': 'table1.C1', 'XT': 'table1.C1'}, []),
  1027                     ('OneFetchStep',
  1032                     ('OneFetchStep',
  1028                      [('Any X,XT,U WHERE X owned_by U?, X title XT, X is Card',
  1033                      [('Any X,XT,U WHERE X owned_by U?, X title XT, X is Card',
  1029                        [{'X': 'Card', 'XT': 'String'}])],
  1034                        [{'X': 'Card', 'U': 'CWUser', 'XT': 'String'}])],
  1030                      None, None, [self.system], {'L': 'table0.C1',
  1035                      None, None, [self.system], {'L': 'table0.C1',
  1031                                                  'U': 'table0.C0',
  1036                                                  'U': 'table0.C0',
  1032                                                  'X': 'table1.C0',
  1037                                                  'X': 'table1.C0',
  1033                                                  'X.title': 'table1.C1',
  1038                                                  'X.title': 'table1.C1',
  1034                                                  'XT': 'table1.C1'}, [])
  1039                                                  'XT': 'table1.C1'}, [])
  1434                                     [{'T': 'String', 'X': 'Bookmark'}])],
  1439                                     [{'T': 'String', 'X': 'Bookmark'}])],
  1435                      [self.system], {}, {'N': 'table0.C1', 'X': 'table0.C0', 'X.name': 'table0.C1'}, []),
  1440                      [self.system], {}, {'N': 'table0.C1', 'X': 'table0.C0', 'X.name': 'table0.C1'}, []),
  1436                     ('FetchStep',
  1441                     ('FetchStep',
  1437                      [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
  1442                      [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
  1438                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
  1443                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
  1439                     ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser',
  1444                     ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser, A is IN(Bookmark, Tag)',
  1440                                        [{'A': 'Bookmark', 'B': 'CWUser', 'C': 'String'},
  1445                                        [{'A': 'Bookmark', 'B': 'CWUser', 'C': 'String'},
  1441                                         {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
  1446                                         {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
  1442                      None, None, [self.system],
  1447                      None, None, [self.system],
  1443                      {'A': 'table0.C0',
  1448                      {'A': 'table0.C0',
  1444                       'B': 'table1.C0', 'B.login': 'table1.C1',
  1449                       'B': 'table1.C0', 'B.login': 'table1.C1',
  1468                         'X.title': 'table0.C1'}, []),
  1473                         'X.title': 'table0.C1'}, []),
  1469                       ]),
  1474                       ]),
  1470                     ('FetchStep',
  1475                     ('FetchStep',
  1471                      [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
  1476                      [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
  1472                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
  1477                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
  1473                     ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser',
  1478                     ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser, A is IN(Card, Tag)',
  1474                                        [{'A': 'Card', 'B': 'CWUser', 'C': 'String'},
  1479                                        [{'A': 'Card', 'B': 'CWUser', 'C': 'String'},
  1475                                         {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
  1480                                         {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
  1476                      None, None, [self.system],
  1481                      None, None, [self.system],
  1477                      {'A': 'table0.C0',
  1482                      {'A': 'table0.C0',
  1478                       'B': 'table1.C0', 'B.login': 'table1.C1',
  1483                       'B': 'table1.C0', 'B.login': 'table1.C1',
  1534                    {'x': 999999,})
  1539                    {'x': 999999,})
  1535 
  1540 
  1536     def test_crossed_relation_eid_2_needattr(self):
  1541     def test_crossed_relation_eid_2_needattr(self):
  1537         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1542         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1538         self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T',
  1543         self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T',
  1539                    [('FetchStep', [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])],
  1544                    [('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note',
  1540                      [self.cards, self.system], None,
  1545                                        [{'T': 'String', 'Y': 'Note'}])],
  1541                      {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'}, []),
  1546                      None, None, [self.cards, self.system], {},
  1542                     ('UnionStep', None, None,
  1547                      []),
  1543                      [('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note',
  1548                     ],
  1544                                          [{'T': 'String', 'Y': 'Note'}])],
       
  1545                        None, None, [self.cards], None,
       
  1546                        []),
       
  1547                       ('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note',
       
  1548                                          [{'T': 'String', 'Y': 'Note'}])],
       
  1549                        None, None, [self.system],
       
  1550                        {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'},
       
  1551                        [])]
       
  1552                      )],
       
  1553                    {'x': 999999,})
  1549                    {'x': 999999,})
  1554 
  1550 
  1555     def test_crossed_relation_eid_not_1(self):
  1551     def test_crossed_relation_eid_not_1(self):
  1556         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1552         repo._type_source_cache[999999] = ('Note', 'system', 999999)
  1557         self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y',
  1553         self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y',
  1754 #                        ('OneFetchStep', [('DISTINCT Any X,%s WHERE X is CWUser' % activatedeid,
  1750 #                        ('OneFetchStep', [('DISTINCT Any X,%s WHERE X is CWUser' % activatedeid,
  1755 #                                           [{'X': 'CWUser'}])],
  1751 #                                           [{'X': 'CWUser'}])],
  1756 #                         None, None, [self.system], {}, []),
  1752 #                         None, None, [self.system], {}, []),
  1757 #                        ]),
  1753 #                        ]),
  1758 #                     ])
  1754 #                     ])
       
  1755 
       
  1756     def test_ldap_user_related_to_invariant_and_dont_cross_rel(self):
       
  1757         self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
       
  1758         self.cards.dont_cross_relations.add('created_by')
       
  1759         try:
       
  1760             self._test('Any X,XL WHERE E eid %(x)s, E created_by X, X login XL',
       
  1761                    [('FetchStep', [('Any X,XL WHERE X login XL, X is CWUser',
       
  1762                                     [{'X': 'CWUser', 'XL': 'String'}])],
       
  1763                      [self.ldap, self.system], None,
       
  1764                      {'X': 'table0.C0', 'X.login': 'table0.C1', 'XL': 'table0.C1'},
       
  1765                      []),
       
  1766                     ('OneFetchStep',
       
  1767                      [('Any X,XL WHERE 999999 created_by X, X login XL, X is CWUser',
       
  1768                        [{'X': 'CWUser', 'XL': 'String'}])],
       
  1769                      None, None,
       
  1770                      [self.system],
       
  1771                      {'X': 'table0.C0', 'X.login': 'table0.C1', 'XL': 'table0.C1'},
       
  1772                      [])],
       
  1773                        {'x': 999999})
       
  1774         finally:
       
  1775             self.cards.dont_cross_relations.remove('created_by')
       
  1776 
       
  1777     def test_ambigous_cross_relation(self):
       
  1778         self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
       
  1779         self.cards.support_relations['see_also'] = True
       
  1780         self.cards.cross_relations.add('see_also')
       
  1781         try:
       
  1782             self._test('Any X,AA ORDERBY AA WHERE E eid %(x)s, E see_also X, X modification_date AA',
       
  1783                        [('AggrStep',
       
  1784                          'SELECT table0.C0, table0.C1 FROM table0 ORDER BY table0.C1',
       
  1785                          None,
       
  1786                          [('FetchStep',
       
  1787                            [('Any X,AA WHERE 999999 see_also X, X modification_date AA, X is Note',
       
  1788                              [{'AA': 'Datetime', 'X': 'Note'}])], [self.cards, self.system], {},
       
  1789                            {'AA': 'table0.C1', 'X': 'table0.C0',
       
  1790                             'X.modification_date': 'table0.C1'},
       
  1791                            []),
       
  1792                           ('FetchStep',
       
  1793                            [('Any X,AA WHERE 999999 see_also X, X modification_date AA, X is Bookmark',
       
  1794                              [{'AA': 'Datetime', 'X': 'Bookmark'}])],
       
  1795                            [self.system], {},
       
  1796                            {'AA': 'table0.C1', 'X': 'table0.C0',
       
  1797                             'X.modification_date': 'table0.C1'},
       
  1798                            [])])],
       
  1799                          {'x': 999999})
       
  1800         finally:
       
  1801             del self.cards.support_relations['see_also']
       
  1802             self.cards.cross_relations.remove('see_also')
  1759 
  1803 
  1760     # non regression tests ####################################################
  1804     # non regression tests ####################################################
  1761 
  1805 
  1762     def test_nonregr1(self):
  1806     def test_nonregr1(self):
  1763         self._test('Any X, Y WHERE X copain Y, X login "syt", Y login "cochon"',
  1807         self._test('Any X, Y WHERE X copain Y, X login "syt", Y login "cochon"',
  1871                    {'n': 999999})
  1915                    {'n': 999999})
  1872 
  1916 
  1873     def test_nonregr8(self):
  1917     def test_nonregr8(self):
  1874         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1918         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1875         self._test('Any X,Z WHERE X eid %(x)s, X multisource_rel Y, Z concerne X',
  1919         self._test('Any X,Z WHERE X eid %(x)s, X multisource_rel Y, Z concerne X',
  1876                    [('FetchStep', [('Any  WHERE 999999 multisource_rel Y, Y is Note', [{'Y': 'Note'}])],
  1920                    [('FetchStep', [('Any 999999 WHERE 999999 multisource_rel Y, Y is Note',
  1877                      [self.cards], None, {}, []),
  1921                                     [{'Y': 'Note'}])],
       
  1922                      [self.cards],
       
  1923                      None, {u'%(x)s': 'table0.C0'},
       
  1924                      []),
  1878                     ('OneFetchStep', [('Any 999999,Z WHERE Z concerne 999999, Z is Affaire',
  1925                     ('OneFetchStep', [('Any 999999,Z WHERE Z concerne 999999, Z is Affaire',
  1879                                        [{'Z': 'Affaire'}])],
  1926                                        [{'Z': 'Affaire'}])],
  1880                      None, None, [self.system], {}, [])],
  1927                      None, None, [self.system],
       
  1928                      {u'%(x)s': 'table0.C0'}, []),
       
  1929                     ],
  1881                    {'x': 999999})
  1930                    {'x': 999999})
  1882 
  1931 
  1883     def test_nonregr9(self):
  1932     def test_nonregr9(self):
  1884         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1933         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
  1885         repo._type_source_cache[999998] = ('Note', 'cards', 999998)
  1934         repo._type_source_cache[999998] = ('Note', 'cards', 999998)