From cfff46ff9becdbe5cf48816870e625ed253ecc57 Mon Sep 17 00:00:00 2001 From: drebs Date: Sun, 17 Sep 2017 12:08:25 -0300 Subject: [refactor] move tests to root of repository Tests entrypoint was in a testing/ subfolder in the root of the repository. This was made mainly because we had some common files for tests and we didn't want to ship them (files in testing/test_soledad, which is itself a python package. This sometimes causes errors when loading tests (it seems setuptools is confused with having one python package in a subdirectory of another). This commit moves the tests entrypoint to the root of the repository. Closes: #8952 --- tests/responsiveness/conftest.py | 20 +++++++++++ tests/responsiveness/elastic.py | 47 +++++++++++++++++++++++++ tests/responsiveness/test_responsiveness.py | 50 +++++++++++++++++++++++++++ tests/responsiveness/watchdog.py | 53 +++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 tests/responsiveness/conftest.py create mode 100644 tests/responsiveness/elastic.py create mode 100644 tests/responsiveness/test_responsiveness.py create mode 100644 tests/responsiveness/watchdog.py (limited to 'tests/responsiveness') diff --git a/tests/responsiveness/conftest.py b/tests/responsiveness/conftest.py new file mode 100644 index 00000000..a46aea44 --- /dev/null +++ b/tests/responsiveness/conftest.py @@ -0,0 +1,20 @@ +import pytest + +import elastic +import watchdog as wd + + +def _post_results(dog, request): + elastic.post(dog.seconds_blocked, request) + + +@pytest.fixture +def watchdog(request): + dog = wd.Watchdog() + dog_d = dog.start() + request.addfinalizer(lambda: _post_results(dog, request)) + + def _run(deferred_fun): + deferred_fun().addCallback(lambda _: dog.stop()) + return dog_d + return _run diff --git a/tests/responsiveness/elastic.py b/tests/responsiveness/elastic.py new file mode 100644 index 00000000..fed1506b --- /dev/null +++ b/tests/responsiveness/elastic.py @@ -0,0 +1,47 @@ +import datetime +import elasticsearch + +from pytest_benchmark.plugin import pytest_benchmark_generate_machine_info +from pytest_benchmark.utils import get_commit_info, get_tag, get_machine_id +from pytest_benchmark.storage.elasticsearch import BenchmarkJSONSerializer + + +def post(seconds_blocked, request,): + body, doc_id = get_doc(seconds_blocked, request) + url = request.config.getoption("elasticsearch_url") + if url: + es = elasticsearch.Elasticsearch( + hosts=[url], + serializer=BenchmarkJSONSerializer()) + es.index( + index='responsiveness', + doc_type='responsiveness', + id=doc_id, + body=body) + else: + print body + + +def get_doc(seconds_blocked, request): + fullname = request.node._nodeid + name = request.node.name + group = None + marker = request.node.get_marker("responsivness") + if marker: + group = marker.kwargs.get("group") + + doc = { + "datetime": datetime.datetime.utcnow().isoformat(), + "commit_info": get_commit_info(), + "fullname": fullname, + "name": name, + "group": group, + "machine_info": pytest_benchmark_generate_machine_info(), + } + + # generate a doc id like the one used by pytest-benchmark + machine_id = get_machine_id() + tag = get_tag() + doc_id = machine_id + "_" + tag + "_" + fullname + + return doc, doc_id diff --git a/tests/responsiveness/test_responsiveness.py b/tests/responsiveness/test_responsiveness.py new file mode 100644 index 00000000..b3e2c56a --- /dev/null +++ b/tests/responsiveness/test_responsiveness.py @@ -0,0 +1,50 @@ +import pytest + +from twisted.internet import defer + + +@pytest.inlineCallbacks +def load_up(client, amount, payload): + # create a bunch of local documents + deferreds = [] + for i in xrange(amount): + deferreds.append(client.create_doc({'content': payload})) + yield defer.gatherResults(deferreds) + + +def create_upload(amount, size): + + @pytest.mark.responsiveness + @pytest.inlineCallbacks + def _test(soledad_client, payload, watchdog): + + client = soledad_client() + yield load_up(client, amount, payload(size)) + yield watchdog(client.sync) + + return _test + + +test_responsiveness_upload_10_1000k = create_upload(10, 1000 * 1000) +test_responsiveness_upload_100_100k = create_upload(100, 100 * 1000) +test_responsiveness_upload_1000_10k = create_upload(1000, 10 * 1000) + + +def create_download(downloads, size): + + @pytest.mark.responsiveness + @pytest.inlineCallbacks + def _test(soledad_client, payload, watchdog): + client = soledad_client() + yield load_up(client, downloads, payload(size)) + yield client.sync() + + clean_client = soledad_client(force_fresh_db=True) + yield watchdog(clean_client.sync) + + return _test + + +test_responsiveness_download_10_1000k = create_download(10, 1000 * 1000) +test_responsiveness_download_100_100k = create_download(100, 100 * 1000) +test_responsiveness_download_1000_10k = create_download(1000, 10 * 1000) diff --git a/tests/responsiveness/watchdog.py b/tests/responsiveness/watchdog.py new file mode 100644 index 00000000..88f4fa67 --- /dev/null +++ b/tests/responsiveness/watchdog.py @@ -0,0 +1,53 @@ +from twisted.internet import defer, reactor +from twisted.internet.task import LoopingCall +from twisted.internet.threads import deferToThread + + +class Watchdog(object): + + DEBUG = False + + def __init__(self, delay=0.01): + self.delay = delay + self.loop_call = LoopingCall.withCount(self.watch) + self.blocked = 0 + self.checks = [] + self.d = None + + def start(self): + self.debug("\n[watchdog] starting") + self.loop_call.start(self.delay) + self.d = defer.Deferred() + return self.d + + def watch(self, count): + self.debug("[watchdog] watching (%d)" % count) + if (self.loop_call.running): + self.checks.append(deferToThread(self._check, count)) + + def _check(self, count): + # self.debug("[watchdog] _checking (%d)" % count) + if count > 1: + self.blocked += count + + def stop(self): + # delay the actual stop so we make sure at least one check watch will + # run in the reactor. + reactor.callLater(2 * self.delay, self._stop) + + @defer.inlineCallbacks + def _stop(self): + if not self.loop_call.running: + return + + self.loop_call.stop() + yield defer.gatherResults(self.checks) + self.d.callback(None) + + @property + def seconds_blocked(self): + return self.blocked * self.delay + + def debug(self, s): + if self.DEBUG: + print(s) -- cgit v1.2.3