Commit bd9cd5b8 authored by Sam Thursfield's avatar Sam Thursfield

Merge branch 'sam/functional-tests-remove-generated-data' into 'master'

functional-tests: Remove stress tests

Closes #124

See merge request GNOME/tracker!113
parents 7188a3ce 0a4df434
#!/usr/bin/python3
#
# 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 the query while importing at the same time. This was raising
some SQLITE_MISUSED errors before.
"""
import os
from gi.repository import GLib
from common.utils import configuration as cfg
import unittest as ut
from common.utils.storetest import CommonTrackerStoreTest as CommonTrackerStoreTest
class TestSqliteMisused (CommonTrackerStoreTest):
"""
Send queries while importing files (in .ttl directory)
"""
def setUp(self):
self.main_loop = GLib.MainLoop()
self.files_counter = 0
def test_queries_while_import(self):
assert os.path.isdir(cfg.generated_ttl_dir())
for root, dirs, files in os.walk(cfg.generated_ttl_dir()):
for ttl_file in [f for f in files if f.endswith(".ttl")]:
full_path = os.path.abspath(os.path.join(root, ttl_file))
self.files_counter += 1
self.tracker.load(
"file://" + full_path, timeout=30000,
result_handler=self.loaded_success_cb,
error_handler=self.loaded_failed_cb,
user_data=full_path)
GLib.timeout_add_seconds(2, self.run_a_query)
# Safeguard of 60 seconds. The last reply should quit the loop
# It doesn't matter if we didn't import all of the files yet.
GLib.timeout_add_seconds(60, self.timeout_cb)
self.main_loop.run()
def run_a_query(self):
QUERY = "SELECT ?u ?title WHERE { ?u a nie:InformationElement; nie:title ?title. }"
self.tracker.query(
QUERY, timeout=20000,
result_handler=self.reply_cb,
error_handler=self.error_handler)
return True
def reply_cb(self, obj, results, data):
print("Query replied correctly")
def error_handler(self, obj, error, data):
print("ERROR in DBus call: %s" % error)
def loaded_success_cb(self, obj, results, user_data):
self.files_counter -= 1
if (self.files_counter == 0):
print("Last file loaded")
self.timeout_cb()
print("Success loading %s" % user_data)
def loaded_failed_cb(self, obj, error, user_data):
raise RuntimeError("Failed loading %s: %s" % (user_data, error))
def timeout_cb(self):
print("Forced timeout after 60 sec.")
self.main_loop.quit()
return False
if __name__ == "__main__":
ut.main()
#!/usr/bin/python3
#
# 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 the query while running BatchSparqlUpdate at the same time. This was raising
some SQLITE_MISUSED errors before.
"""
import os
from gi.repository import GLib
from common.utils import configuration as cfg
import unittest as ut
from common.utils.storetest import CommonTrackerStoreTest as CommonTrackerStoreTest
# Number of instances per batch
BATCH_SIZE = 3000
class TestSqliteBatchMisused (CommonTrackerStoreTest):
"""
Send big batchSparqlUpdates and run queries at the same time
Don't run this script directly, use the bash script "force-sqlite-misused.sh" instead
to configure properly the environment
"""
def setUp(self):
self.main_loop = GLib.MainLoop()
self.batch_counter = 0
def test_queries_while_batch_insert(self):
self.assertTrue(os.path.exists(cfg.generated_ttl_dir()))
for root, dirs, files in os.walk(cfg.generated_ttl_dir()):
for ttl_file in [f for f in files if f.endswith(".ttl")]:
full_path = os.path.abspath(os.path.join(root, ttl_file))
print(full_path)
counter = 0
current_batch = ""
for line in open(full_path):
if (line.startswith("@prefix")):
continue
current_batch += line
if len(line) > 1 and line[:-1].endswith('.'):
counter += 1
if counter >= BATCH_SIZE:
query = "INSERT {" + current_batch + "}"
token = self.tracker.batch_update(
query,
timeout=20000,
result_handler=self.batch_success_cb,
error_handler=self.batch_failed_cb)
self.run_a_query()
counter = 0
current_batch = ""
self.batch_counter += 1
GLib.timeout_add_seconds(2, self.run_a_query)
# Safeguard of 60 seconds. The last reply should quit the loop
GLib.timeout_add_seconds(60, self.timeout_cb)
self.main_loop.run()
def run_a_query(self):
QUERY = "SELECT ?u ?title WHERE { ?u a nie:InformationElement; nie:title ?title. }"
self.tracker.query(
QUERY, timeout=20000,
reply_handler=self.reply_cb,
error_handler=self.error_handler)
return True
def reply_cb(self, obj, results, data):
print("Query replied correctly")
def error_handler(self, error_msg):
print("Query failed", error_msg)
raise error_msg
def batch_success_cb(self, obj, result, user_data):
self.batch_counter -= 1
if (self.batch_counter == 0):
print("Last batch was success")
self.timeout_cb()
print("Success processing a batch")
def batch_failed_cb(self, obj, error, user_data):
print("Failed processing a batch: %s" % error)
raise error
def timeout_cb(self):
print("Forced timeout after 60 sec.")
self.main_loop.quit()
return False
if __name__ == "__main__":
ut.main()
#!/usr/bin/python3
#
# 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
from gi.repository import GLib
import time
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):
self.main_loop = GLib.MainLoop()
self.simple_queries_counter = AMOUNT_SIMPLE_QUERIES
self.simple_queries_answers = 0
def __populate_database(self):
self.assertTrue(os.path.exists(cfg.generated_ttl_dir()))
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(
cfg.generated_ttl_dir(), ttl_file))
print(full_path)
self.tracker.get_tracker_iface().Load(
'(s)', "file://" + full_path, timeout=30000)
@ut.skip("Test fails with 'GDBus.Error:org.freedesktop.Tracker1.SparqlError.Internal: parser stack overflow (36)'")
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:imStatusMessage (?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.query(
COMPLEX_QUERY, timeout=COMPLEX_QUERY_TIMEOUT,
response_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.query(
SIMPLE_QUERY,
timeout=10000,
response_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, obj, results, data):
print("Simple query answered")
self.assertNotEqual(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, obj, results, data):
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()
......@@ -89,10 +89,3 @@ TEST_ONTOLOGIES_DIR = os.path.normpath(
TRACKER_STORE_PATH = os.path.normpath(expandvars(config['TRACKER_STORE_PATH']))
disableJournal = (len(config['disableJournal']) == 0)
def generated_ttl_dir():
if TOP_BUILDDIR:
return os.path.join(TOP_BUILDDIR, 'tests', 'functional-tests', 'ttl')
else:
return 'ttl'
......@@ -26,15 +26,6 @@ functional_tests = [
'17-ontology-changes',
]
subdir('ttl')
functional_tests_with_test_data = [
'13-threaded-store',
]
# These tests are disabled by default as they are really slow.
# '10-sqlite-misused',
# '11-sqlite-batch-misused',
config_json_full_path = join_paths(meson.current_build_dir(), 'configuration.json')
dconf_profile_full_path = join_paths(meson.current_source_dir(), 'trackertest')
......@@ -48,7 +39,7 @@ test_env.set('TRACKER_FUNCTIONAL_TEST_CONFIG', config_json_full_path)
test_env.set('TRACKER_LANGUAGE_STOP_WORDS_DIR', tracker_uninstalled_stop_words_dir)
test_env.set('TRACKER_TEST_DOMAIN_ONTOLOGY_RULE', tracker_uninstalled_domain_rule)
foreach t: functional_tests + functional_tests_with_test_data
foreach t: functional_tests
test('functional-' + t, test_runner,
args: './' + t + '.py',
env: test_env,
......
barnum_dir = join_paths(meson.current_source_dir(), '..', '..', '..', 'utils', 'data-generators', 'cc')
barnum = join_paths(barnum_dir, 'generate')
barnum_config = join_paths(barnum_dir, 'max.cfg')
barnum_outputs = [
'010-nco_EmailAddress.ttl',
'011-nco_PostalAddress.ttl',
'012-nco_PhoneNumber.ttl',
'013-nco_IMAddress.ttl',
'014-nco_ContactEmail.ttl',
'015-nco_ContactCall.ttl',
'016-nco_ContactIM.ttl',
'018-nco_PersonContact.ttl',
'020-slo_GeoLocation.ttl',
'021-slo_Landmark.ttl',
'026-mlo_GeoPoint.ttl',
'027-mlo_LocationBoundingBox.ttl',
'028-mlo_GeoLocation.ttl',
'029-mlo_Landmark.ttl',
'030-nmo_MailAccount.ttl',
'031-nmo_MailFolder.ttl',
'032-nmo_Email.ttl',
'035-nmo_CommunicationChannel.ttl',
'036-nmo_IMMessage.ttl',
'037-nmo_SMSMessage.ttl',
'038-nmo_Call.ttl',
'040-nmm_Artist.ttl',
'040-nmm_MusicAlbumDisc.ttl',
'041-nmm_MusicAlbum.ttl',
'042-nmm_MusicPiece.ttl',
'045-nmm_Photo.ttl',
'044-nfo_Equipment.ttl',
'046-nmm_Video.ttl',
'050-tracker_Volume.ttl',
'051-nfo_PlainTextDocument.ttl',
'060-nfo_SoftwareCategory.ttl',
'061-nfo_SoftwareApplication.ttl',
'065-nfo_WebHistory.ttl',
'070-ncal_Alarm.ttl',
'071-ncal_Calendar.ttl',
'072-ncal_Event.ttl',
'073-ncal_Todo.ttl',
'080-mfo_FeedChannel.ttl',
'081-mfo_FeedMessage.ttl',
'090-mto_TransferElement.ttl',
'091-mto_UploadTransfer.ttl',
]
barnum_test_data = custom_target('barnum-test-data',
command: [barnum, barnum_config, meson.current_build_dir()],
output: barnum_outputs,
build_by_default: true)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment