summaryrefslogtreecommitdiff
path: root/tests/functional-tests/13-threaded-store.py
blob: 69c970477fccc9b089eb8038beffa540c9d53b42 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/python
#
# Copyright (C) 2010, Nokia <ivan.frade@nokia.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
"""
Test that the threads in the daemon are working:
 A very long query shouldn't block smaller queries.
"""
import os
import dbus
from gi.repository import GObject
from gi.repository import GLib
import time
from dbus.mainloop.glib import DBusGMainLoop

from common.utils import configuration as cfg
import unittest2 as ut
#import unittest as ut
from common.utils.storetest import CommonTrackerStoreTest as CommonTrackerStoreTest

MAX_TEST_TIME = 60  # seconds to finish the tests (to avoid infinite waitings)

AMOUNT_SIMPLE_QUERIES = 10
# ms (How long do we wait for an answer to the complex query)
COMPLEX_QUERY_TIMEOUT = 15000
# seconds (How freq do we send a simple query to the daemon)
SIMPLE_QUERY_FREQ = 2


class TestThreadedStore (CommonTrackerStoreTest):

    """
    When the database is big, running a complex query takes ages.
    After cancelling the query, any following query is queued

    Reported in bug NB#183499
    """

    def setUp(self):
        self.main_loop = GObject.MainLoop()
        self.simple_queries_counter = AMOUNT_SIMPLE_QUERIES
        self.simple_queries_answers = 0

    def __populate_database(self):

        self.assertTrue(os.path.exists('ttl'))
        for ttl_file in ["010-nco_EmailAddress.ttl",
                         "011-nco_PostalAddress.ttl",
                         "012-nco_PhoneNumber.ttl",
                         "014-nco_ContactEmail.ttl",
                         "015-nco_ContactCall.ttl",
                         "018-nco_PersonContact.ttl",
                         "012-nco_PhoneNumber.ttl",
                         "016-nco_ContactIM.ttl"]:
            full_path = os.path.abspath(os.path.join("ttl", ttl_file))
            print full_path
            self.tracker.get_tracker_iface().Load("file://" + full_path,
                                                  timeout=30000)

    def test_complex_query(self):
        start = time.time()
        self.__populate_database()
        end = time.time()
        print "Loading: %.3f sec." % (end - start)

        COMPLEX_QUERY = """
        SELECT ?url nie:url(?photo) nco:imContactStatusMessage (?url)
                tracker:coalesce(nco:nameFamily (?url), nco:nameFamily (?url), nco:nameGiven (?org), ?email, ?phone, nco:blogUrl (?url))
        WHERE {
          { ?url a nco:PersonContact.
            ?url fts:match 'fami*'.
          } UNION {
            ?url a nco:PersonContact.
            ?url nco:hasEmailAddress ?add.
            ?add fts:match 'fami*'.
         } UNION {
            ?url a nco:PersonContact.
            ?url nco:hasPostalAddress ?post.
            ?post fts:match 'fami*'.
         }
         OPTIONAL { ?url nco:photo ?photo.}
         OPTIONAL { ?url nco:org ?org. }
         OPTIONAL { ?url maemo:relevance ?relevance.}
         OPTIONAL { ?url nco:hasPhoneNumber ?hasphone. ?hasPhone nco:phoneNumber ?phone.}
         OPTIONAL { ?url nco:hasEmailAddress ?hasemail. ?hasemail nco:emailAddress ?email.}
         } ORDER BY ?relevance LIMIT 100"""

        # Standard timeout
        print "Send complex query"
        self.complex_start = time.time()
        self.tracker.get_tracker_iface(
        ).SparqlQuery(COMPLEX_QUERY, timeout=COMPLEX_QUERY_TIMEOUT,
                      reply_handler=self.reply_complex,
                      error_handler=self.error_handler_complex)

        self.timeout_id = GLib.timeout_add_seconds(
            MAX_TEST_TIME, self.__timeout_on_idle)
        GLib.timeout_add_seconds(SIMPLE_QUERY_FREQ, self.__simple_query)
        self.main_loop.run()

    def __simple_query(self):
        print "Send simple query (%d)" % (self.simple_queries_counter)
        SIMPLE_QUERY = "SELECT ?name WHERE { ?u a nco:PersonContact; nco:fullname ?name. }"
        self.tracker.get_tracker_iface().SparqlQuery(SIMPLE_QUERY,
                                                     timeout=10000,
                                                     reply_handler=self.reply_simple,
                                                     error_handler=self.error_handler)
        self.simple_queries_counter -= 1
        if (self.simple_queries_counter == 0):
            print "Stop sending queries (wait)"
            return False
        return True

    def reply_simple(self, results):
        print "Simple query answered"
        self.assertNotEquals(len(results), 0)
        self.simple_queries_answers += 1
        if (self.simple_queries_answers == AMOUNT_SIMPLE_QUERIES):
            print "All simple queries answered"
            self.main_loop.quit()

    def reply_complex(self, results):
        print "Complex query: %.3f" % (time.time() - self.complex_start)

    def error_handler(self, error_msg):
        print "ERROR in dbus call", error_msg

    def error_handler_complex(self, error_msg):
        print "Complex query timedout in DBus (", error_msg, ")"

    def __timeout_on_idle(self):
        print "Timeout... asumming idle"
        self.main_loop.quit()
        return False


if __name__ == "__main__":
    ut.main()