From 1e3de25ce10156655bcb1bc879f5340baa889ead Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Fri, 16 Sep 2016 04:37:20 -0300 Subject: [bug] disable decpool Temporary fix for server streaming --- testing/tests/perf/test_sync.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/test_sync.py b/testing/tests/perf/test_sync.py index 0b48a0b9..4d42395b 100644 --- a/testing/tests/perf/test_sync.py +++ b/testing/tests/perf/test_sync.py @@ -23,7 +23,8 @@ def create_upload(uploads, size): def setup(): return load_up(client, uploads, payload(size)) - yield txbenchmark_with_setup(setup, client.sync) + yield txbenchmark_with_setup(setup, client.sync, + defer_decryption=False) return test -- cgit v1.2.3 From 35563cb74fcfd7f6ae969ed3af3a74d3c18cbf5b Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Sun, 18 Sep 2016 00:26:45 -0300 Subject: [refactor] remove decpool It's not being used --- testing/tests/perf/test_encdecpool.py | 41 ----------------------------------- testing/tests/perf/test_sync.py | 3 +-- 2 files changed, 1 insertion(+), 43 deletions(-) (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/test_encdecpool.py b/testing/tests/perf/test_encdecpool.py index 77091a41..8e820b9c 100644 --- a/testing/tests/perf/test_encdecpool.py +++ b/testing/tests/perf/test_encdecpool.py @@ -3,7 +3,6 @@ import json from uuid import uuid4 from twisted.internet.defer import gatherResults from leap.soledad.client.encdecpool import SyncEncrypterPool -from leap.soledad.client.encdecpool import SyncDecrypterPool from leap.soledad.common.document import SoledadDocument # FIXME: test load is low due issue #7370, higher values will get out of memory @@ -36,43 +35,3 @@ def create_encrypt(amount, size): test_encdecpool_encrypt_100_10k = create_encrypt(100, 10*1000) test_encdecpool_encrypt_100_100k = create_encrypt(100, 100*1000) test_encdecpool_encrypt_100_500k = create_encrypt(100, 500*1000) - - -def create_decrypt(amount, size): - @pytest.mark.benchmark(group="test_pool_decrypt") - @pytest.inlineCallbacks - def test(soledad_client, txbenchmark_with_setup, request, payload): - DOC_CONTENT = {'payload': payload(size)} - client = soledad_client() - - def setup(): - pool = SyncDecrypterPool( - client._crypto, - client._sync_db, - source_replica_uid=client._dbpool.replica_uid, - insert_doc_cb=lambda x, y, z: False) # ignored - pool.start(amount) - request.addfinalizer(pool.stop) - crypto = client._crypto - docs = [] - for _ in xrange(amount): - doc = SoledadDocument( - doc_id=uuid4().hex, rev='rev', - json=json.dumps(DOC_CONTENT)) - encrypted_content = json.loads(crypto.encrypt_doc(doc)) - docs.append((doc.doc_id, encrypted_content)) - return pool, docs - - def put_and_wait(pool, docs): - deferreds = [] # fires on completion - for idx, (doc_id, content) in enumerate(docs, 1): - deferreds.append(pool.insert_encrypted_received_doc( - doc_id, 'rev', content, idx, "trans_id", idx)) - return gatherResults(deferreds) - - yield txbenchmark_with_setup(setup, put_and_wait) - return test - -test_encdecpool_decrypt_100_10k = create_decrypt(100, 10*1000) -test_encdecpool_decrypt_100_100k = create_decrypt(100, 100*1000) -test_encdecpool_decrypt_100_500k = create_decrypt(100, 500*1000) diff --git a/testing/tests/perf/test_sync.py b/testing/tests/perf/test_sync.py index 4d42395b..0b48a0b9 100644 --- a/testing/tests/perf/test_sync.py +++ b/testing/tests/perf/test_sync.py @@ -23,8 +23,7 @@ def create_upload(uploads, size): def setup(): return load_up(client, uploads, payload(size)) - yield txbenchmark_with_setup(setup, client.sync, - defer_decryption=False) + yield txbenchmark_with_setup(setup, client.sync) return test -- cgit v1.2.3 From a8182bb4f954c02d53d699bfe2a645667d770269 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Mon, 19 Sep 2016 21:48:56 -0300 Subject: [feature] upload streaming 1) enable HTTP 1.1 chunked upload on server 2) make the client sync.py generate a list of function calls instead of a list of full docs 3) disable encryption pool 4) make the doc encryption a list of function calls 5) create a twisted protocol for sending 6) make a producer that calls the doc generation as necessary --- testing/tests/perf/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/conftest.py b/testing/tests/perf/conftest.py index 6fa6b2c0..09567b88 100644 --- a/testing/tests/perf/conftest.py +++ b/testing/tests/perf/conftest.py @@ -243,7 +243,7 @@ def soledad_client(tmpdir, soledad_server, remote_db, soledad_dbs, request): server_url=server_url, cert_file=None, auth_token=token, - defer_encryption=True) + defer_encryption=False) request.addfinalizer(soledad_client.close) return soledad_client return create -- cgit v1.2.3 From 0098849ffd6d9d7514a2eff7b6ced9403a9062ca Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 19 Sep 2016 22:00:04 -0400 Subject: [refactor] add SoledadCrypto interface --- testing/tests/perf/conftest.py | 3 +- testing/tests/perf/test_crypto.py | 79 +++++++++++++++++++++-------------- testing/tests/perf/test_encdecpool.py | 37 ---------------- 3 files changed, 48 insertions(+), 71 deletions(-) delete mode 100644 testing/tests/perf/test_encdecpool.py (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/conftest.py b/testing/tests/perf/conftest.py index 09567b88..2964936b 100644 --- a/testing/tests/perf/conftest.py +++ b/testing/tests/perf/conftest.py @@ -242,8 +242,7 @@ def soledad_client(tmpdir, soledad_server, remote_db, soledad_dbs, request): local_db_path=local_db_path, server_url=server_url, cert_file=None, - auth_token=token, - defer_encryption=False) + auth_token=token) request.addfinalizer(soledad_client.close) return soledad_client return create diff --git a/testing/tests/perf/test_crypto.py b/testing/tests/perf/test_crypto.py index be00560b..9ce418ba 100644 --- a/testing/tests/perf/test_crypto.py +++ b/testing/tests/perf/test_crypto.py @@ -1,9 +1,21 @@ +""" +Benchmarks for crypto operations. +If you don't want to stress your local machine too much, you can pass the +SIZE_LIMT environment variable. + +For instance, to keep the maximum payload at 1MB: + +SIZE_LIMIT=1E6 py.test -s tests/perf/test_crypto.py +""" import pytest +import os import json from uuid import uuid4 + from leap.soledad.common.document import SoledadDocument -from leap.soledad.client.crypto import encrypt_sym -from leap.soledad.client.crypto import decrypt_sym +from leap.soledad.client import _crypto + +LIMIT = int(float(os.environ.get('SIZE_LIMIT', 50 * 1000 * 1000))) def create_doc_encryption(size): @@ -20,7 +32,11 @@ def create_doc_encryption(size): return test_doc_encryption +# TODO this test is really bullshit, because it's still including +# the json serialization. + def create_doc_decryption(size): + @pytest.inlineCallbacks @pytest.mark.benchmark(group="test_crypto_decrypt_doc") def test_doc_decryption(soledad_client, benchmark, payload): crypto = soledad_client()._crypto @@ -29,32 +45,19 @@ def create_doc_decryption(size): doc = SoledadDocument( doc_id=uuid4().hex, rev='rev', json=json.dumps(DOC_CONTENT)) - encrypted_doc = crypto.encrypt_doc(doc) + + encrypted_doc = yield crypto.encrypt_doc(doc) doc.set_json(encrypted_doc) benchmark(crypto.decrypt_doc, doc) return test_doc_decryption -test_encrypt_doc_10k = create_doc_encryption(10*1000) -test_encrypt_doc_100k = create_doc_encryption(100*1000) -test_encrypt_doc_500k = create_doc_encryption(500*1000) -test_encrypt_doc_1M = create_doc_encryption(1000*1000) -test_encrypt_doc_10M = create_doc_encryption(10*1000*1000) -test_encrypt_doc_50M = create_doc_encryption(50*1000*1000) -test_decrypt_doc_10k = create_doc_decryption(10*1000) -test_decrypt_doc_100k = create_doc_decryption(100*1000) -test_decrypt_doc_500k = create_doc_decryption(500*1000) -test_decrypt_doc_1M = create_doc_decryption(1000*1000) -test_decrypt_doc_10M = create_doc_decryption(10*1000*1000) -test_decrypt_doc_50M = create_doc_decryption(50*1000*1000) - - def create_raw_encryption(size): @pytest.mark.benchmark(group="test_crypto_raw_encrypt") def test_raw_encrypt(benchmark, payload): key = payload(32) - benchmark(encrypt_sym, payload(size), key) + benchmark(_crypto.encrypt_sym, payload(size), key) return test_raw_encrypt @@ -62,20 +65,32 @@ def create_raw_decryption(size): @pytest.mark.benchmark(group="test_crypto_raw_decrypt") def test_raw_decrypt(benchmark, payload): key = payload(32) - iv, ciphertext = encrypt_sym(payload(size), key) - benchmark(decrypt_sym, ciphertext, key, iv) + iv, ciphertext = _crypto.encrypt_sym(payload(size), key) + benchmark(_crypto.decrypt_sym, ciphertext, key, iv) return test_raw_decrypt -test_encrypt_raw_10k = create_raw_encryption(10*1000) -test_encrypt_raw_100k = create_raw_encryption(100*1000) -test_encrypt_raw_500k = create_raw_encryption(500*1000) -test_encrypt_raw_1M = create_raw_encryption(1000*1000) -test_encrypt_raw_10M = create_raw_encryption(10*1000*1000) -test_encrypt_raw_50M = create_raw_encryption(50*1000*1000) -test_decrypt_raw_10k = create_raw_decryption(10*1000) -test_decrypt_raw_100k = create_raw_decryption(100*1000) -test_decrypt_raw_500k = create_raw_decryption(500*1000) -test_decrypt_raw_1M = create_raw_decryption(1000*1000) -test_decrypt_raw_10M = create_raw_decryption(10*1000*1000) -test_decrypt_raw_50M = create_raw_decryption(50*1000*1000) +# Create the TESTS in the global namespace, they'll be picked by the benchmark +# plugin. + +encryption_tests = [ + ('10k', 1E4), + ('100k', 1E5), + ('500k', 5E5), + ('1M', 1E6), + ('10M', 1E7), + ('50M', 5E7), +] + +for name, size in encryption_tests: + if size < LIMIT: + sz = int(size) + globals()['test_encrypt_doc_' + name] = create_doc_encryption(sz) + globals()['test_decrypt_doc_' + name] = create_doc_decryption(sz) + + +for name, size in encryption_tests: + if size < LIMIT: + sz = int(size) + globals()['test_encrypt_raw_' + name] = create_raw_encryption(sz) + globals()['test_decrypt_raw_' + name] = create_raw_decryption(sz) diff --git a/testing/tests/perf/test_encdecpool.py b/testing/tests/perf/test_encdecpool.py deleted file mode 100644 index 8e820b9c..00000000 --- a/testing/tests/perf/test_encdecpool.py +++ /dev/null @@ -1,37 +0,0 @@ -import pytest -import json -from uuid import uuid4 -from twisted.internet.defer import gatherResults -from leap.soledad.client.encdecpool import SyncEncrypterPool -from leap.soledad.common.document import SoledadDocument -# FIXME: test load is low due issue #7370, higher values will get out of memory - - -def create_encrypt(amount, size): - @pytest.mark.benchmark(group="test_pool_encrypt") - @pytest.inlineCallbacks - def test(soledad_client, txbenchmark_with_setup, request, payload): - DOC_CONTENT = {'payload': payload(size)} - - def setup(): - client = soledad_client() - pool = SyncEncrypterPool(client._crypto, client._sync_db) - pool.start() - request.addfinalizer(pool.stop) - docs = [ - SoledadDocument(doc_id=uuid4().hex, rev='rev', - json=json.dumps(DOC_CONTENT)) - for _ in xrange(amount) - ] - return pool, docs - - @pytest.inlineCallbacks - def put_and_wait(pool, docs): - yield gatherResults([pool.encrypt_doc(doc) for doc in docs]) - - yield txbenchmark_with_setup(setup, put_and_wait) - return test - -test_encdecpool_encrypt_100_10k = create_encrypt(100, 10*1000) -test_encdecpool_encrypt_100_100k = create_encrypt(100, 100*1000) -test_encdecpool_encrypt_100_500k = create_encrypt(100, 500*1000) -- cgit v1.2.3 From 349e42d73225282935b2d4677e778821db25634b Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Fri, 28 Oct 2016 21:37:56 -0300 Subject: [tests] improve doc creation on benchmarks If we create all at once we cant test higher loads because it will try to hold all in memory at the same time. Also, this code is smaller and more readable. --- testing/tests/perf/test_sync.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/test_sync.py b/testing/tests/perf/test_sync.py index 0b48a0b9..7b3c4bf0 100644 --- a/testing/tests/perf/test_sync.py +++ b/testing/tests/perf/test_sync.py @@ -1,17 +1,11 @@ import pytest -from twisted.internet.defer import gatherResults - +@pytest.inlineCallbacks def load_up(client, amount, payload): - deferreds = [] # create a bunch of local documents for i in xrange(amount): - d = client.create_doc({'content': payload}) - deferreds.append(d) - d = gatherResults(deferreds) - d.addCallback(lambda _: None) - return d + yield client.create_doc({'content': payload}) def create_upload(uploads, size): -- cgit v1.2.3 From 529dbdf27804f12da80907d25c412d10e9fa3763 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Thu, 17 Nov 2016 01:33:04 -0300 Subject: [style] fix pep8 and confs Fixes setup.cfg, adding current exclude rules, simplified tox.ini to use setup.cfg and fixed all. --- testing/tests/perf/test_crypto.py | 14 +++++++------- testing/tests/perf/test_sqlcipher.py | 12 ++++++------ testing/tests/perf/test_sync.py | 12 ++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/test_crypto.py b/testing/tests/perf/test_crypto.py index 9ce418ba..367c3b5b 100644 --- a/testing/tests/perf/test_crypto.py +++ b/testing/tests/perf/test_crypto.py @@ -5,7 +5,7 @@ SIZE_LIMT environment variable. For instance, to keep the maximum payload at 1MB: -SIZE_LIMIT=1E6 py.test -s tests/perf/test_crypto.py +SIZE_LIMIT=1E6 py.test -s tests/perf/test_crypto.py """ import pytest import os @@ -45,7 +45,7 @@ def create_doc_decryption(size): doc = SoledadDocument( doc_id=uuid4().hex, rev='rev', json=json.dumps(DOC_CONTENT)) - + encrypted_doc = yield crypto.encrypt_doc(doc) doc.set_json(encrypted_doc) @@ -74,16 +74,16 @@ def create_raw_decryption(size): # plugin. encryption_tests = [ - ('10k', 1E4), + ('10k', 1E4), ('100k', 1E5), ('500k', 5E5), - ('1M', 1E6), - ('10M', 1E7), - ('50M', 5E7), + ('1M', 1E6), + ('10M', 1E7), + ('50M', 5E7), ] for name, size in encryption_tests: - if size < LIMIT: + if size < LIMIT: sz = int(size) globals()['test_encrypt_doc_' + name] = create_doc_encryption(sz) globals()['test_decrypt_doc_' + name] = create_doc_decryption(sz) diff --git a/testing/tests/perf/test_sqlcipher.py b/testing/tests/perf/test_sqlcipher.py index e7a54228..39c9e3ad 100644 --- a/testing/tests/perf/test_sqlcipher.py +++ b/testing/tests/perf/test_sqlcipher.py @@ -29,10 +29,10 @@ def build_test_sqlcipher_create(amount, size): return test -test_async_create_20_500k = build_test_sqlcipher_async_create(20, 500*1000) -test_async_create_100_100k = build_test_sqlcipher_async_create(100, 100*1000) -test_async_create_1000_10k = build_test_sqlcipher_async_create(1000, 10*1000) +test_async_create_20_500k = build_test_sqlcipher_async_create(20, 500 * 1000) +test_async_create_100_100k = build_test_sqlcipher_async_create(100, 100 * 1000) +test_async_create_1000_10k = build_test_sqlcipher_async_create(1000, 10 * 1000) # synchronous -test_create_20_500k = build_test_sqlcipher_create(20, 500*1000) -test_create_100_100k = build_test_sqlcipher_create(100, 100*1000) -test_create_1000_10k = build_test_sqlcipher_create(1000, 10*1000) +test_create_20_500k = build_test_sqlcipher_create(20, 500 * 1000) +test_create_100_100k = build_test_sqlcipher_create(100, 100 * 1000) +test_create_1000_10k = build_test_sqlcipher_create(1000, 10 * 1000) diff --git a/testing/tests/perf/test_sync.py b/testing/tests/perf/test_sync.py index 7b3c4bf0..1bf6cc21 100644 --- a/testing/tests/perf/test_sync.py +++ b/testing/tests/perf/test_sync.py @@ -21,9 +21,9 @@ def create_upload(uploads, size): return test -test_upload_20_500k = create_upload(20, 500*1000) -test_upload_100_100k = create_upload(100, 100*1000) -test_upload_1000_10k = create_upload(1000, 10*1000) +test_upload_20_500k = create_upload(20, 500 * 1000) +test_upload_100_100k = create_upload(100, 100 * 1000) +test_upload_1000_10k = create_upload(1000, 10 * 1000) def create_download(downloads, size): @@ -46,9 +46,9 @@ def create_download(downloads, size): return test -test_download_20_500k = create_download(20, 500*1000) -test_download_100_100k = create_download(100, 100*1000) -test_download_1000_10k = create_download(1000, 10*1000) +test_download_20_500k = create_download(20, 500 * 1000) +test_download_100_100k = create_download(100, 100 * 1000) +test_download_1000_10k = create_download(1000, 10 * 1000) @pytest.inlineCallbacks -- cgit v1.2.3 From 5294f5b9ae01429e6d0ee75c8dc98441ba760845 Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 17 Nov 2016 22:14:51 -0200 Subject: [test] use tags for selecting benchmark tests --- testing/tests/perf/conftest.py | 3 --- testing/tests/perf/test_crypto.py | 3 +++ testing/tests/perf/test_misc.py | 2 ++ testing/tests/perf/test_sqlcipher.py | 2 ++ testing/tests/perf/test_sync.py | 2 ++ 5 files changed, 9 insertions(+), 3 deletions(-) (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/conftest.py b/testing/tests/perf/conftest.py index 2964936b..d08ea61d 100644 --- a/testing/tests/perf/conftest.py +++ b/testing/tests/perf/conftest.py @@ -25,9 +25,6 @@ server.ensure_server() def pytest_addoption(parser): - parser.addoption( - "--couch-url", type="string", default="http://127.0.0.1:5984", - help="the url for the couch server to be used during tests") parser.addoption( "--num-docs", type="int", default=100, help="the number of documents to use in performance tests") diff --git a/testing/tests/perf/test_crypto.py b/testing/tests/perf/test_crypto.py index 367c3b5b..a438ee49 100644 --- a/testing/tests/perf/test_crypto.py +++ b/testing/tests/perf/test_crypto.py @@ -18,6 +18,9 @@ from leap.soledad.client import _crypto LIMIT = int(float(os.environ.get('SIZE_LIMIT', 50 * 1000 * 1000))) +pytestmark = pytest.mark.perf + + def create_doc_encryption(size): @pytest.mark.benchmark(group="test_crypto_encrypt_doc") def test_doc_encryption(soledad_client, benchmark, payload): diff --git a/testing/tests/perf/test_misc.py b/testing/tests/perf/test_misc.py index ead48adf..b45dc04e 100644 --- a/testing/tests/perf/test_misc.py +++ b/testing/tests/perf/test_misc.py @@ -1,5 +1,7 @@ import pytest +pytestmark = pytest.mark.perf + @pytest.mark.benchmark(group="test_instance") def test_initialization(soledad_client, benchmark): diff --git a/testing/tests/perf/test_sqlcipher.py b/testing/tests/perf/test_sqlcipher.py index 39c9e3ad..807af6e9 100644 --- a/testing/tests/perf/test_sqlcipher.py +++ b/testing/tests/perf/test_sqlcipher.py @@ -5,6 +5,8 @@ import pytest from twisted.internet.defer import gatherResults +pytestmark = pytest.mark.perf + def load_up(client, amount, payload, defer=True): results = [client.create_doc({'content': payload}) for _ in xrange(amount)] diff --git a/testing/tests/perf/test_sync.py b/testing/tests/perf/test_sync.py index 1bf6cc21..9bb20389 100644 --- a/testing/tests/perf/test_sync.py +++ b/testing/tests/perf/test_sync.py @@ -1,5 +1,7 @@ import pytest +pytestmark = pytest.mark.perf + @pytest.inlineCallbacks def load_up(client, amount, payload): -- cgit v1.2.3 From eadc36dbc23368f8d11a8cf7c9bd5571641d5b36 Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 17 Nov 2016 22:15:32 -0200 Subject: [test] move fixtures one level up --- testing/tests/perf/conftest.py | 188 ----------------------------------------- 1 file changed, 188 deletions(-) (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/conftest.py b/testing/tests/perf/conftest.py index d08ea61d..a9cc3464 100644 --- a/testing/tests/perf/conftest.py +++ b/testing/tests/perf/conftest.py @@ -1,21 +1,9 @@ -import json -import os import pytest -import requests import random import base64 -import signal -import time -from hashlib import sha512 -from uuid import uuid4 -from subprocess import call -from urlparse import urljoin from twisted.internet import threads, reactor -from leap.soledad.client import Soledad -from leap.soledad.common.couch import CouchDatabase - # we have to manually setup the events server in order to be able to signal # events. This is usually done by the enclosing application using soledad @@ -30,18 +18,6 @@ def pytest_addoption(parser): help="the number of documents to use in performance tests") -# -# default options for all tests -# - -DEFAULT_PASSPHRASE = '123' - -DEFAULT_URL = 'http://127.0.0.1:2424' -DEFAULT_PRIVKEY = 'soledad_privkey.pem' -DEFAULT_CERTKEY = 'soledad_certkey.pem' -DEFAULT_TOKEN = 'an-auth-token' - - @pytest.fixture() def payload(): def generate(size): @@ -52,140 +28,6 @@ def payload(): return generate -# -# soledad_dbs fixture: provides all databases needed by soledad server in a per -# module scope (same databases for all tests in this module). -# - -def _token_dbname(): - dbname = 'tokens_' + \ - str(int(time.time() / (30 * 24 * 3600))) - return dbname - - -class SoledadDatabases(object): - - def __init__(self, url): - self._token_db_url = urljoin(url, _token_dbname()) - self._shared_db_url = urljoin(url, 'shared') - - def setup(self, uuid): - self._create_dbs() - self._add_token(uuid) - - def _create_dbs(self): - requests.put(self._token_db_url) - requests.put(self._shared_db_url) - - def _add_token(self, uuid): - token = sha512(DEFAULT_TOKEN).hexdigest() - content = {'type': 'Token', 'user_id': uuid} - requests.put( - self._token_db_url + '/' + token, data=json.dumps(content)) - - def teardown(self): - requests.delete(self._token_db_url) - requests.delete(self._shared_db_url) - - -@pytest.fixture() -def soledad_dbs(request): - couch_url = request.config.option.couch_url - - def create(uuid): - db = SoledadDatabases(couch_url) - request.addfinalizer(db.teardown) - return db.setup(uuid) - return create - - -# -# remote_db fixture: provides an empty database for a given user in a per -# function scope. -# - -class UserDatabase(object): - - def __init__(self, url, uuid): - self._remote_db_url = urljoin(url, 'user-%s' % uuid) - - def setup(self): - return CouchDatabase.open_database( - url=self._remote_db_url, create=True, replica_uid=None) - - def teardown(self): - requests.delete(self._remote_db_url) - - -@pytest.fixture() -def remote_db(request): - couch_url = request.config.option.couch_url - - def create(uuid): - db = UserDatabase(couch_url, uuid) - request.addfinalizer(db.teardown) - return db.setup() - return create - - -def get_pid(pidfile): - if not os.path.isfile(pidfile): - return 0 - try: - with open(pidfile) as f: - return int(f.read()) - except IOError: - return 0 - - -# -# soledad_server fixture: provides a running soledad server in a per module -# context (same soledad server for all tests in this module). -# - -class SoledadServer(object): - - def __init__(self, tmpdir_factory, couch_url): - tmpdir = tmpdir_factory.mktemp('soledad-server') - self._pidfile = os.path.join(tmpdir.strpath, 'soledad-server.pid') - self._logfile = os.path.join(tmpdir.strpath, 'soledad-server.log') - self._couch_url = couch_url - - def start(self): - self._create_conf_file() - # start the server - call([ - 'twistd', - '--logfile=%s' % self._logfile, - '--pidfile=%s' % self._pidfile, - 'web', - '--wsgi=leap.soledad.server.application.wsgi_application', - '--port=2424' - ]) - - def _create_conf_file(self): - if not os.access('/etc', os.W_OK): - return - if not os.path.isdir('/etc/soledad'): - os.mkdir('/etc/soledad') - with open('/etc/soledad/soledad-server.conf', 'w') as f: - content = '[soledad-server]\ncouch_url = %s' % self._couch_url - f.write(content) - - def stop(self): - pid = get_pid(self._pidfile) - os.kill(pid, signal.SIGKILL) - - -@pytest.fixture(scope='module') -def soledad_server(tmpdir_factory, request): - couch_url = request.config.option.couch_url - server = SoledadServer(tmpdir_factory, couch_url) - server.start() - request.addfinalizer(server.stop) - return server - - @pytest.fixture() def txbenchmark(benchmark): def blockOnThread(*args, **kwargs): @@ -213,33 +55,3 @@ def txbenchmark_with_setup(benchmark): rounds=4, warmup_rounds=1) return threads.deferToThread(bench) return blockOnThreadWithSetup - - -# -# soledad_client fixture: provides a clean soledad client for a test function. -# - -@pytest.fixture() -def soledad_client(tmpdir, soledad_server, remote_db, soledad_dbs, request): - passphrase = DEFAULT_PASSPHRASE - server_url = DEFAULT_URL - token = DEFAULT_TOKEN - default_uuid = uuid4().hex - remote_db(default_uuid) - soledad_dbs(default_uuid) - - # get a soledad instance - def create(): - secrets_path = os.path.join(tmpdir.strpath, '%s.secret' % uuid4().hex) - local_db_path = os.path.join(tmpdir.strpath, '%s.db' % uuid4().hex) - soledad_client = Soledad( - default_uuid, - unicode(passphrase), - secrets_path=secrets_path, - local_db_path=local_db_path, - server_url=server_url, - cert_file=None, - auth_token=token) - request.addfinalizer(soledad_client.close) - return soledad_client - return create -- cgit v1.2.3 From 378a07113a713a7c25f0fb8510d18ecdae2198bd Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 17 Nov 2016 22:35:21 -0200 Subject: [test] rename benchmark tests directory and tag --- testing/tests/perf/assets/cert_default.conf | 15 ----- testing/tests/perf/conftest.py | 57 ----------------- testing/tests/perf/pytest.ini | 2 - testing/tests/perf/test_crypto.py | 99 ----------------------------- testing/tests/perf/test_misc.py | 8 --- testing/tests/perf/test_sqlcipher.py | 40 ------------ testing/tests/perf/test_sync.py | 64 ------------------- 7 files changed, 285 deletions(-) delete mode 100644 testing/tests/perf/assets/cert_default.conf delete mode 100644 testing/tests/perf/conftest.py delete mode 100644 testing/tests/perf/pytest.ini delete mode 100644 testing/tests/perf/test_crypto.py delete mode 100644 testing/tests/perf/test_misc.py delete mode 100644 testing/tests/perf/test_sqlcipher.py delete mode 100644 testing/tests/perf/test_sync.py (limited to 'testing/tests/perf') diff --git a/testing/tests/perf/assets/cert_default.conf b/testing/tests/perf/assets/cert_default.conf deleted file mode 100644 index 8043cea3..00000000 --- a/testing/tests/perf/assets/cert_default.conf +++ /dev/null @@ -1,15 +0,0 @@ -[ req ] -default_bits = 1024 -default_keyfile = keyfile.pem -distinguished_name = req_distinguished_name -prompt = no -output_password = mypass - -[ req_distinguished_name ] -C = GB -ST = Test State or Province -L = Test Locality -O = Organization Name -OU = Organizational Unit Name -CN = localhost -emailAddress = test@email.address diff --git a/testing/tests/perf/conftest.py b/testing/tests/perf/conftest.py deleted file mode 100644 index a9cc3464..00000000 --- a/testing/tests/perf/conftest.py +++ /dev/null @@ -1,57 +0,0 @@ -import pytest -import random -import base64 - -from twisted.internet import threads, reactor - - -# we have to manually setup the events server in order to be able to signal -# events. This is usually done by the enclosing application using soledad -# client (i.e. bitmask client). -from leap.common.events import server -server.ensure_server() - - -def pytest_addoption(parser): - parser.addoption( - "--num-docs", type="int", default=100, - help="the number of documents to use in performance tests") - - -@pytest.fixture() -def payload(): - def generate(size): - random.seed(1337) # same seed to avoid different bench results - payload_bytes = bytearray(random.getrandbits(8) for _ in xrange(size)) - # encode as base64 to avoid ascii encode/decode errors - return base64.b64encode(payload_bytes)[:size] # remove b64 overhead - return generate - - -@pytest.fixture() -def txbenchmark(benchmark): - def blockOnThread(*args, **kwargs): - return threads.deferToThread( - benchmark, threads.blockingCallFromThread, - reactor, *args, **kwargs) - return blockOnThread - - -@pytest.fixture() -def txbenchmark_with_setup(benchmark): - def blockOnThreadWithSetup(setup, f): - def blocking_runner(*args, **kwargs): - return threads.blockingCallFromThread(reactor, f, *args, **kwargs) - - def blocking_setup(): - args = threads.blockingCallFromThread(reactor, setup) - try: - return tuple(arg for arg in args), {} - except TypeError: - return ((args,), {}) if args else None - - def bench(): - return benchmark.pedantic(blocking_runner, setup=blocking_setup, - rounds=4, warmup_rounds=1) - return threads.deferToThread(bench) - return blockOnThreadWithSetup diff --git a/testing/tests/perf/pytest.ini b/testing/tests/perf/pytest.ini deleted file mode 100644 index 7a0508ce..00000000 --- a/testing/tests/perf/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -twisted = yes diff --git a/testing/tests/perf/test_crypto.py b/testing/tests/perf/test_crypto.py deleted file mode 100644 index a438ee49..00000000 --- a/testing/tests/perf/test_crypto.py +++ /dev/null @@ -1,99 +0,0 @@ -""" -Benchmarks for crypto operations. -If you don't want to stress your local machine too much, you can pass the -SIZE_LIMT environment variable. - -For instance, to keep the maximum payload at 1MB: - -SIZE_LIMIT=1E6 py.test -s tests/perf/test_crypto.py -""" -import pytest -import os -import json -from uuid import uuid4 - -from leap.soledad.common.document import SoledadDocument -from leap.soledad.client import _crypto - -LIMIT = int(float(os.environ.get('SIZE_LIMIT', 50 * 1000 * 1000))) - - -pytestmark = pytest.mark.perf - - -def create_doc_encryption(size): - @pytest.mark.benchmark(group="test_crypto_encrypt_doc") - def test_doc_encryption(soledad_client, benchmark, payload): - crypto = soledad_client()._crypto - - DOC_CONTENT = {'payload': payload(size)} - doc = SoledadDocument( - doc_id=uuid4().hex, rev='rev', - json=json.dumps(DOC_CONTENT)) - - benchmark(crypto.encrypt_doc, doc) - return test_doc_encryption - - -# TODO this test is really bullshit, because it's still including -# the json serialization. - -def create_doc_decryption(size): - @pytest.inlineCallbacks - @pytest.mark.benchmark(group="test_crypto_decrypt_doc") - def test_doc_decryption(soledad_client, benchmark, payload): - crypto = soledad_client()._crypto - - DOC_CONTENT = {'payload': payload(size)} - doc = SoledadDocument( - doc_id=uuid4().hex, rev='rev', - json=json.dumps(DOC_CONTENT)) - - encrypted_doc = yield crypto.encrypt_doc(doc) - doc.set_json(encrypted_doc) - - benchmark(crypto.decrypt_doc, doc) - return test_doc_decryption - - -def create_raw_encryption(size): - @pytest.mark.benchmark(group="test_crypto_raw_encrypt") - def test_raw_encrypt(benchmark, payload): - key = payload(32) - benchmark(_crypto.encrypt_sym, payload(size), key) - return test_raw_encrypt - - -def create_raw_decryption(size): - @pytest.mark.benchmark(group="test_crypto_raw_decrypt") - def test_raw_decrypt(benchmark, payload): - key = payload(32) - iv, ciphertext = _crypto.encrypt_sym(payload(size), key) - benchmark(_crypto.decrypt_sym, ciphertext, key, iv) - return test_raw_decrypt - - -# Create the TESTS in the global namespace, they'll be picked by the benchmark -# plugin. - -encryption_tests = [ - ('10k', 1E4), - ('100k', 1E5), - ('500k', 5E5), - ('1M', 1E6), - ('10M', 1E7), - ('50M', 5E7), -] - -for name, size in encryption_tests: - if size < LIMIT: - sz = int(size) - globals()['test_encrypt_doc_' + name] = create_doc_encryption(sz) - globals()['test_decrypt_doc_' + name] = create_doc_decryption(sz) - - -for name, size in encryption_tests: - if size < LIMIT: - sz = int(size) - globals()['test_encrypt_raw_' + name] = create_raw_encryption(sz) - globals()['test_decrypt_raw_' + name] = create_raw_decryption(sz) diff --git a/testing/tests/perf/test_misc.py b/testing/tests/perf/test_misc.py deleted file mode 100644 index b45dc04e..00000000 --- a/testing/tests/perf/test_misc.py +++ /dev/null @@ -1,8 +0,0 @@ -import pytest - -pytestmark = pytest.mark.perf - - -@pytest.mark.benchmark(group="test_instance") -def test_initialization(soledad_client, benchmark): - benchmark(soledad_client) diff --git a/testing/tests/perf/test_sqlcipher.py b/testing/tests/perf/test_sqlcipher.py deleted file mode 100644 index 807af6e9..00000000 --- a/testing/tests/perf/test_sqlcipher.py +++ /dev/null @@ -1,40 +0,0 @@ -''' -Tests SoledadClient/SQLCipher interaction -''' -import pytest - -from twisted.internet.defer import gatherResults - -pytestmark = pytest.mark.perf - - -def load_up(client, amount, payload, defer=True): - results = [client.create_doc({'content': payload}) for _ in xrange(amount)] - if defer: - return gatherResults(results) - - -def build_test_sqlcipher_async_create(amount, size): - @pytest.inlineCallbacks - @pytest.mark.benchmark(group="test_sqlcipher_async_create") - def test(soledad_client, txbenchmark, payload): - client = soledad_client() - yield txbenchmark(load_up, client, amount, payload(size)) - return test - - -def build_test_sqlcipher_create(amount, size): - @pytest.mark.benchmark(group="test_sqlcipher_create") - def test(soledad_client, benchmark, payload): - client = soledad_client()._dbsyncer - benchmark(load_up, client, amount, payload(size), defer=False) - return test - - -test_async_create_20_500k = build_test_sqlcipher_async_create(20, 500 * 1000) -test_async_create_100_100k = build_test_sqlcipher_async_create(100, 100 * 1000) -test_async_create_1000_10k = build_test_sqlcipher_async_create(1000, 10 * 1000) -# synchronous -test_create_20_500k = build_test_sqlcipher_create(20, 500 * 1000) -test_create_100_100k = build_test_sqlcipher_create(100, 100 * 1000) -test_create_1000_10k = build_test_sqlcipher_create(1000, 10 * 1000) diff --git a/testing/tests/perf/test_sync.py b/testing/tests/perf/test_sync.py deleted file mode 100644 index 9bb20389..00000000 --- a/testing/tests/perf/test_sync.py +++ /dev/null @@ -1,64 +0,0 @@ -import pytest - -pytestmark = pytest.mark.perf - - -@pytest.inlineCallbacks -def load_up(client, amount, payload): - # create a bunch of local documents - for i in xrange(amount): - yield client.create_doc({'content': payload}) - - -def create_upload(uploads, size): - @pytest.inlineCallbacks - @pytest.mark.benchmark(group="test_upload") - def test(soledad_client, txbenchmark_with_setup, payload): - client = soledad_client() - - def setup(): - return load_up(client, uploads, payload(size)) - - yield txbenchmark_with_setup(setup, client.sync) - return test - - -test_upload_20_500k = create_upload(20, 500 * 1000) -test_upload_100_100k = create_upload(100, 100 * 1000) -test_upload_1000_10k = create_upload(1000, 10 * 1000) - - -def create_download(downloads, size): - @pytest.inlineCallbacks - @pytest.mark.benchmark(group="test_download") - def test(soledad_client, txbenchmark_with_setup, payload): - client = soledad_client() - - yield load_up(client, downloads, payload(size)) - yield client.sync() - # We could create them directly on couch, but sending them - # ensures we are dealing with properly encrypted docs - - def setup(): - return soledad_client() - - def sync(clean_client): - return clean_client.sync() - yield txbenchmark_with_setup(setup, sync) - return test - - -test_download_20_500k = create_download(20, 500 * 1000) -test_download_100_100k = create_download(100, 100 * 1000) -test_download_1000_10k = create_download(1000, 10 * 1000) - - -@pytest.inlineCallbacks -@pytest.mark.benchmark(group="test_nothing_to_sync") -def test_nothing_to_sync(soledad_client, txbenchmark_with_setup): - def setup(): - return soledad_client() - - def sync(clean_client): - return clean_client.sync() - yield txbenchmark_with_setup(setup, sync) -- cgit v1.2.3