128 lines
3.4 KiB
Python
128 lines
3.4 KiB
Python
import os
|
|
import signal
|
|
import socket
|
|
import subprocess
|
|
import time
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
import requests
|
|
from dump_things_service import config_file_name
|
|
|
|
|
|
# String representation of curated- and incoming-path
|
|
curated = 'curated'
|
|
incoming = 'incoming'
|
|
audit_log = 'audit_log'
|
|
|
|
# Path to a local simple test schema
|
|
schema_path = Path(__file__).parent / 'assets' / 'pyclient_testschema.yaml'
|
|
schema_path = schema_path.resolve()
|
|
|
|
# The global configuration file, all collections and
|
|
# staging areas share the same directories. All tokens
|
|
# of the same collection share an "incoming_label".
|
|
global_config_text = f"""
|
|
type: collections
|
|
version: 1
|
|
collections:
|
|
collection_1:
|
|
default_token: user_1
|
|
curated: {curated}
|
|
incoming: {incoming}
|
|
backend:
|
|
type: record_dir
|
|
auth_sources:
|
|
- type: config
|
|
submission_tags:
|
|
submitter_id_tag: https://submitter.example.com
|
|
submission_time_tag: https://time.example.com
|
|
audit_backends:
|
|
- type: gitaudit
|
|
path: {{gitaudit_path}}
|
|
auto_flush_timeout: 1
|
|
tokens:
|
|
user_1:
|
|
user_id: test_user_1
|
|
collections:
|
|
collection_1:
|
|
mode: WRITE_COLLECTION
|
|
incoming_label: test_user_1
|
|
user_2:
|
|
user_id: test_user_1
|
|
collections:
|
|
collection_1:
|
|
mode: WRITE_COLLECTION
|
|
incoming_label: test_user_2
|
|
token-curator:
|
|
user_id: test_curator
|
|
collections:
|
|
collection_1:
|
|
mode: CURATOR
|
|
incoming_label: test_curator
|
|
"""
|
|
|
|
|
|
collection_1_config = f"""type: records
|
|
version: 1
|
|
schema: {schema_path}
|
|
format: yaml
|
|
idfx: digest-md5
|
|
"""
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
def dump_stores_simple(tmp_path_factory):
|
|
tmp_path = tmp_path_factory.mktemp('dump_store')
|
|
|
|
# Write the global config file, create collection directories, and write
|
|
# the collection config file.
|
|
global_config_with_audit = global_config_text.format(
|
|
gitaudit_path=str(tmp_path / audit_log)
|
|
)
|
|
(tmp_path / config_file_name).write_text(global_config_with_audit)
|
|
(tmp_path / curated).mkdir(parents=True, exist_ok=True)
|
|
(tmp_path / incoming).mkdir(parents=True, exist_ok=True)
|
|
(tmp_path / curated / config_file_name).write_text(collection_1_config)
|
|
return tmp_path
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
def dump_things_service(dump_stores_simple):
|
|
|
|
# Start a server on an unused port
|
|
port = _get_unused_port()
|
|
process_info = subprocess.Popen(
|
|
['dump-things-service', '--port', str(port), str(dump_stores_simple)],
|
|
)
|
|
|
|
# Wait until the server is responding to requests
|
|
waited = 1
|
|
while True:
|
|
time.sleep(1)
|
|
try:
|
|
result = requests.get(f'http://127.0.0.1:{port}/server')
|
|
if result.status_code == 200:
|
|
break
|
|
msg = f'dump-things-server responded with {result.status_code}: {result.text}'
|
|
raise ValueError(msg)
|
|
except requests.exceptions.ConnectionError:
|
|
waited += 1
|
|
if waited >= 10:
|
|
raise Exception from None
|
|
continue
|
|
|
|
# Give the port and storage location to the user
|
|
yield port, dump_stores_simple
|
|
|
|
# Shut the server down
|
|
os.kill(process_info.pid, signal.SIGTERM)
|
|
os.waitpid(process_info.pid, 0)
|
|
|
|
|
|
def _get_unused_port() -> int:
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
s.bind(('', 0))
|
|
addr = s.getsockname()
|
|
s.close()
|
|
return addr[1]
|