Skip to content

Commit

Permalink
Merge pull request #188 from SciCatProject/fix-backend-ci-tests
Browse files Browse the repository at this point in the history
Attempt to fix backend ci tests
  • Loading branch information
jl-wynen authored Jan 22, 2024
2 parents e26db2f + dfb8a81 commit 26ef3b4
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 37 deletions.
2 changes: 2 additions & 0 deletions docs/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Breaking changes
Bugfixes
~~~~~~~~

* Fixed testing setup to explicitly define user accounts in the test backend.

Documentation
~~~~~~~~~~~~~

Expand Down
8 changes: 3 additions & 5 deletions src/scitacean/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ def _log_in_via_users_login(
)
if not response.ok:
get_logger().info(
"Failed to log in via endpoint Users/login: %s", response.json()["error"]
"Failed to log in via endpoint Users/login: %s", response.text
)
return response

Expand All @@ -1129,9 +1129,7 @@ def _log_in_via_auth_msad(
timeout=timeout.seconds,
)
if not response.ok:
get_logger().error(
"Failed to log in via auth/msad: %s", response.json()["error"]
)
get_logger().error("Failed to log in via auth/msad: %s", response.text)
return response


Expand Down Expand Up @@ -1159,7 +1157,7 @@ def _get_token(
if response.ok:
return str(response.json()["access_token"])

get_logger().error("Failed log in: %s", response.json()["error"])
get_logger().error("Failed log in: %s", response.text)
raise ScicatLoginError(response.content)


Expand Down
3 changes: 0 additions & 3 deletions src/scitacean/testing/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def test_manual_client(require_scicat_backend, scicat_access):
add_pytest_option
backend_enabled
can_connect
configure
skip_if_not_backend
start_backend
Expand All @@ -73,7 +72,6 @@ def test_manual_client(require_scicat_backend, scicat_access):

from . import config, seed
from ._backend import (
can_connect,
configure,
start_backend,
stop_backend,
Expand All @@ -84,7 +82,6 @@ def test_manual_client(require_scicat_backend, scicat_access):
__all__ = [
"add_pytest_option",
"backend_enabled",
"can_connect",
"config",
"configure",
"seed",
Expand Down
33 changes: 23 additions & 10 deletions src/scitacean/testing/backend/_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import time
from copy import deepcopy
from pathlib import Path
from typing import Any, Dict, Union
from urllib.parse import urljoin

Expand Down Expand Up @@ -35,7 +36,9 @@ def _docker_compose_template() -> Dict[str, Any]:
return template # type: ignore[no-any-return]


def _apply_config(template: Dict[str, Any]) -> Dict[str, Any]:
def _apply_config(
template: Dict[str, Any], account_config_path: Path
) -> Dict[str, Any]:
res = deepcopy(template)
scicat = res["services"]["scicat"]
ports = scicat["ports"][0].split(":")
Expand All @@ -46,6 +49,10 @@ def _apply_config(template: Dict[str, Any]) -> Dict[str, Any]:
env["PID_PREFIX"] = config.PID_PREFIX
env["SITE"] = config.SITE

scicat["volumes"] = [
f"{account_config_path}:/home/node/app/functionalAccounts.json",
]

return res


Expand All @@ -57,7 +64,9 @@ def configure(target_path: _PathLike) -> None:
target_path:
Generate a docker-compose file at this path.
"""
c = yaml.dump(_apply_config(_docker_compose_template()))
account_config_path = Path(target_path).parent / "functionalAccounts.json"
config.dump_account_config(account_config_path)
c = yaml.dump(_apply_config(_docker_compose_template(), account_config_path))
if "PLACEHOLDER" in c:
raise RuntimeError("Incorrect config")

Expand All @@ -75,13 +84,14 @@ def stop_backend(docker_compose_file: _PathLike) -> None:
docker_compose_down(docker_compose_file)


def can_connect() -> bool:
def _can_connect() -> tuple[bool, str]:
"""Test the connection to the testing SciCat backend.
Returns
-------
:
True if the backend is reachable, False otherwise.
The first element indicates whether the connection was successful.
The second element is an error message.
"""
scicat_access = config.local_access("user1")
try:
Expand All @@ -90,9 +100,11 @@ def can_connect() -> bool:
json=scicat_access.user.credentials,
timeout=0.5,
)
except requests.ConnectionError:
return False
return response.ok
except requests.ConnectionError as err:
return False, str(err)
if response.ok:
return True, ""
return False, str(f"{response}: {response.text}")


def wait_until_backend_is_live(max_time: float, n_tries: int) -> None:
Expand All @@ -116,8 +128,9 @@ def wait_until_backend_is_live(max_time: float, n_tries: int) -> None:
If no connection can be made within the time limit.
"""
for _ in range(n_tries):
if can_connect():
if _can_connect()[0]:
return
time.sleep(max_time / n_tries)
if not can_connect():
raise RuntimeError("Cannot connect to backend")
ok, err = _can_connect()
if not ok:
raise RuntimeError(f"Cannot connect to backend: {err}")
22 changes: 20 additions & 2 deletions src/scitacean/testing/backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
# Copyright (c) 2024 SciCat Project (https://github.com/SciCatProject/scitacean)
"""Backend configuration."""

import json
from dataclasses import dataclass
from typing import Dict
from pathlib import Path
from typing import Union


@dataclass
Expand All @@ -23,7 +25,7 @@ class SciCatUser:
group: str

@property
def credentials(self) -> Dict[str, str]:
def credentials(self) -> dict[str, str]:
"""Return login credentials for this user.
User as
Expand All @@ -37,6 +39,16 @@ def credentials(self) -> Dict[str, str]:
"password": self.password,
}

def dump(self) -> dict[str, Union[str, bool]]:
"""Return a dict that can be serialized to functionalAccounts.json."""
return {
"username": self.username,
"password": self.password,
"email": self.email,
"role": self.group,
"global": False,
}


# see https://github.com/SciCatProject/scicat-backend-next/blob/master/src/config/configuration.ts
USERS = {
Expand Down Expand Up @@ -116,3 +128,9 @@ def local_access(user: str) -> SciCatAccess:
Parameters for the local SciCat backend.
"""
return SciCatAccess(url=f"http://localhost:{SCICAT_PORT}/api/v3/", user=USERS[user])


def dump_account_config(path: Path) -> None:
"""Write a functional account config for the backend."""
with path.open("w") as f:
json.dump([user.dump() for user in USERS.values()], f)
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@

services:
mongodb:
image: bitnami/mongodb:4.2
volumes:
- mongodb_data:/bitnami
image: mongo:latest
ports:
- "27017:27017"

Expand All @@ -26,6 +24,7 @@ services:
- 3000:PLACEHOLDER
environment:
DOI_PREFIX: DOI.SAMPLE.PREFIX
ELASTICSEARCH_ENABLED: no
HTTP_MAX_REDIRECTS: 1 # Scitacean should not require redirects
HTTP_TIMEOUT: 5000 # in ms
JWT_EXPIRES_IN: 3600 # in s (expiry of token)
Expand All @@ -37,7 +36,3 @@ services:
PID_PREFIX: PLACEHOLDER
SITE: PLACEHOLDER
PORT: PLACEHOLDER

volumes:
mongodb_data:
driver: local
2 changes: 0 additions & 2 deletions src/scitacean/testing/sftp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,13 @@ def test_sftp_upload(
IgnorePolicy,
SFTPAccess,
SFTPUser,
can_connect,
configure,
local_access,
wait_until_sftp_server_is_live,
)

__all__ = [
"add_pytest_option",
"can_connect",
"configure",
"local_access",
"sftp_enabled",
Expand Down
6 changes: 3 additions & 3 deletions src/scitacean/testing/sftp/_sftp.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def configure(target_dir: Union[Path, str]) -> Path:
return config_target


def can_connect(sftp_access: SFTPAccess) -> bool:
def _can_connect(sftp_access: SFTPAccess) -> bool:
try:
_make_client(sftp_access)
except paramiko.SSHException:
Expand All @@ -121,10 +121,10 @@ def wait_until_sftp_server_is_live(
) -> None:
# The container takes a while to be fully live.
for _ in range(n_tries):
if can_connect(sftp_access):
if _can_connect(sftp_access):
return
time.sleep(max_time / n_tries)
if not can_connect(sftp_access):
if not _can_connect(sftp_access):
raise RuntimeError("Cannot connect to SFTP server")


Expand Down
2 changes: 0 additions & 2 deletions src/scitacean/testing/ssh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,13 @@ def test_ssh_upload(
IgnorePolicy,
SSHAccess,
SSHUser,
can_connect,
configure,
local_access,
wait_until_ssh_server_is_live,
)

__all__ = [
"add_pytest_option",
"can_connect",
"configure",
"local_access",
"ssh_enabled",
Expand Down
6 changes: 3 additions & 3 deletions src/scitacean/testing/ssh/_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def configure(target_dir: Union[Path, str]) -> Path:
return config_target


def can_connect(ssh_access: SSHAccess) -> bool:
def _can_connect(ssh_access: SSHAccess) -> bool:
try:
_make_client(ssh_access)
except paramiko.SSHException:
Expand All @@ -111,10 +111,10 @@ def wait_until_ssh_server_is_live(
) -> None:
# The container takes a while to be fully live.
for _ in range(n_tries):
if can_connect(ssh_access):
if _can_connect(ssh_access):
return
time.sleep(max_time / n_tries)
if not can_connect(ssh_access):
if not _can_connect(ssh_access):
raise RuntimeError("Cannot connect to SSH server")


Expand Down

0 comments on commit 26ef3b4

Please sign in to comment.