From ca3f5f91b521b59c9c831b58e53ce182b68d7334 Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Mon, 10 Feb 2025 17:54:27 +0100 Subject: [PATCH] tests: removed docker-compose tests and moved instead to fakeredis and mongomock --- .gitlab-ci.yml | 70 +- .../bec_atlas/datasources/mongodb/mongodb.py | 16 +- .../bec_atlas/datasources/redis_datasource.py | 25 +- backend/bec_atlas/ingestor/data_ingestor.py | 10 +- backend/bec_atlas/router/scan_router.py | 1 + backend/pyproject.toml | 3 +- backend/tests/conftest.py | 216 ++--- backend/tests/export_test_data.py | 29 + .../bec_atlas.deployment_access.json | 13 + .../bec_atlas.deployment_credentials.json | 1 + .../test_data/bec_atlas.deployments.json | 12 + backend/tests/test_data/bec_atlas.scans.json | 914 ++++++++++++++++++ .../tests/test_data/bec_atlas.sessions.json | 9 + .../test_data/bec_atlas.user_credentials.json | 18 + backend/tests/test_data/bec_atlas.users.json | 22 + backend/tests/test_scan_ingestor.py | 191 ++-- 16 files changed, 1302 insertions(+), 248 deletions(-) create mode 100644 backend/tests/export_test_data.py create mode 100644 backend/tests/test_data/bec_atlas.deployment_access.json create mode 100644 backend/tests/test_data/bec_atlas.deployment_credentials.json create mode 100644 backend/tests/test_data/bec_atlas.deployments.json create mode 100644 backend/tests/test_data/bec_atlas.scans.json create mode 100644 backend/tests/test_data/bec_atlas.sessions.json create mode 100644 backend/tests/test_data/bec_atlas.user_credentials.json create mode 100644 backend/tests/test_data/bec_atlas.users.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2fe4226..cfcb2c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,6 +39,18 @@ stages: include: - template: Security/Secret-Detection.gitlab-ci.yml +before_script: + - if [[ "$CI_PROJECT_PATH" != "bec/bec_atlas" ]]; then + echo -e "\033[35;1m Using branch $CHILD_PIPELINE_BRANCH of BEC Atlas \033[0;m"; + test -d bec_atlas || git clone --branch $CHILD_PIPELINE_BRANCH https://gitlab.psi.ch/bec/bec_atlas.git; cd bec_atlas; + fi + - pip install ./backend[dev] + - git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git + - pip install ./bec/bec_lib[dev] + + # Remove the following line once there is a new release of fakeredis-py + - pip install git+https://github.com/cunla/fakeredis-py.git + formatter: stage: Formatter needs: [] @@ -82,28 +94,13 @@ pylint: backend_pytest: stage: test - image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:23-dind - services: - - name: docker:dind - entrypoint: ["dockerd-entrypoint.sh", "--tls=false"] + image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.11 needs: [] script: - - if [[ "$CI_PROJECT_PATH" != "bec/bec_atlas" ]]; then - apk update; apk add git; echo -e "\033[35;1m Using branch $CHILD_PIPELINE_BRANCH of BEC Atlas \033[0;m"; - test -d bec_atlas || git clone --branch $CHILD_PIPELINE_BRANCH https://gitlab.psi.ch/bec/bec_atlas.git; cd bec_atlas; - TARGET_BRANCH=$CHILD_PIPELINE_BRANCH; - else - TARGET_BRANCH=$CI_COMMIT_REF_NAME; - fi - # start services - - docker-compose -f ./backend/tests/docker-compose.yml up -d - - # build test environment - - echo "$CI_DEPENDENCY_PROXY_PASSWORD" | docker login $CI_DEPENDENCY_PROXY_SERVER --username $CI_DEPENDENCY_PROXY_USER --password-stdin - - docker build -t bec_atlas_backend:test -f ./backend/tests/Dockerfile.run_pytest --build-arg PY_VERSION=3.10 --build-arg BEC_ATLAS_BRANCH=$TARGET_BRANCH --build-arg BEC_CORE_BRANCH=$BEC_CORE_BRANCH --build-arg CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX . - - docker run --network=host --name bec_atlas_backend bec_atlas_backend:test - after_script: - - docker cp bec_atlas_backend:/code/bec_atlas/test_files/. $CI_PROJECT_DIR + - pip install coverage + - coverage run --source=./backend --omit=*/backend/tests/* -m pytest -v --junitxml=report.xml --random-order --full-trace ./backend/tests + - coverage report + - coverage xml coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/' artifacts: reports: @@ -113,6 +110,39 @@ backend_pytest: path: coverage.xml interruptible: true +# backend_pytest: +# stage: test +# image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:23-dind +# services: +# - name: docker:dind +# entrypoint: ["dockerd-entrypoint.sh", "--tls=false"] +# needs: [] +# script: +# - if [[ "$CI_PROJECT_PATH" != "bec/bec_atlas" ]]; then +# apk update; apk add git; echo -e "\033[35;1m Using branch $CHILD_PIPELINE_BRANCH of BEC Atlas \033[0;m"; +# test -d bec_atlas || git clone --branch $CHILD_PIPELINE_BRANCH https://gitlab.psi.ch/bec/bec_atlas.git; cd bec_atlas; +# TARGET_BRANCH=$CHILD_PIPELINE_BRANCH; +# else +# TARGET_BRANCH=$CI_COMMIT_REF_NAME; +# fi +# # start services +# - docker-compose -f ./backend/tests/docker-compose.yml up -d + +# # build test environment +# - echo "$CI_DEPENDENCY_PROXY_PASSWORD" | docker login $CI_DEPENDENCY_PROXY_SERVER --username $CI_DEPENDENCY_PROXY_USER --password-stdin +# - docker build -t bec_atlas_backend:test -f ./backend/tests/Dockerfile.run_pytest --build-arg PY_VERSION=3.10 --build-arg BEC_ATLAS_BRANCH=$TARGET_BRANCH --build-arg BEC_CORE_BRANCH=$BEC_CORE_BRANCH --build-arg CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX . +# - docker run --network=host --name bec_atlas_backend bec_atlas_backend:test +# after_script: +# - docker cp bec_atlas_backend:/code/bec_atlas/test_files/. $CI_PROJECT_DIR +# coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/' +# artifacts: +# reports: +# junit: report.xml +# coverage_report: +# coverage_format: cobertura +# path: coverage.xml +# interruptible: true + # semver: # stage: Deploy # needs: ["backend_pytest"] diff --git a/backend/bec_atlas/datasources/mongodb/mongodb.py b/backend/bec_atlas/datasources/mongodb/mongodb.py index e0d60e6..eea78f9 100644 --- a/backend/bec_atlas/datasources/mongodb/mongodb.py +++ b/backend/bec_atlas/datasources/mongodb/mongodb.py @@ -33,15 +33,19 @@ class MongoDBDatasource: port = self.config.get("port") username = self.config.get("username") password = self.config.get("password") - if username and password: - self.client = pymongo.MongoClient( - f"mongodb://{username}:{password}@{host}:{port}/?authSource=bec_atlas" - ) + + if self.config.get("mongodb_client"): + self.client = self.config.get("mongodb_client") else: - self.client = pymongo.MongoClient(f"mongodb://{host}:{port}/") + if username and password: + self.client = pymongo.MongoClient( + f"mongodb://{username}:{password}@{host}:{port}/?authSource=bec_atlas" + ) + else: + self.client = pymongo.MongoClient(f"mongodb://{host}:{port}/") # Check if the connection is successful - self.client.list_databases() + self.client.list_database_names() logger.info(f"Connecting to MongoDB at {host}:{port}") self.db = self.client["bec_atlas"] diff --git a/backend/bec_atlas/datasources/redis_datasource.py b/backend/bec_atlas/datasources/redis_datasource.py index 5988348..b9bb295 100644 --- a/backend/bec_atlas/datasources/redis_datasource.py +++ b/backend/bec_atlas/datasources/redis_datasource.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING from bec_lib.redis_connector import RedisConnector from redis.asyncio import Redis as AsyncRedis -from redis.exceptions import AuthenticationError +from redis.exceptions import AuthenticationError, ResponseError if TYPE_CHECKING: from bec_atlas.model.model import DeploymentCredential @@ -13,14 +13,18 @@ if TYPE_CHECKING: class RedisDatasource: def __init__(self, config: dict): self.config = config - self.connector = RedisConnector(f"{config.get('host')}:{config.get('port')}") + + if config.get("sync_instance"): + self.connector = config.get("sync_instance") + else: + self.connector = RedisConnector(f"{config.get('host')}:{config.get('port')}") username = config.get("username") password = config.get("password") try: self.connector._redis_conn.auth(password, username=username) self.reconfigured_acls = False - except AuthenticationError: + except (AuthenticationError, ResponseError): self.setup_acls() self.connector._redis_conn.auth(password, username=username) self.reconfigured_acls = True @@ -28,12 +32,15 @@ class RedisDatasource: self.connector._redis_conn.connection_pool.connection_kwargs["username"] = username self.connector._redis_conn.connection_pool.connection_kwargs["password"] = password - self.async_connector = AsyncRedis( - host=config.get("host"), - port=config.get("port"), - username="ingestor", - password=config.get("password"), - ) + if config.get("async_instance"): + self.async_connector = config.get("async_instance") + else: + self.async_connector = AsyncRedis( + host=config.get("host"), + port=config.get("port"), + username="ingestor", + password=config.get("password"), + ) print("Connected to Redis") def setup_acls(self): diff --git a/backend/bec_atlas/ingestor/data_ingestor.py b/backend/bec_atlas/ingestor/data_ingestor.py index 709df59..e3b3955 100644 --- a/backend/bec_atlas/ingestor/data_ingestor.py +++ b/backend/bec_atlas/ingestor/data_ingestor.py @@ -29,9 +29,13 @@ class DataIngestor: redis_host = config.get("redis", {}).get("host", "localhost") redis_port = config.get("redis", {}).get("port", 6380) - self.redis = RedisConnector( - f"{redis_host}:{redis_port}" # username="ingestor", password="ingestor" - ) + + if config.get("redis", {}).get("sync_instance"): + self.redis = config.get("redis", {}).get("sync_instance") + else: + self.redis = RedisConnector( + f"{redis_host}:{redis_port}" # username="ingestor", password="ingestor" + ) # self.redis.authenticate( # config.get("redis", {}).get("password", "ingestor"), username="ingestor" # ) diff --git a/backend/bec_atlas/router/scan_router.py b/backend/bec_atlas/router/scan_router.py index d138f15..c1ff772 100644 --- a/backend/bec_atlas/router/scan_router.py +++ b/backend/bec_atlas/router/scan_router.py @@ -170,3 +170,4 @@ class ScanRouter(BaseRouter): out = self.db.aggregate("scans", pipeline=pipeline, dtype=None, user=current_user) if out: return out[0] + return {"count": 0} diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 2689740..246f398 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -33,7 +33,8 @@ dev = [ "pytest-random-order~=1.1", "pytest-timeout~=2.2", "pytest~=8.0", - "pytest-docker", + "fakeredis", + "mongomock~=4.3", "isort~=5.13, >=5.13.2", "pytest-asyncio", ] diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index befcda6..9651836 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -1,147 +1,121 @@ -import contextlib +import json import os -from typing import Iterator +from unittest import mock +import fakeredis +import mongomock +import pymongo import pytest +from bec_lib.redis_connector import RedisConnector +from bson import ObjectId from fastapi.testclient import TestClient -from pytest_docker.plugin import DockerComposeExecutor, Services from bec_atlas.main import AtlasApp +from bec_atlas.router.redis_router import BECAsyncRedisManager -def pytest_addoption(parser): - parser.addoption( - "--skip-docker", - action="store_true", - default=False, - help="Skip spinning up docker containers", - ) +def import_mongodb_data(mongo_client: pymongo.MongoClient): + """ + Import the test data into the mongodb container. The data is stored in the + tests/test_data directory as json files per collection. + + Args: + mongo_client (pymongo.MongoClient): The mongo client + """ + client = mongo_client + db = client["bec_atlas"] + + collections = [ + # "bec_access_profiles", + "deployment_access", + "deployment_credentials", + "deployments", + # "fs.chunks", + # "fs.files", + "scans", + "sessions", + "user_credentials", + "users", + ] + + for collection in collections: + db.drop_collection(collection) + + current_dir = os.path.dirname(os.path.abspath(__file__)) + + for collection in collections: + with open( + f"{current_dir}/test_data/bec_atlas.{collection}.json", "r", encoding="utf-8" + ) as f: + data = f.read() + data = json.loads(data) + data = [convert_to_object_id(d) for d in data] + + db[collection].insert_many(data) + client.close() + + +def convert_to_object_id(data): + """ + Convert the _id field in the data to an ObjectId. + + Args: + data (dict): The data + + Returns: + dict: The data with the _id field converted to an ObjectId + """ + if isinstance(data, dict) and "$oid" in data: + return ObjectId(data["$oid"]) + if isinstance(data, dict): + for key, value in data.items(): + data[key] = convert_to_object_id(value) + return data @pytest.fixture(scope="session") -def docker_compose_file(pytestconfig): - test_directory = os.path.dirname(os.path.abspath(__file__)) - return os.path.join(test_directory, "docker-compose.yml") +def redis_server(): + redis_server = fakeredis.FakeServer() + yield redis_server @pytest.fixture(scope="session") -def docker_compose_project_name() -> str: - """Generate a project name using the current process PID. Override this - fixture in your tests if you need a particular project name.""" +def backend(redis_server): - return "pytest_9070_atlas" + def _fake_redis(host, port): + return fakeredis.FakeStrictRedis(server=redis_server) + mongo_client = mongomock.MongoClient("localhost", 27027) -@contextlib.contextmanager -def get_docker_services( - docker_compose_command: str, - docker_compose_file: list[str] | str, - docker_compose_project_name: str, - docker_setup: list[str] | str, - docker_cleanup: list[str] | str, -) -> Iterator[Services]: - docker_compose = DockerComposeExecutor( - docker_compose_command, docker_compose_file, docker_compose_project_name - ) - - try: - if docker_cleanup: - # Maintain backwards compatibility with the string format. - if isinstance(docker_cleanup, str): - docker_cleanup = [docker_cleanup] - for command in docker_cleanup: - docker_compose.execute(command) - except Exception: - pass - - # setup containers. - if docker_setup: - # Maintain backwards compatibility with the string format. - if isinstance(docker_setup, str): - docker_setup = [docker_setup] - for command in docker_setup: - docker_compose.execute(command) - - try: - # Let test(s) run. - yield Services(docker_compose) - finally: - # Clean up. - if docker_cleanup: - # Maintain backwards compatibility with the string format. - if isinstance(docker_cleanup, str): - docker_cleanup = [docker_cleanup] - for command in docker_cleanup: - docker_compose.execute(command) - - -@pytest.fixture(scope="session") -def docker_services( - docker_compose_command: str, - docker_compose_file: list[str] | str, - docker_compose_project_name: str, - docker_setup: str, - docker_cleanup: str, - request, -) -> Iterator[Services]: - """Start all services from a docker compose file (`docker-compose up`). - After test are finished, shutdown all services (`docker-compose down`).""" - - if request.config.getoption("--skip-docker"): - yield - return - - with get_docker_services( - docker_compose_command, - docker_compose_file, - docker_compose_project_name, - docker_setup, - docker_cleanup, - ) as docker_service: - yield docker_service - - -@pytest.fixture(scope="session") -def redis_container(docker_ip, docker_services): - host = docker_ip - if os.path.exists("/.dockerenv"): - host = "redis" - if docker_services is None: - port = 6380 - else: - port = docker_services.port_for("redis", 6379) - - return "localhost", port - - -@pytest.fixture(scope="session") -def mongo_container(docker_ip, docker_services): - host = docker_ip - if os.path.exists("/.dockerenv"): - host = "mongo" - if docker_services is None: - port = 27017 - else: - port = docker_services.port_for("mongodb", 27017) - - return "localhost", port - - -@pytest.fixture(scope="session") -def backend(redis_container, mongo_container): - redis_host, redis_port = redis_container - mongo_host, mongo_port = mongo_container config = { "redis": { - "host": redis_host, - "port": redis_port, + "host": "localhost", + "port": 6480, "username": "ingestor", "password": "ingestor", + "sync_instance": RedisConnector("localhost:1", redis_cls=_fake_redis), + "async_instance": fakeredis.FakeAsyncRedis(server=redis_server), }, - "mongodb": {"host": mongo_host, "port": mongo_port}, + "mongodb": {"host": "localhost", "port": 27027, "mongodb_client": mongo_client}, } + import_mongodb_data(mongo_client) + app = AtlasApp(config) - with TestClient(app.app) as _client: - yield _client, app + class PatchedBECAsyncRedisManager(BECAsyncRedisManager): + def _redis_connect(self): + self.redis = fakeredis.FakeAsyncRedis( + server=redis_server, + username=config["redis"]["username"], + password=config["redis"]["password"], + ) + self.redis.connection_pool.connection_kwargs["username"] = config["redis"]["username"] + self.redis.connection_pool.connection_kwargs["password"] = config["redis"]["password"] + self.pubsub = self.redis.pubsub(ignore_subscribe_messages=True) + + with mock.patch( + "bec_atlas.router.redis_router.BECAsyncRedisManager", PatchedBECAsyncRedisManager + ): + with TestClient(app.app) as _client: + yield _client, app diff --git a/backend/tests/export_test_data.py b/backend/tests/export_test_data.py new file mode 100644 index 0000000..9748fe2 --- /dev/null +++ b/backend/tests/export_test_data.py @@ -0,0 +1,29 @@ +import os + + +def export_mongodb_data(host: str, port: int): + """Export data from MongoDB to a JSON file.""" + + collections = [ + "bec_access_profiles", + "deployment_access", + "deployment_credentials", + "deployments", + "fs.chunks", + "fs.files", + "scans", + "sessions", + "user_credentials", + "users", + ] + + current_dir = os.path.dirname(os.path.abspath(__file__)) + + for collection in collections: + os.system( + f"mongoexport --host {host} --port {port} --db bec_atlas --collection {collection} --jsonArray --out {current_dir}/test_data/bec_atlas.{collection}.json" + ) + + +if __name__ == "__main__": + export_mongodb_data("localhost", 27017) diff --git a/backend/tests/test_data/bec_atlas.deployment_access.json b/backend/tests/test_data/bec_atlas.deployment_access.json new file mode 100644 index 0000000..61d2002 --- /dev/null +++ b/backend/tests/test_data/bec_atlas.deployment_access.json @@ -0,0 +1,13 @@ +[ + { + "_id": { "$oid": "678aa8d4875568640bd92176" }, + "owner_groups": ["admin", "demo"], + "access_groups": [], + "user_read_access": [], + "user_write_access": [], + "su_read_access": [], + "su_write_access": [], + "remote_read_access": [], + "remote_write_access": [] + } +] diff --git a/backend/tests/test_data/bec_atlas.deployment_credentials.json b/backend/tests/test_data/bec_atlas.deployment_credentials.json new file mode 100644 index 0000000..ebc2035 --- /dev/null +++ b/backend/tests/test_data/bec_atlas.deployment_credentials.json @@ -0,0 +1 @@ +[{ "_id": { "$oid": "678aa8d4875568640bd92176" }, "credential": "Ae4833LFqPQHwDKH_iV1HJ--wcdGLWOjjRCrCxxYGKs" }] diff --git a/backend/tests/test_data/bec_atlas.deployments.json b/backend/tests/test_data/bec_atlas.deployments.json new file mode 100644 index 0000000..8304dcd --- /dev/null +++ b/backend/tests/test_data/bec_atlas.deployments.json @@ -0,0 +1,12 @@ +[ + { + "_id": { "$oid": "678aa8d4875568640bd92176" }, + "owner_groups": ["admin", "demo"], + "access_groups": ["demo"], + "id": null, + "realm_id": "demo_beamline_1", + "name": "Demo Deployment 1", + "active_session_id": null, + "config_templates": [] + } +] diff --git a/backend/tests/test_data/bec_atlas.scans.json b/backend/tests/test_data/bec_atlas.scans.json new file mode 100644 index 0000000..d04b286 --- /dev/null +++ b/backend/tests/test_data/bec_atlas.scans.json @@ -0,0 +1,914 @@ +[ + { + "_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "metadata": {}, + "scan_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "status": "closed", + "scan_number": 2254, + "num_points": 400, + "scan_name": "line_scan", + "scan_type": "step", + "dataset_number": 2253, + "scan_report_devices": ["samx"], + "user_metadata": {}, + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { "file_suffix": null, "file_directory": null } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { "steps": 400, "relative": false, "system_config": { "file_suffix": null, "file_directory": null } } + }, + "info": { + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "file_suffix": null, + "file_directory": null, + "user_metadata": {}, + "RID": "22a3a0e0-64f8-426d-b58e-1de75ef58c6f", + "scan_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "queue_id": "a8984b11-214e-41ac-9a03-2690600b3f3c", + "scan_motors": ["samx"], + "num_points": 400, + "positions": [ + [-20.0], + [-19.899749373433583], + [-19.79949874686717], + [-19.69924812030075], + [-19.598997493734338], + [-19.49874686716792], + [-19.398496240601503], + [-19.29824561403509], + [-19.19799498746867], + [-19.097744360902254], + [-18.99749373433584], + [-18.897243107769423], + [-18.796992481203006], + [-18.696741854636592], + [-18.596491228070175], + [-18.49624060150376], + [-18.395989974937343], + [-18.295739348370926], + [-18.195488721804512], + [-18.095238095238095], + [-17.99498746867168], + [-17.894736842105264], + [-17.794486215538846], + [-17.694235588972433], + [-17.593984962406015], + [-17.493734335839598], + [-17.393483709273184], + [-17.293233082706767], + [-17.19298245614035], + [-17.092731829573935], + [-16.992481203007518], + [-16.892230576441104], + [-16.791979949874687], + [-16.69172932330827], + [-16.591478696741856], + [-16.49122807017544], + [-16.390977443609025], + [-16.290726817042607], + [-16.19047619047619], + [-16.090225563909776], + [-15.989974937343359], + [-15.889724310776943], + [-15.789473684210527], + [-15.68922305764411], + [-15.588972431077694], + [-15.488721804511279], + [-15.388471177944862], + [-15.288220551378446], + [-15.18796992481203], + [-15.087719298245615], + [-14.9874686716792], + [-14.887218045112782], + [-14.786967418546366], + [-14.68671679197995], + [-14.586466165413533], + [-14.486215538847118], + [-14.385964912280702], + [-14.285714285714286], + [-14.18546365914787], + [-14.085213032581454], + [-13.984962406015038], + [-13.884711779448622], + [-13.784461152882205], + [-13.68421052631579], + [-13.583959899749374], + [-13.483709273182958], + [-13.383458646616543], + [-13.283208020050125], + [-13.18295739348371], + [-13.082706766917294], + [-12.982456140350877], + [-12.882205513784461], + [-12.781954887218046], + [-12.68170426065163], + [-12.581453634085214], + [-12.481203007518797], + [-12.380952380952381], + [-12.280701754385966], + [-12.180451127819548], + [-12.080200501253133], + [-11.979949874686717], + [-11.879699248120302], + [-11.779448621553886], + [-11.679197994987469], + [-11.578947368421053], + [-11.478696741854638], + [-11.37844611528822], + [-11.278195488721805], + [-11.177944862155389], + [-11.077694235588973], + [-10.977443609022558], + [-10.87719298245614], + [-10.776942355889725], + [-10.67669172932331], + [-10.576441102756892], + [-10.476190476190476], + [-10.37593984962406], + [-10.275689223057645], + [-10.17543859649123], + [-10.075187969924812], + [-9.974937343358397], + [-9.874686716791981], + [-9.774436090225564], + [-9.674185463659148], + [-9.573934837092732], + [-9.473684210526317], + [-9.373433583959901], + [-9.273182957393484], + [-9.172932330827068], + [-9.072681704260653], + [-8.972431077694235], + [-8.87218045112782], + [-8.771929824561404], + [-8.671679197994989], + [-8.571428571428573], + [-8.471177944862156], + [-8.37092731829574], + [-8.270676691729324], + [-8.170426065162907], + [-8.070175438596491], + [-7.969924812030076], + [-7.86967418546366], + [-7.769423558897245], + [-7.669172932330827], + [-7.568922305764412], + [-7.468671679197996], + [-7.368421052631579], + [-7.268170426065163], + [-7.167919799498748], + [-7.067669172932332], + [-6.967418546365916], + [-6.867167919799499], + [-6.766917293233083], + [-6.666666666666668], + [-6.5664160401002505], + [-6.466165413533835], + [-6.365914786967419], + [-6.265664160401004], + [-6.165413533834588], + [-6.065162907268171], + [-5.964912280701755], + [-5.86466165413534], + [-5.764411027568922], + [-5.664160401002507], + [-5.563909774436091], + [-5.463659147869675], + [-5.36340852130326], + [-5.2631578947368425], + [-5.162907268170427], + [-5.062656641604011], + [-4.962406015037594], + [-4.862155388471178], + [-4.761904761904763], + [-4.661654135338347], + [-4.561403508771932], + [-4.461152882205514], + [-4.360902255639099], + [-4.260651629072683], + [-4.160401002506266], + [-4.06015037593985], + [-3.9598997493734345], + [-3.859649122807017], + [-3.7593984962406033], + [-3.659147869674186], + [-3.558897243107772], + [-3.4586466165413547], + [-3.3583959899749374], + [-3.2581453634085236], + [-3.157894736842106], + [-3.057644110275689], + [-2.957393483709275], + [-2.8571428571428577], + [-2.7568922305764403], + [-2.6566416040100265], + [-2.556390977443609], + [-2.4561403508771953], + [-2.355889724310778], + [-2.2556390977443606], + [-2.1553884711779467], + [-2.0551378446115294], + [-1.9548872180451156], + [-1.8546365914786982], + [-1.7543859649122808], + [-1.654135338345867], + [-1.5538847117794496], + [-1.4536340852130323], + [-1.3533834586466185], + [-1.253132832080201], + [-1.1528822055137837], + [-1.05263157894737], + [-0.9523809523809526], + [-0.8521303258145387], + [-0.7518796992481214], + [-0.651629072681704], + [-0.5513784461152902], + [-0.4511278195488728], + [-0.350877192982459], + [-0.25062656641604164], + [-0.15037593984962427], + [-0.05012531328321046], + [0.05012531328320691], + [0.15037593984962427], + [0.2506265664160381], + [0.35087719298245545], + [0.4511278195488728], + [0.5513784461152866], + [0.651629072681704], + [0.7518796992481178], + [0.8521303258145352], + [0.9523809523809526], + [1.0526315789473664], + [1.1528822055137837], + [1.2531328320801975], + [1.353383458646615], + [1.4536340852130323], + [1.553884711779446], + [1.6541353383458635], + [1.7543859649122808], + [1.8546365914786946], + [1.954887218045112], + [2.0551378446115294], + [2.155388471177943], + [2.2556390977443606], + [2.3558897243107744], + [2.4561403508771917], + [2.556390977443609], + [2.656641604010023], + [2.7568922305764403], + [2.857142857142854], + [2.9573934837092715], + [3.057644110275689], + [3.1578947368421026], + [3.25814536340852], + [3.3583959899749374], + [3.458646616541351], + [3.5588972431077686], + [3.659147869674186], + [3.7593984962405997], + [3.859649122807017], + [3.959899749373431], + [4.060150375939848], + [4.160401002506266], + [4.2606516290726795], + [4.360902255639097], + [4.461152882205511], + [4.561403508771928], + [4.661654135338345], + [4.761904761904759], + [4.862155388471177], + [4.962406015037594], + [5.062656641604008], + [5.162907268170425], + [5.2631578947368425], + [5.363408521303256], + [5.463659147869674], + [5.5639097744360875], + [5.664160401002505], + [5.764411027568922], + [5.864661654135336], + [5.964912280701753], + [6.065162907268167], + [6.165413533834585], + [6.265664160401002], + [6.365914786967416], + [6.466165413533833], + [6.5664160401002505], + [6.666666666666664], + [6.766917293233082], + [6.867167919799499], + [6.967418546365913], + [7.06766917293233], + [7.167919799498744], + [7.268170426065161], + [7.368421052631579], + [7.468671679197993], + [7.56892230576441], + [7.669172932330824], + [7.769423558897241], + [7.8696741854636585], + [7.969924812030072], + [8.07017543859649], + [8.170426065162907], + [8.27067669172932], + [8.370927318295738], + [8.471177944862156], + [8.57142857142857], + [8.671679197994987], + [8.7719298245614], + [8.872180451127818], + [8.972431077694235], + [9.07268170426065], + [9.172932330827066], + [9.27318295739348], + [9.373433583959898], + [9.473684210526315], + [9.573934837092729], + [9.674185463659146], + [9.774436090225564], + [9.874686716791977], + [9.974937343358395], + [10.075187969924812], + [10.175438596491226], + [10.275689223057643], + [10.375939849624057], + [10.476190476190474], + [10.576441102756892], + [10.676691729323306], + [10.776942355889723], + [10.877192982456137], + [10.977443609022554], + [11.077694235588972], + [11.177944862155385], + [11.278195488721803], + [11.37844611528822], + [11.478696741854634], + [11.578947368421051], + [11.679197994987469], + [11.779448621553883], + [11.8796992481203], + [11.979949874686714], + [12.080200501253131], + [12.180451127819545], + [12.280701754385966], + [12.38095238095238], + [12.481203007518793], + [12.581453634085214], + [12.681704260651628], + [12.781954887218042], + [12.882205513784456], + [12.982456140350877], + [13.08270676691729], + [13.182957393483704], + [13.283208020050125], + [13.383458646616539], + [13.483709273182953], + [13.583959899749374], + [13.684210526315788], + [13.784461152882201], + [13.884711779448622], + [13.984962406015036], + [14.08521303258145], + [14.18546365914787], + [14.285714285714285], + [14.385964912280699], + [14.48621553884712], + [14.586466165413533], + [14.686716791979947], + [14.78696741854636], + [14.887218045112782], + [14.987468671679196], + [15.08771929824561], + [15.18796992481203], + [15.288220551378444], + [15.388471177944858], + [15.488721804511279], + [15.588972431077693], + [15.689223057644107], + [15.789473684210527], + [15.889724310776941], + [15.989974937343355], + [16.09022556390977], + [16.19047619047619], + [16.290726817042604], + [16.390977443609017], + [16.49122807017544], + [16.591478696741852], + [16.691729323308266], + [16.791979949874687], + [16.8922305764411], + [16.992481203007515], + [17.092731829573935], + [17.19298245614035], + [17.293233082706763], + [17.393483709273184], + [17.493734335839598], + [17.59398496240601], + [17.694235588972433], + [17.794486215538846], + [17.89473684210526], + [17.994987468671674], + [18.095238095238095], + [18.19548872180451], + [18.295739348370923], + [18.395989974937343], + [18.496240601503757], + [18.59649122807017], + [18.696741854636592], + [18.796992481203006], + [18.89724310776942], + [18.99749373433584], + [19.097744360902254], + [19.197994987468668], + [19.298245614035082], + [19.398496240601503], + [19.498746867167917], + [19.59899749373433], + [19.69924812030075], + [19.799498746867165], + [19.89974937343358], + [20.0] + ], + "scan_name": "line_scan", + "scan_type": "step", + "scan_number": 2254, + "dataset_number": 2253, + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "scan_report_devices": ["samx"], + "monitor_sync": "bec", + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { "file_suffix": null, "file_directory": null } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { "steps": 400, "relative": false, "system_config": { "file_suffix": null, "file_directory": null } } + }, + "scan_msgs": [ + "metadata={'file_suffix': None, 'file_directory': None, 'user_metadata': {}, 'RID': '22a3a0e0-64f8-426d-b58e-1de75ef58c6f'} scan_type='line_scan' parameter={'args': {'samx': [-20, 20]}, 'kwargs': {'steps': 400, 'relative': False, 'system_config': {'file_suffix': None, 'file_directory': None}}} queue='primary'" + ], + "args": { "samx": [-20, 20] }, + "kwargs": { "steps": 400, "relative": false, "system_config": { "file_suffix": null, "file_directory": null } } + }, + "timestamp": 1.7377484829922938e9, + "owner_groups": ["admin"], + "access_groups": ["admin"], + "session_id": "6792392e3e28ff5364050c85" + } +] diff --git a/backend/tests/test_data/bec_atlas.sessions.json b/backend/tests/test_data/bec_atlas.sessions.json new file mode 100644 index 0000000..2deaf75 --- /dev/null +++ b/backend/tests/test_data/bec_atlas.sessions.json @@ -0,0 +1,9 @@ +[ + { + "_id": { "$oid": "6792392e3e28ff5364050c85" }, + "owner_groups": ["admin", "demo"], + "access_groups": ["demo"], + "deployment_id": "678aa8d4875568640bd92176", + "name": "_default_" + } +] diff --git a/backend/tests/test_data/bec_atlas.user_credentials.json b/backend/tests/test_data/bec_atlas.user_credentials.json new file mode 100644 index 0000000..1176282 --- /dev/null +++ b/backend/tests/test_data/bec_atlas.user_credentials.json @@ -0,0 +1,18 @@ +[ + { + "_id": { "$oid": "67a5d652d22ba335392b915a" }, + "owner_groups": ["admin"], + "access_groups": [], + "id": null, + "user_id": { "$oid": "67a5d652d22ba335392b9159" }, + "password": "$argon2id$v=19$m=65536,t=3,p=4$SjLcoiN+JHSLWDnSv6ysTw$nrqkM6a/KkJ56pTRPWQRSGP7ht9JYnhBUcB1vBOhkag" + }, + { + "_id": { "$oid": "67a5d694c13d2198c91cc47d" }, + "owner_groups": ["admin"], + "access_groups": [], + "id": null, + "user_id": { "$oid": "67a5d694c13d2198c91cc47c" }, + "password": "$argon2id$v=19$m=65536,t=3,p=4$hS1xfyCzbpUfHeNiZ54lyQ$DTZWjwHy95VWO5Btl/qcIcPfZseL+g/iljuRdMfWXok" + } +] diff --git a/backend/tests/test_data/bec_atlas.users.json b/backend/tests/test_data/bec_atlas.users.json new file mode 100644 index 0000000..7e7fcc2 --- /dev/null +++ b/backend/tests/test_data/bec_atlas.users.json @@ -0,0 +1,22 @@ +[ + { + "_id": { "$oid": "67a5d652d22ba335392b9159" }, + "owner_groups": ["admin"], + "access_groups": [], + "id": null, + "email": "admin@bec_atlas.ch", + "groups": ["demo", "admin", "atlas_func_account"], + "first_name": "Admin", + "last_name": "Admin" + }, + { + "_id": { "$oid": "67a5d694c13d2198c91cc47c" }, + "owner_groups": ["admin"], + "access_groups": [], + "id": null, + "email": "jane.doe@bec_atlas.ch", + "groups": ["demo", "atlas_func_account"], + "first_name": "Jane", + "last_name": "Doe" + } +] diff --git a/backend/tests/test_scan_ingestor.py b/backend/tests/test_scan_ingestor.py index 6c3445f..e919951 100644 --- a/backend/tests/test_scan_ingestor.py +++ b/backend/tests/test_scan_ingestor.py @@ -1,7 +1,13 @@ +from typing import TYPE_CHECKING + import pytest from bec_lib import messages from bec_atlas.ingestor.data_ingestor import DataIngestor +from bec_atlas.model.model import Deployments, Session + +if TYPE_CHECKING: + from bec_atlas.datasources.mongodb.mongodb import MongoDBDatasource @pytest.fixture @@ -13,95 +19,104 @@ def scan_ingestor(backend): ingestor.shutdown() -# @pytest.mark.timeout(60) -# def test_scan_ingestor_create_scan(scan_ingestor, backend): -# """ -# Test that the login endpoint returns a token. -# """ -# client, app = backend -# msg = messages.ScanStatusMessage( -# metadata={}, -# scan_id="92429a81-4bd4-41c2-82df-eccfaddf3d96", -# status="open", -# # session_id="5cc67967-744d-4115-a46b-13246580cb3f", -# info={ -# "readout_priority": { -# "monitored": ["bpm3i", "diode", "ftp", "bpm5c", "bpm3x", "bpm3z", "bpm4x"], -# "baseline": ["ddg1a", "bs1y", "mobdco"], -# "async": ["eiger", "monitor_async", "waveform"], -# "continuous": [], -# "on_request": ["flyer_sim"], -# }, -# "file_suffix": None, -# "file_directory": None, -# "user_metadata": {"sample_name": "testA"}, -# "RID": "5cc67967-744d-4115-a46b-13246580cb3f", -# "scan_id": "92429a81-4bd4-41c2-82df-eccfaddf3d96", -# "queue_id": "7d77d976-bee0-4bb8-aabb-2b862b4506ec", -# "session_id": "5cc67967-744d-4115-a46b-13246580cb3f", -# "scan_motors": ["samx"], -# "num_points": 10, -# "positions": [ -# [-5.0024118137239455], -# [-3.8913007026128343], -# [-2.780189591501723], -# [-1.6690784803906122], -# [-0.557967369279501], -# [0.5531437418316097], -# [1.6642548529427212], -# [2.775365964053833], -# [3.886477075164944], -# [4.9975881862760545], -# ], -# "scan_name": "line_scan", -# "scan_type": "step", -# "scan_number": 2, -# "dataset_number": 2, -# "exp_time": 0, -# "frames_per_trigger": 1, -# "settling_time": 0, -# "readout_time": 0, -# "acquisition_config": {"default": {"exp_time": 0, "readout_time": 0}}, -# "scan_report_devices": ["samx"], -# "monitor_sync": "bec", -# "scan_msgs": [ -# "metadata={'file_suffix': None, 'file_directory': None, 'user_metadata': {'sample_name': 'testA'}, 'RID': '5cc67967-744d-4115-a46b-13246580cb3f'} scan_type='line_scan' parameter={'args': {'samx': [-5, 5]}, 'kwargs': {'steps': 10, 'exp_time': 0, 'relative': True, 'system_config': {'file_suffix': None, 'file_directory': None}}} queue='primary'" -# ], -# "args": {"samx": [-5, 5]}, -# "kwargs": { -# "steps": 10, -# "exp_time": 0, -# "relative": True, -# "system_config": {"file_suffix": None, "file_directory": None}, -# }, -# }, -# timestamp=1732610545.15924, -# ) -# scan_ingestor.update_scan_status(msg, deployment_id="678aa8d4875568640bd92174") +@pytest.mark.timeout(60) +def test_scan_ingestor_create_scan(scan_ingestor, backend): + """ + Test that the login endpoint returns a token. + """ + client, app = backend + mongo: MongoDBDatasource = app.datasources.datasources["mongodb"] + deployment_id = str(mongo.find_one("deployments", {}, dtype=Deployments).id) + session_id = str(mongo.find_one("sessions", {"deployment_id": deployment_id}, dtype=Session).id) + msg = messages.ScanStatusMessage( + metadata={}, + scan_id="92429a81-4bd4-41c2-82df-eccfaddf3d96", + status="open", + # session_id="5cc67967-744d-4115-a46b-13246580cb3f", + info={ + "readout_priority": { + "monitored": ["bpm3i", "diode", "ftp", "bpm5c", "bpm3x", "bpm3z", "bpm4x"], + "baseline": ["ddg1a", "bs1y", "mobdco"], + "async": ["eiger", "monitor_async", "waveform"], + "continuous": [], + "on_request": ["flyer_sim"], + }, + "file_suffix": None, + "file_directory": None, + "user_metadata": {"sample_name": "testA"}, + "RID": "5cc67967-744d-4115-a46b-13246580cb3f", + "scan_id": "92429a81-4bd4-41c2-82df-eccfaddf3d96", + "queue_id": "7d77d976-bee0-4bb8-aabb-2b862b4506ec", + "session_id": session_id, + "scan_motors": ["samx"], + "num_points": 10, + "positions": [ + [-5.0024118137239455], + [-3.8913007026128343], + [-2.780189591501723], + [-1.6690784803906122], + [-0.557967369279501], + [0.5531437418316097], + [1.6642548529427212], + [2.775365964053833], + [3.886477075164944], + [4.9975881862760545], + ], + "scan_name": "line_scan", + "scan_type": "step", + "scan_number": 2, + "dataset_number": 2, + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "acquisition_config": {"default": {"exp_time": 0, "readout_time": 0}}, + "scan_report_devices": ["samx"], + "monitor_sync": "bec", + "scan_msgs": [ + "metadata={'file_suffix': None, 'file_directory': None, 'user_metadata': {'sample_name': 'testA'}, 'RID': '5cc67967-744d-4115-a46b-13246580cb3f'} scan_type='line_scan' parameter={'args': {'samx': [-5, 5]}, 'kwargs': {'steps': 10, 'exp_time': 0, 'relative': True, 'system_config': {'file_suffix': None, 'file_directory': None}}} queue='primary'" + ], + "args": {"samx": [-5, 5]}, + "kwargs": { + "steps": 10, + "exp_time": 0, + "relative": True, + "system_config": {"file_suffix": None, "file_directory": None}, + }, + }, + timestamp=1732610545.15924, + ) + scan_ingestor.update_scan_status(msg, deployment_id=deployment_id) -# response = client.post( -# "/api/v1/user/login", json={"username": "admin@bec_atlas.ch", "password": "admin"} -# ) -# client.headers.update({"Authorization": f"Bearer {response.json()}"}) + response = client.post( + "/api/v1/user/login", json={"username": "admin@bec_atlas.ch", "password": "admin"} + ) + client.headers.update({"Authorization": f"Bearer {response.json()}"}) -# session_id = msg.info.get("session_id") -# scan_id = msg.scan_id -# response = client.get("/api/v1/scans/session", params={"session_id": session_id}) -# assert response.status_code == 200 -# out = response.json()[0] -# # assert out["session_id"] == session_id -# assert out["scan_id"] == scan_id -# assert out["status"] == "open" + session_id = msg.info.get("session_id") + scan_id = msg.scan_id + response = client.get("/api/v1/scans/session", params={"session_id": session_id}) + assert response.status_code == 200 + out = response.json() + num_scans = len(out) + inserted_scan = [scan for scan in out if scan["scan_id"] == scan_id] -# msg.status = "closed" -# scan_ingestor.update_scan_status(msg, deployment_id="678aa8d4875568640bd92174") -# response = client.get("/api/v1/scans/id", params={"scan_id": scan_id}) -# assert response.status_code == 200 -# out = response.json() -# assert out["status"] == "closed" -# assert out["scan_id"] == scan_id + assert len(inserted_scan) == 1 + out = inserted_scan[0] + # assert out["session_id"] == session_id + assert out["scan_id"] == scan_id + assert out["status"] == "open" -# response = client.get("/api/v1/scans/session", params={"session_id": session_id}) -# assert response.status_code == 200 -# out = response.json() -# assert len(out) == 1 + msg.status = "closed" + scan_ingestor.update_scan_status(msg, deployment_id=deployment_id) + response = client.get("/api/v1/scans/id", params={"scan_id": scan_id}) + assert response.status_code == 200 + out = response.json() + assert out["status"] == "closed" + assert out["scan_id"] == scan_id + + # Test that the number of scans did not change + response = client.get("/api/v1/scans/session", params={"session_id": session_id}) + assert response.status_code == 200 + out = response.json() + assert len(out) == num_scans