cubicweb/devtools/repotest.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 06 Oct 2017 16:59:10 +0200
changeset 12206 cfd25da225c2
parent 12125 1d3a9bb46339
child 12235 03b94c9863de
permissions -rw-r--r--
[test] Pin some test dependencies We currently have CI failures because cubes used as test dependencies have been updated to new-style cube layout. To avoid this, pin them to previous released. Those dependencies should be removed but in the mean time this should be enough (and backported in all active branches).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
     1
# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
"""some utilities to ease repository testing
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
This module contains functions to initialize a new repository.
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    21
"""
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10365
diff changeset
    22
from __future__ import print_function
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
12039
7514626e1dc5 [session+test] Stop storing / accessing session when it's not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12035
diff changeset
    24
from contextlib import contextmanager
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
from pprint import pprint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
6818
5fa425574548 [server test] can't use skipTest method as a class method, raise appropriate exception instead
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6804
diff changeset
    27
from logilab.common.testlib import SkipTest
2074
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
    28
11203
e5d065f612e8 [devtools/repotest] use the RepoAccess object
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 11076
diff changeset
    29
from cubicweb.devtools.testlib import RepoAccess
12040
e9682629df57 [test] Use user_session_cache_key function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12039
diff changeset
    30
from cubicweb.entities.authobjs import user_session_cache_key
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
    31
9835
5ad968dd9d51 [devtools/repotest] simplify a very small helper
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9834
diff changeset
    32
def tuplify(mylist):
5ad968dd9d51 [devtools/repotest] simplify a very small helper
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9834
diff changeset
    33
    return [tuple(item) for item in mylist]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
    35
10711
d7f009a3b960 [py3k] replace cmp with key in sorted()
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
    36
def snippet_key(a):
d7f009a3b960 [py3k] replace cmp with key in sorted()
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
    37
    # a[0] may be a dict or a key/value tuple
d7f009a3b960 [py3k] replace cmp with key in sorted()
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
    38
    return (sorted(dict(a[0]).items()), [e.expression for e in a[1]])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
    40
11250
597f02c5cf5a [tox] Use py.test to run tests
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11237
diff changeset
    41
def check_plan(self, rql, expected, kwargs=None):
12055
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
    42
    with self.admin_access.cnx() as cnx:
9834
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    43
        plan = self._prepare_plan(cnx, rql, kwargs)
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    44
        self.planner.build_plan(plan)
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    45
        try:
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    46
            self.assertEqual(len(plan.steps), len(expected),
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
    47
                             'expected %s steps, got %s' % (len(expected), len(plan.steps)))
9834
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    48
            # step order is important
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    49
            for i, step in enumerate(plan.steps):
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    50
                compare_steps(self, step.test_repr(), expected[i])
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    51
        except AssertionError:
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    52
            pprint([step.test_repr() for step in plan.steps])
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
    53
            raise
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
    55
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
def compare_steps(self, step, expected):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
    try:
6369
a151453dc564 [test] more update to unittest2 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
    58
        self.assertEqual(step[0], expected[0], 'expected step type %s, got %s' % (expected[0], step[0]))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        if len(step) > 2 and isinstance(step[1], list) and isinstance(expected[1], list):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
            queries, equeries = step[1], expected[1]
6369
a151453dc564 [test] more update to unittest2 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
    61
            self.assertEqual(len(queries), len(equeries),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
                              'expected %s queries, got %s' % (len(equeries), len(queries)))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
            for i, (rql, sol) in enumerate(queries):
6369
a151453dc564 [test] more update to unittest2 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
    64
                self.assertEqual(rql, equeries[i][0])
10821
107b87bbbaa7 [devtools] more sorted() vs dict vs python3
Julien Cristau <julien.cristau@logilab.fr>
parents: 10804
diff changeset
    65
                self.assertEqual(sorted(sorted(x.items()) for x in sol), sorted(sorted(x.items()) for x in equeries[i][1]))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
            idx = 2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
            idx = 1
6369
a151453dc564 [test] more update to unittest2 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
    69
        self.assertEqual(step[idx:-1], expected[idx:-1],
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
                          'expected step characteristic \n%s\n, got\n%s' % (expected[1:-1], step[1:-1]))
6369
a151453dc564 [test] more update to unittest2 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
    71
        self.assertEqual(len(step[-1]), len(expected[-1]),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
                          'got %s child steps, expected %s' % (len(step[-1]), len(expected[-1])))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
    except AssertionError:
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10365
diff changeset
    74
        print('error on step ', end=' ')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        pprint(step[:-1])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        raise
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
    children = step[-1]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
    if step[0] in ('UnionFetchStep', 'UnionStep'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
        # sort children
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        children = sorted(children)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
        expectedchildren = sorted(expected[-1])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
        expectedchildren = expected[-1]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    for i, substep in enumerate(children):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
        compare_steps(self, substep, expectedchildren[i])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
class DumbOrderedDict(list):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    def __iter__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
        return self.iterkeys()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    def __contains__(self, key):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        return key in self.iterkeys()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    def __getitem__(self, key):
1236
aeb46e43138d fix choose_term monkey-patching
sylvain.thenault@logilab.fr
parents: 1235
diff changeset
    94
        for key_, value in list.__iter__(self):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
            if key == key_:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
                return value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        raise KeyError(key)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    def iterkeys(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        return (x for x, y in list.__iter__(self))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
    def iteritems(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        return (x for x in list.__iter__(self))
1236
aeb46e43138d fix choose_term monkey-patching
sylvain.thenault@logilab.fr
parents: 1235
diff changeset
   102
    def items(self):
aeb46e43138d fix choose_term monkey-patching
sylvain.thenault@logilab.fr
parents: 1235
diff changeset
   103
        return [x for x in list.__iter__(self)]
aeb46e43138d fix choose_term monkey-patching
sylvain.thenault@logilab.fr
parents: 1235
diff changeset
   104
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
4766
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   106
def schema_eids_idx(schema):
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   107
    """return a dictionary mapping schema types to their eids so we can reread
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   108
    it from the fs instead of the db (too costly) between tests
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   109
    """
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   110
    schema_eids = {}
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   111
    for x in schema.entities():
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   112
        schema_eids[x] = x.eid
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   113
    for x in schema.relations():
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   114
        schema_eids[x] = x.eid
10663
54b8a1f249fb [py3k] dict.itervalues → dict.values
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
   115
        for rdef in x.rdefs.values():
4766
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   116
            schema_eids[(rdef.subject, rdef.rtype, rdef.object)] = rdef.eid
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   117
    return schema_eids
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   118
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   119
def restore_schema_eids_idx(schema, schema_eids):
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   120
    """rebuild schema eid index"""
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   121
    for x in schema.entities():
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   122
        x.eid = schema_eids[x]
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   123
        schema._eid_index[x.eid] = x
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   124
    for x in schema.relations():
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   125
        x.eid = schema_eids[x]
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   126
        schema._eid_index[x.eid] = x
10663
54b8a1f249fb [py3k] dict.itervalues → dict.values
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
   127
        for rdef in x.rdefs.values():
4766
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   128
            rdef.eid = schema_eids[(rdef.subject, rdef.rtype, rdef.object)]
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   129
            schema._eid_index[rdef.eid] = rdef
162b2b127b15 [test] get a chance to get proper garbage collection when running pytest on whole cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4674
diff changeset
   130
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   132
from logilab.common.testlib import TestCase, mock_object
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   133
from logilab.database import get_db_helper
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   134
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
from rql import RQLHelper
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   136
11076
403a901b6b1e [devtools] Re-implement generative tests using subtests
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11057
diff changeset
   137
from cubicweb.devtools.testlib import BaseTestCase
12035
2fcb9339f69a [devtools] Rename FakeSession into FakeConnection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12024
diff changeset
   138
from cubicweb.devtools.fake import FakeRepo, FakeConfig, FakeRequest, FakeConnection
6758
28b11ecf319b [ms] #1382452: incorrect results with multi-sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6671
diff changeset
   139
from cubicweb.server import set_debug, debugged
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
from cubicweb.server.querier import QuerierHelper
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   141
from cubicweb.server.sources.rql2sql import SQLGenerator, remove_unused_solutions
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
11076
403a901b6b1e [devtools] Re-implement generative tests using subtests
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11057
diff changeset
   143
class RQLGeneratorTC(BaseTestCase):
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7850
diff changeset
   144
    schema = backend = None # set this in concrete class
6804
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   145
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   146
    @classmethod
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   147
    def setUpClass(cls):
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   148
        if cls.backend is not None:
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   149
            try:
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   150
                cls.dbhelper = get_db_helper(cls.backend)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8544
diff changeset
   151
            except ImportError as ex:
6818
5fa425574548 [server test] can't use skipTest method as a class method, raise appropriate exception instead
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6804
diff changeset
   152
                raise SkipTest(str(ex))
6804
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   153
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
    def setUp(self):
9460
a2a0bc984863 [config] cleanup/refactor server sources file values handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9456
diff changeset
   155
        self.repo = FakeRepo(self.schema, config=FakeConfig(apphome=self.datadir))
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   156
        self.repo.system_source = mock_object(dbdriver=self.backend)
9850
5ef9dd383ae2 [tests/rqlannotation,querier] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9835
diff changeset
   157
        self.rqlhelper = RQLHelper(self.schema,
5ef9dd383ae2 [tests/rqlannotation,querier] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9835
diff changeset
   158
                                   special_relations={'eid': 'uid',
5ef9dd383ae2 [tests/rqlannotation,querier] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9835
diff changeset
   159
                                                      'has_text': 'fti'},
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   160
                                   backend=self.backend)
3240
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2200
diff changeset
   161
        self.qhelper = QuerierHelper(self.repo, self.schema)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        ExecutionPlan._check_permissions = _dummy_check_permissions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
        rqlannotation._select_principal = _select_principal
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   164
        if self.backend is not None:
6804
4262d0d6abcb unittest2 fix: can't skip test in setUp, but it's fine in setUpClass
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6794
diff changeset
   165
            self.o = SQLGenerator(self.schema, self.dbhelper)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
    def tearDown(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        ExecutionPlan._check_permissions = _orig_check_permissions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
        rqlannotation._select_principal = _orig_select_principal
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2074
diff changeset
   170
2069
7c0a1b90b1c6 set_debug method on rql2sql test as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   171
    def set_debug(self, debug):
7c0a1b90b1c6 set_debug method on rql2sql test as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   172
        set_debug(debug)
6758
28b11ecf319b [ms] #1382452: incorrect results with multi-sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6671
diff changeset
   173
    def debugged(self, debug):
28b11ecf319b [ms] #1382452: incorrect results with multi-sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6671
diff changeset
   174
        return debugged(debug)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1789
diff changeset
   175
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
    def _prepare(self, rql):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        #print '******************** prepare', rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
        union = self.rqlhelper.parse(rql)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
        #print '********* parsed', union.as_string()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
        self.rqlhelper.compute_solutions(union)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        #print '********* solutions', solutions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
        self.rqlhelper.simplify(union)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
        #print '********* simplified', union.as_string()
12035
2fcb9339f69a [devtools] Rename FakeSession into FakeConnection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12024
diff changeset
   184
        plan = self.qhelper.plan_factory(union, {}, FakeConnection(self.repo))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        plan.preprocess(union)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        for select in union.children:
10804
ee113e1e03de [devtools] pass a key to sort() method
Julien Cristau <julien.cristau@logilab.fr>
parents: 10747
diff changeset
   187
            select.solutions.sort(key=lambda x: list(x.items()))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
        #print '********* ppsolutions', solutions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        return union
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
class BaseQuerierTC(TestCase):
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7850
diff changeset
   193
    repo = None # set this in concrete class
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1789
diff changeset
   194
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    def setUp(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        self.o = self.repo.querier
12055
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
   197
        self.admin_access = RepoAccess(self.repo, 'admin', FakeRequest)
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
   198
        self.ueid = self.admin_access._user.eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        assert self.ueid != -1
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   200
        self.repo._type_cache = {} # clear cache
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
        self.maxeid = self.get_max_eid()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        do_monkey_patch()
4773
6ab9ca63531f [testlib] properly close dumb sessions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4766
diff changeset
   203
        self._dumb_sessions = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
    def get_max_eid(self):
12055
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
   206
        with self.admin_access.cnx() as cnx:
9833
1485aab7ece6 [tests/querier] use the new connection api (part 3/3)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9831
diff changeset
   207
            return cnx.execute('Any MAX(X)')[0][0]
1485aab7ece6 [tests/querier] use the new connection api (part 3/3)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9831
diff changeset
   208
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
    def cleanup(self):
12055
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
   210
        with self.admin_access.cnx() as cnx:
9833
1485aab7ece6 [tests/querier] use the new connection api (part 3/3)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9831
diff changeset
   211
            cnx.execute('DELETE Any X WHERE X eid > %s' % self.maxeid)
1485aab7ece6 [tests/querier] use the new connection api (part 3/3)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9831
diff changeset
   212
            cnx.commit()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1789
diff changeset
   213
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
    def tearDown(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
        undo_monkey_patch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        self.cleanup()
12055
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
   217
        assert self.admin_access._user.eid != -1
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
    def set_debug(self, debug):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        set_debug(debug)
6758
28b11ecf319b [ms] #1382452: incorrect results with multi-sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6671
diff changeset
   221
    def debugged(self, debug):
28b11ecf319b [ms] #1382452: incorrect results with multi-sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6671
diff changeset
   222
        return debugged(debug)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1789
diff changeset
   223
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
    def _rqlhelper(self):
3240
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2200
diff changeset
   225
        rqlhelper = self.repo.vreg.rqlhelper
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
        # reset uid_func so it don't try to get type from eids
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
        rqlhelper._analyser.uid_func = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        rqlhelper._analyser.uid_func_mapping = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
        return rqlhelper
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
9850
5ef9dd383ae2 [tests/rqlannotation,querier] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9835
diff changeset
   231
    def _prepare_plan(self, cnx, rql, kwargs=None, simplify=True):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        rqlhelper = self._rqlhelper()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        rqlst = rqlhelper.parse(rql)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
        rqlhelper.compute_solutions(rqlst, kwargs=kwargs)
4184
7002e91d304a should not simplify previous to preprocess
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3240
diff changeset
   235
        if simplify:
7002e91d304a should not simplify previous to preprocess
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3240
diff changeset
   236
            rqlhelper.simplify(rqlst)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
        for select in rqlst.children:
10804
ee113e1e03de [devtools] pass a key to sort() method
Julien Cristau <julien.cristau@logilab.fr>
parents: 10747
diff changeset
   238
            select.solutions.sort(key=lambda x: list(x.items()))
9850
5ef9dd383ae2 [tests/rqlannotation,querier] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9835
diff changeset
   239
        return self.o.plan_factory(rqlst, kwargs, cnx)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1789
diff changeset
   240
9850
5ef9dd383ae2 [tests/rqlannotation,querier] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9835
diff changeset
   241
    def _prepare(self, cnx, rql, kwargs=None):
5ef9dd383ae2 [tests/rqlannotation,querier] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9835
diff changeset
   242
        plan = self._prepare_plan(cnx, rql, kwargs, simplify=False)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
        plan.preprocess(plan.rqlst)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
        rqlst = plan.rqlst.children[0]
11237
f32134dd0067 [repository] drop remanescence of old multi-sources code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11227
diff changeset
   245
        rqlst.solutions = remove_unused_solutions(rqlst, rqlst.solutions, self.repo.schema)[0]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
        return rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
12039
7514626e1dc5 [session+test] Stop storing / accessing session when it's not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12035
diff changeset
   248
    @contextmanager
4674
3d509dbb473a [test api] rename _user_session to user_groups_session, fix its arguments and return only the session, not (user, session) to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   249
    def user_groups_session(self, *groups):
3d509dbb473a [test api] rename _user_session to user_groups_session, fix its arguments and return only the session, not (user, session) to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   250
        """lightweight session using the current user with hi-jacked groups"""
12039
7514626e1dc5 [session+test] Stop storing / accessing session when it's not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12035
diff changeset
   251
        # use cnx.user.eid to get correct owned_by relation, unless explicit eid
12055
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
   252
        with self.admin_access.cnx() as cnx:
12039
7514626e1dc5 [session+test] Stop storing / accessing session when it's not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12035
diff changeset
   253
            user_eid = cnx.user.eid
12125
1d3a9bb46339 [session] Avoid deprecation warning on access to Connection.data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   254
            cnx.user._cw.transaction_data[user_session_cache_key(user_eid, 'groups')] = set(groups)
12039
7514626e1dc5 [session+test] Stop storing / accessing session when it's not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12035
diff changeset
   255
            yield cnx
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
9831
db4aeba5d336 [test/querier] use the new connection api (part 1/3)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9468
diff changeset
   257
    def qexecute(self, rql, args=None, build_descr=True):
12055
6672f51d8268 [test] Rename BaseQuerierTC._access to BaseQuerierTC.admin_access
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12040
diff changeset
   258
        with self.admin_access.cnx() as cnx:
10365
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9850
diff changeset
   259
            try:
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9850
diff changeset
   260
                return self.o.execute(cnx, rql, args, build_descr)
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9850
diff changeset
   261
            finally:
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9850
diff changeset
   262
                if rql.startswith(('INSERT', 'DELETE', 'SET')):
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9850
diff changeset
   263
                    cnx.commit()
9831
db4aeba5d336 [test/querier] use the new connection api (part 1/3)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9468
diff changeset
   264
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
class BasePlannerTC(BaseQuerierTC):
6957
ffda12be2e9f [repository] #1460066: backport datafeed cube as cubicweb source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6818
diff changeset
   267
2074
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   268
    def setup(self):
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   269
        # XXX source_defs
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   270
        self.o = self.repo.querier
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   271
        self.schema = self.o.schema
9456
a79e88aad555 [multi-sources-removal] Kill repo.sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   272
        self.system = self.repo.system_source
2074
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   273
        do_monkey_patch()
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   274
        self.repo.vreg.rqlhelper.backend = 'postgres' # so FTIRANK is considered
2074
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   275
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   276
    def tearDown(self):
9e268cb6202e enhance BasePlannerTC to ease subclasses definition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2069
diff changeset
   277
        undo_monkey_patch()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
9834
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
   279
    def _prepare_plan(self, cnx, rql, kwargs=None):
12060
0cdf5fafd234 [repo] Extract rql cache handling to a dedicated class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12055
diff changeset
   280
        rqlst = self.repo.vreg.rqlhelper.parse(rql, annotate=True)
0cdf5fafd234 [repo] Extract rql cache handling to a dedicated class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12055
diff changeset
   281
        self.repo.vreg.solutions(cnx, rqlst, kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
        if rqlst.TYPE == 'select':
3240
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2200
diff changeset
   283
            self.repo.vreg.rqlhelper.annotate(rqlst)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
            for select in rqlst.children:
10804
ee113e1e03de [devtools] pass a key to sort() method
Julien Cristau <julien.cristau@logilab.fr>
parents: 10747
diff changeset
   285
                select.solutions.sort(key=lambda x: list(x.items()))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
        else:
10804
ee113e1e03de [devtools] pass a key to sort() method
Julien Cristau <julien.cristau@logilab.fr>
parents: 10747
diff changeset
   287
            rqlst.solutions.sort(key=lambda x: list(x.items()))
9834
807f7a6f33f4 [tests/repotest] use the new connection api
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9833
diff changeset
   288
        return self.o.plan_factory(rqlst, kwargs, cnx)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
10711
d7f009a3b960 [py3k] replace cmp with key in sorted()
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
   291
# monkey patch some methods to get predictable results #######################
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
7850
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   293
from cubicweb import rqlrewrite
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   294
_orig_iter_relations = rqlrewrite.iter_relations
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   295
_orig_insert_snippets = rqlrewrite.RQLRewriter.insert_snippets
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   296
_orig_build_variantes = rqlrewrite.RQLRewriter.build_variantes
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
def _insert_snippets(self, snippets, varexistsmap=None):
10711
d7f009a3b960 [py3k] replace cmp with key in sorted()
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
   299
    _orig_insert_snippets(self, sorted(snippets, key=snippet_key), varexistsmap)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
def _build_variantes(self, newsolutions):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
    variantes = _orig_build_variantes(self, newsolutions)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
    sortedvariantes = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
    for variante in variantes:
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
   305
        orderedkeys = sorted((k[1], k[2], v) for k, v in variante.items())
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
   306
        variante = DumbOrderedDict(sorted(variante.items(),
10711
d7f009a3b960 [py3k] replace cmp with key in sorted()
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
   307
                                          key=lambda a: (a[0][1], a[0][2], a[1])))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
        sortedvariantes.append( (orderedkeys, variante) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
    return [v for ok, v in sorted(sortedvariantes)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
from cubicweb.server.querier import ExecutionPlan
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
_orig_check_permissions = ExecutionPlan._check_permissions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
def _check_permissions(*args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
    res, restricted = _orig_check_permissions(*args, **kwargs)
11226
6b0807ba056a [devtools] fix sorting in ExecutionPlan._check_permissions on python3
Julien Cristau <julien.cristau@logilab.fr>
parents: 11203
diff changeset
   316
    res = DumbOrderedDict(sorted(res.items(), key=lambda x: [list(y.items()) for y in x[1]]))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
    return res, restricted
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
def _dummy_check_permissions(self, rqlst):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
    return {(): rqlst.solutions}, set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
from cubicweb.server import rqlannotation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
_orig_select_principal = rqlannotation._select_principal
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
def _select_principal(scope, relations):
7357
5ad3154a8810 [rql2sql] fix bug avoiding outer join relation to be used as a variable principal. Closes #1659395
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6957
diff changeset
   326
    def sort_key(something):
5ad3154a8810 [rql2sql] fix bug avoiding outer join relation to be used as a variable principal. Closes #1659395
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6957
diff changeset
   327
        try:
5ad3154a8810 [rql2sql] fix bug avoiding outer join relation to be used as a variable principal. Closes #1659395
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6957
diff changeset
   328
            return something.r_type
5ad3154a8810 [rql2sql] fix bug avoiding outer join relation to be used as a variable principal. Closes #1659395
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6957
diff changeset
   329
        except AttributeError:
5ad3154a8810 [rql2sql] fix bug avoiding outer join relation to be used as a variable principal. Closes #1659395
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6957
diff changeset
   330
            return (something[0].r_type, something[1])
599
9ef680acd92a fix select principal so results are predictable during tests
Sylvain <syt@logilab.fr>
parents: 0
diff changeset
   331
    return _orig_select_principal(scope, relations,
7357
5ad3154a8810 [rql2sql] fix bug avoiding outer join relation to be used as a variable principal. Closes #1659395
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6957
diff changeset
   332
                                  _sort=lambda rels: sorted(rels, key=sort_key))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
7850
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   335
def _ordered_iter_relations(stinfo):
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   336
    return sorted(_orig_iter_relations(stinfo), key=lambda x:x.r_type)
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   337
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
def do_monkey_patch():
7850
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   339
    rqlrewrite.iter_relations = _ordered_iter_relations
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   340
    rqlrewrite.RQLRewriter.insert_snippets = _insert_snippets
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   341
    rqlrewrite.RQLRewriter.build_variantes = _build_variantes
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
    ExecutionPlan._check_permissions = _check_permissions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
    ExecutionPlan.tablesinorder = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
def undo_monkey_patch():
7850
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   346
    rqlrewrite.iter_relations = _orig_iter_relations
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   347
    rqlrewrite.RQLRewriter.insert_snippets = _orig_insert_snippets
d14b77c42b06 [test] sort to avoid random failure due to dict order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7398
diff changeset
   348
    rqlrewrite.RQLRewriter.build_variantes = _orig_build_variantes
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
    ExecutionPlan._check_permissions = _orig_check_permissions