Skip to content

Commit

Permalink
chore(functional test): run in parallel (#7236)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bento007 authored Jul 10, 2024
1 parent f4c5e7f commit 422d9db
Show file tree
Hide file tree
Showing 15 changed files with 887 additions and 848 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ cellguide-pipeline-unittest:

.PHONY: functional-test
functional-test:
python3 -m pytest tests/functional/ --rootdir=. --verbose
python3 -m pytest tests/functional/ --rootdir=. --verbose -n auto

.PHONY: prod-performance-test
prod-performance-test:
Expand Down
25 changes: 20 additions & 5 deletions scripts/smoke_tests/setup.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
#!/usr/bin/env python
import json
import os
import sys
import threading

from backend.common.constants import DATA_SUBMISSION_POLICY_VERSION
from tests.functional.backend.common import BaseFunctionalTestCase
from backend.common.corpora_config import CorporaAuthConfig
from tests.functional.backend.constants import API_URL
from tests.functional.backend.utils import (
get_auth_token,
make_cookie,
make_proxy_auth_token,
make_session,
upload_and_wait,
)

# Amount to reduce chance of collision where multiple test instances select the same collection to test against
NUM_TEST_DATASETS = 3
NUM_TEST_COLLECTIONS = 10
TEST_ACCT_CONTACT_NAME = "Smoke Test User"


class SmokeTestsInitializer(BaseFunctionalTestCase):
class SmokeTestsInitializer:
def __init__(self):
super().setUpClass(smoke_tests=True)
super().setUp()
self.deployment_stage = os.environ["DEPLOYMENT_STAGE"]
self.config = CorporaAuthConfig()
proxy_auth_token = make_proxy_auth_token(self.config, self.deployment_stage)
self.session = make_session(proxy_auth_token)
self.api = API_URL.get(self.deployment_stage)
username, password = self.config.test_account_username, self.config.test_account_password
auth_token = get_auth_token(username, password, self.session, self.config, self.deployment_stage)
self.curator_cookie = make_cookie(auth_token)
self.headers = {"Cookie": f"cxguser={self.curator_cookie}", "Content-Type": "application/json"}

def get_collection_count(self):
Expand All @@ -33,7 +48,7 @@ def get_collection_count(self):
def create_and_publish_collection(self, dropbox_url):
collection_id = self.create_collection()
for _ in range(NUM_TEST_DATASETS):
self.upload_and_wait(collection_id, dropbox_url, cleanup=False)
upload_and_wait(collection_id, dropbox_url, cleanup=False)
self.publish_collection(collection_id)
print(f"created and published collection {collection_id}")

Expand Down
175 changes: 0 additions & 175 deletions tests/functional/backend/common.py

This file was deleted.

103 changes: 103 additions & 0 deletions tests/functional/backend/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import os

import pytest

from backend.common.corpora_config import CorporaAuthConfig
from tests.functional.backend.constants import API_URL
from tests.functional.backend.distributed import distributed_singleton
from tests.functional.backend.utils import (
get_auth_token,
make_cookie,
make_proxy_auth_token,
make_session,
upload_and_wait,
)


@pytest.fixture(scope="session")
def config():
return CorporaAuthConfig()


@pytest.fixture(scope="session")
def deployment_stage():
return os.environ["DEPLOYMENT_STAGE"]


@pytest.fixture(scope="session")
def proxy_auth_token(config, deployment_stage, tmp_path_factory, worker_id) -> dict:
"""
Generate a proxy token for rdev. If running in parallel mode this will be shared across workers to avoid rate
limiting
"""

def _proxy_auth_token() -> dict:
return make_proxy_auth_token(config, deployment_stage)

return distributed_singleton(tmp_path_factory, worker_id, _proxy_auth_token)


@pytest.fixture(scope="session")
def session(proxy_auth_token):
session = make_session(proxy_auth_token)
yield session
session.close()


@pytest.fixture(scope="session")
def functest_auth_token(config, session, deployment_stage, tmp_path_factory, worker_id):
def _functest_auth_token() -> dict[str, str]:
username = config.functest_account_username
password = config.functest_account_password
return get_auth_token(username, password, session, config, deployment_stage)

return distributed_singleton(tmp_path_factory, worker_id, _functest_auth_token)


@pytest.fixture(scope="session")
def curator_cookie(functest_auth_token):
return make_cookie(functest_auth_token)


@pytest.fixture(scope="session")
def api_url(deployment_stage):
return API_URL.get(deployment_stage)


@pytest.fixture(scope="session")
def curation_api_access_token(session, api_url, config, tmp_path_factory, worker_id):
def _curation_api_access_token() -> str:
response = session.post(
f"{api_url}/curation/v1/auth/token",
headers={"x-api-key": config.super_curator_api_key},
)
response.raise_for_status()
return response.json()["access_token"]

return distributed_singleton(tmp_path_factory, worker_id, _curation_api_access_token)


@pytest.fixture(scope="session")
def upload_dataset(session, api_url, curator_cookie, request):
def _upload_dataset(collection_id, dropbox_url, existing_dataset_id=None):
result = upload_and_wait(session, api_url, curator_cookie, collection_id, dropbox_url, existing_dataset_id)
dataset_id = result["dataset_id"]
headers = {"Cookie": f"cxguser={curator_cookie}", "Content-Type": "application/json"}
request.addfinalizer(lambda: session.delete(f"{api_url}/dp/v1/datasets/{dataset_id}", headers=headers))
if result["errors"]:
raise pytest.fail(str(result["errors"]))
return dataset_id

return _upload_dataset


@pytest.fixture()
def collection_data(request):
return {
"contact_email": "lisbon@gmail.com",
"contact_name": "Madrid Sparkle",
"curator_name": "John Smith",
"description": "Well here are some words",
"links": [{"link_name": "a link to somewhere", "link_type": "PROTOCOL", "link_url": "https://protocol.com"}],
"name": request.function.__name__,
}
21 changes: 21 additions & 0 deletions tests/functional/backend/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os

API_URL = {
"prod": "https://api.cellxgene.cziscience.com",
"staging": "https://api.cellxgene.staging.single-cell.czi.technology",
"dev": "https://api.cellxgene.dev.single-cell.czi.technology",
"test": "https://localhost:5000",
"rdev": f"https://{os.getenv('STACK_NAME', '')}-backend.rdev.single-cell.czi.technology",
}
AUDIENCE = {
"prod": "api.cellxgene.cziscience.com",
"staging": "api.cellxgene.staging.single-cell.czi.technology",
"test": "api.cellxgene.dev.single-cell.czi.technology",
"dev": "api.cellxgene.dev.single-cell.czi.technology",
"rdev": "api.cellxgene.dev.single-cell.czi.technology",
}

DATASET_URI = (
"https://www.dropbox.com/scl/fi/y50umqlcrbz21a6jgu99z/5_0_0_example_valid.h5ad?rlkey"
"=s7p6ybyx082hswix26hbl11pm&dl=0"
)
Loading

0 comments on commit 422d9db

Please sign in to comment.