summaryrefslogtreecommitdiff
path: root/tests/responsiveness
diff options
context:
space:
mode:
Diffstat (limited to 'tests/responsiveness')
-rw-r--r--tests/responsiveness/conftest.py20
-rw-r--r--tests/responsiveness/elastic.py47
-rw-r--r--tests/responsiveness/test_responsiveness.py50
-rw-r--r--tests/responsiveness/watchdog.py53
4 files changed, 170 insertions, 0 deletions
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)