Gitlab Community Edition Instance

Commit 70183438 authored by mhellka's avatar mhellka
Browse files

Split api tests into unit and integration tests.

Integration tests are automatically skipped if TEST_CDSTAR is not defined.
Unit tests use the `responses` library to mock REST-calls and do not need
a running CDSTAR server.
parent 191ddde8
......@@ -28,7 +28,7 @@ setup(
long_description_content_type='text/markdown',
packages=find_packages(where='src'),
package_dir={'': 'src'},
entry_points = {
entry_points={
'console_scripts': ['pycdstar3=pycdstar3.__main__:main'],
},
include_package_data=True,
......@@ -46,10 +46,10 @@ setup(
'test': [
'mock',
'pytest>=3.6',
'pytest-mock',
'pytest-cov',
'pytest-cov>=2.8.1',
'coverage>=4.2',
],'docs': [
'responses>=0.10',
], 'docs': [
'sphinx>=2.2.0',
],
},
......
import pytest
from pycdstar3 import CDStar
import json
from pycdstar3.model import JsonObject
@pytest.fixture
def mockserver(mocker):
class MockSession(mocker.Mock):
callstack = []
def request(self, method, *args, **kw):
path = args[0]
self.callstack.append((method, path))
if method == 'GET' and path == '/_raise':
return mocker.Mock(
ok=False,
status_code=500,
headers={"Content-Type": "application/json"},
json=mocker.Mock(return_value={
'error': 'e', 'message': 'm', 'status': 's', 'detail': [('x', 'y')]}))
payload = {}
if method == 'GET' and path == '/':
payload = {
'vaults': ['demo'],
'version': {
'source': {
'date': '2019-10-01T11:39:44Z',
'branch': '4b7a9983731a8a29251f9b2c0cea54e92af2413e',
'commit': '4b7a9983731a8a29251f9b2c0cea54e92af2413e'
},
'java': '25.111-b14',
'api': '3.0',
'cdstar': '3.0.0-SNAPSHOT'
}
}
elif method == 'GET' and path == '/x':
payload = {'public': True}
elif method == 'GET' and path == '/_tx/tx':
payload = {
'isolation': 'snapshot',
'timeout': 60,
'ttl': 60,
'readonly': False,
'id': 'tx'
}
elif method == 'POST' and path == '/_tx/tx' and kw.get("params", None) == {"renew": True}:
payload = {
'isolation': 'snapshot',
'timeout': 60,
'ttl': 60,
'readonly': False,
'id': 'tx'
}
elif method == 'POST' and path == '/_tx':
payload = {
'isolation': 'snapshot',
'timeout': 60,
'ttl': 60,
'readonly': False,
'id': 'tx'
}
elif method == 'POST' and path == '/_tx/deltx':
raise ValueError()
elif method == 'POST' and path == '/demo':
# create an archive:
payload = {'id': 'archive', 'vault': 'demo', 'revision': '0'}
payload = json.loads(json.dumps(payload), object_hook=JsonObject)
return mocker.Mock(json=mocker.Mock(return_value=payload))
return CDStar('', _session=MockSession(), auth=('test', 'test'))
import pytest
import responses
from pycdstar3 import CDStar, ApiError
SERVER = "https://example.com/test/v3/"
@pytest.fixture
def restmock():
with responses.RequestsMock() as rsps:
yield rsps
@pytest.fixture
def client():
return CDStar(SERVER)
def test_service_info(client, restmock):
restmock.add("GET", SERVER, json={"version": {"api": "3.0"}})
assert client.service_info().version.api == "3.0"
def test_vault_info(client, restmock):
restmock.add("GET", SERVER + "test", json={"public": True})
assert client.vault_info('test').public is True
def test_tx(client, restmock):
with pytest.raises(RuntimeError):
# Can't commit without transaction!
client.commit()
with pytest.raises(RuntimeError):
# Cant't call keepalive without transaction!
client.keepalive()
txjson = {"id": "123", "ttl": 60, "timeout": 60, "isolation": "snapshot", "readonly": False}
restmock.add("POST", SERVER + "_tx", json=txjson)
with client.begin():
assert client.tx.id == '123'
restmock.add("POST", SERVER + "_tx/123?renew=True", json=txjson)
client.keepalive()
restmock.add("POST", SERVER + "_tx/123")
client.commit()
assert client.tx is None
with client.begin():
restmock.add("DELETE", SERVER + "_tx/123")
client.rollback()
assert client.tx is None
with client.begin():
pass
assert restmock.calls[-1].request.method == 'DELETE'
assert restmock.calls[-1].request.url == SERVER + "_tx/123"
with client.begin(autocommit=True):
pass
assert restmock.calls[-1].request.method == 'POST'
assert restmock.calls[-1].request.url == SERVER + "_tx/123"
with pytest.raises(RuntimeError):
with client:
pass # pragma: no cover
def test_error(client, restmock):
with pytest.raises(ApiError) as e:
restmock.add("GET", SERVER + "missing", status=404, json={
"status": 404,
"error": "VaultNotFound",
"message": "Vault not found",
"detail": {
"vault": "bad"
}
})
client.rest('GET', 'missing')
assert e.value.status == 404
assert e.value.error == "VaultNotFound"
......@@ -10,20 +10,20 @@ import os
import pytest
from pycdstar3 import CDStar, ApiError, FormUpdate
from pycdstar3 import CDStar
SERVER = os.environ.get("TEST_CDSTAR", "http://127.0.0.1:8080/v3/")
SERVER = os.environ.get("TEST_CDSTAR")
VAULT = os.environ.get("TEST_VAULT", "test")
pytestmark = pytest.mark.skipif(not SERVER, reason="No TEST_SERVER configured")
@pytest.mark.with_server
def test_service_info(): # pragma: no cover
c = CDStar(SERVER)
si = c.service_info()
assert si['version']['api'] == "3.0"
@pytest.mark.with_server
def test_tx(): # pragma: no cover
c = CDStar(SERVER)
with c.begin():
......@@ -34,7 +34,6 @@ def test_tx(): # pragma: no cover
assert c.tx is None
@pytest.mark.with_server
def test_tx_commit(): # pragma: no cover
c = CDStar(SERVER)
with c.begin():
......@@ -43,14 +42,12 @@ def test_tx_commit(): # pragma: no cover
assert c.tx is None
@pytest.mark.with_server
def test_vault_info(): # pragma: no cover
c = CDStar(SERVER)
vi = c.vault_info(VAULT)
assert 'public' in vi
@pytest.mark.with_server
def test_crud_file(): # pragma: no cover
c = CDStar(SERVER)
......@@ -70,72 +67,3 @@ def test_crud_file(): # pragma: no cover
assert fp.read() == fget.readall()
assert "text/x-python" == fget.type
# no commit
# Mockserver tests:
def test_clone(mockserver):
assert mockserver.clone().auth
def test_service_info2(mockserver):
si = mockserver.service_info()
assert si['version']['api'] == "3.0"
def test_vault_info2(mockserver):
vi = mockserver.vault_info('x')
assert 'public' in vi
def test_tx2(mockserver):
with pytest.raises(RuntimeError):
# Can't commit without transaction!
mockserver.commit()
with pytest.raises(RuntimeError):
# Cant't call keepalive without transaction!
mockserver.keepalive()
with mockserver.begin():
assert 'id' in mockserver.tx
mockserver.service_info()
mockserver.keepalive()
mockserver.commit()
assert mockserver.tx is None
with mockserver.begin():
# tweak the transaction id to trigger Exception:
mockserver._tx['id'] = 'deltx'
with pytest.raises(ValueError):
mockserver.commit()
with mockserver.begin():
mockserver.rollback()
assert mockserver.tx is None
with mockserver.begin():
pass
assert mockserver._session.callstack[-1] == ('DELETE', '/_tx/tx')
with mockserver.begin(autocommit=True):
pass
assert mockserver._session.callstack[-1] == ('POST', '/_tx/tx')
with pytest.raises(RuntimeError):
with mockserver:
pass # pragma: no cover
def test_error(mockserver):
with pytest.raises(ApiError) as e:
mockserver.rest('GET', '_raise')
msg = e.value.pretty()
assert 'e (s)' in msg
def test_archive(mockserver):
with mockserver.begin():
mockserver.create_archive('demo')
with mockserver.begin():
mockserver.create_archive('demo', form=FormUpdate())
......@@ -4,7 +4,8 @@ skip_missing_interpreters = true
[testenv]
extras = test
commands = pytest -m "not with_server" {posargs}
commands = pytest {posargs}
passenv = TEST_CDSTAR TEST_VAULT
[flake8]
ignore = E121,E123,E126,E133,E226,E241,E242,E704,W503,W504,W505
......
Supports Markdown
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