diff options
Diffstat (limited to 'tests/functional-tests/store/test_threaded_store.py')
-rw-r--r-- | tests/functional-tests/store/test_threaded_store.py | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/tests/functional-tests/store/test_threaded_store.py b/tests/functional-tests/store/test_threaded_store.py new file mode 100644 index 000000000..5bc68298f --- /dev/null +++ b/tests/functional-tests/store/test_threaded_store.py @@ -0,0 +1,154 @@ +#!/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 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): + super(TestThreadedStore, self).setUp() + + 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() |