Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: parallel pytest execution #2131

Closed
wants to merge 12 commits into from
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
pip install -r requirements-dev.txt
- name: Test with pytest
run: |
pytest --cov antarest --cov-report xml
pytest --cov antarest --cov-report xml -n 4
- name: Archive code coverage results
if: matrix.os == 'ubuntu-20.04'
uses: actions/upload-artifact@v4
Expand Down
2 changes: 1 addition & 1 deletion antarest/eventbus/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from typing import List, Optional

from fastapi import Depends, FastAPI, HTTPException, Query
from fastapi_jwt_auth import AuthJWT # type: ignore
from pydantic import BaseModel
from starlette.websockets import WebSocket, WebSocketDisconnect

Expand All @@ -27,7 +28,6 @@
from antarest.core.model import PermissionInfo, StudyPermissionType
from antarest.core.permissions import check_permission
from antarest.login.auth import Auth
from fastapi_jwt_auth import AuthJWT # type: ignore

logger = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion antarest/login/auth.py
Copy link
Contributor

@mabw-rte mabw-rte Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an idea why this was not corrected by isort ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually there is no change on import sort order in the final PR. Intermediate commits introduced unwanted changes (related to another PR).

Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
from typing import Any, Callable, Coroutine, Dict, Optional, Tuple, Union

from fastapi import Depends
from fastapi_jwt_auth import AuthJWT # type: ignore
from pydantic import BaseModel
from ratelimit.types import Scope # type: ignore
from starlette.requests import Request

from antarest.core.config import Config
from antarest.core.jwt import DEFAULT_ADMIN_USER, JWTUser
from fastapi_jwt_auth import AuthJWT # type: ignore

logger = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion antarest/login/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from typing import Any, Optional

from fastapi import FastAPI
from fastapi_jwt_auth import AuthJWT # type: ignore
from fastapi_jwt_auth.exceptions import AuthJWTException # type: ignore
from starlette.requests import Request
from starlette.responses import JSONResponse
Expand All @@ -26,7 +27,6 @@
from antarest.login.repository import BotRepository, GroupRepository, RoleRepository, UserLdapRepository, UserRepository
from antarest.login.service import LoginService
from antarest.login.web import create_login_api
from fastapi_jwt_auth import AuthJWT # type: ignore


def build_login(
Expand Down
2 changes: 1 addition & 1 deletion antarest/login/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from typing import Any, List, Optional, Union

from fastapi import APIRouter, Depends, HTTPException
from fastapi_jwt_auth import AuthJWT # type: ignore
from markupsafe import escape
from pydantic import BaseModel

Expand All @@ -41,7 +42,6 @@
UserInfo,
)
from antarest.login.service import LoginService
from fastapi_jwt_auth import AuthJWT # type: ignore

logger = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion antarest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from fastapi import FastAPI, HTTPException
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi_jwt_auth import AuthJWT # type: ignore
from ratelimit import RateLimitMiddleware # type: ignore
from ratelimit.backends.redis import RedisBackend # type: ignore
from ratelimit.backends.simple import MemoryBackend # type: ignore
Expand Down Expand Up @@ -53,7 +54,6 @@
from antarest.study.storage.rawstudy.watcher import Watcher
from antarest.tools.admin_lib import clean_locks
from antarest.utils import SESSION_ARGS, Module, create_services, init_db_engine
from fastapi_jwt_auth import AuthJWT # type: ignore

logger = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion antarest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import sqlalchemy.ext.baked # type: ignore
import uvicorn # type: ignore
from fastapi import FastAPI
from fastapi_jwt_auth import AuthJWT # type: ignore
from ratelimit import RateLimitMiddleware # type: ignore
from ratelimit.backends.redis import RedisBackend # type: ignore
from ratelimit.backends.simple import MemoryBackend # type: ignore
Expand Down Expand Up @@ -53,7 +54,6 @@
from antarest.worker.archive_worker import ArchiveWorker
from antarest.worker.simulator_worker import SimulatorWorker
from antarest.worker.worker import AbstractWorker
from fastapi_jwt_auth import AuthJWT # type: ignore

logger = logging.getLogger(__name__)

Expand Down
4 changes: 3 additions & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
-r requirements.txt
checksumdir~=1.2.0
pytest~=6.2.5
pytest~=8.3.0
pytest-xdist~=3.6.0
pytest-cov~=4.0.0
pytest-mock~=3.14.0

# In this version DataFrame conversion to Excel is done using 'xlsxwriter' library.
# But Excel files reading is done using 'openpyxl' library, during testing only.
Expand Down
26 changes: 13 additions & 13 deletions tests/integration/filesystem_blueprint/test_filesystem_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
import datetime
import operator
import re
import shutil
import typing as t
from pathlib import Path

from pytest_mock import MockerFixture
from starlette.testclient import TestClient

from tests.integration.conftest import RESOURCES_DIR
Expand Down Expand Up @@ -93,6 +93,7 @@ def test_lifecycle(
client: TestClient,
user_access_token: str,
admin_access_token: str,
mocker: MockerFixture,
) -> None:
"""
Test the lifecycle of the filesystem endpoints.
Expand All @@ -102,7 +103,7 @@ def test_lifecycle(
caplog: pytest caplog fixture.
client: test client (tests.integration.conftest.client_fixture).
user_access_token: access token of a classic user (tests.integration.conftest.user_access_token_fixture).
admin_access_token: access token of an admin user (tests.integration.conftest.admin_access_token_fixture).
admin_access_token: access token of an admin user (tests.integration.conftestin_access_token_fixture).
"""
# NOTE: all the following paths are based on the configuration defined in the app_fixture.
archive_dir = tmp_path / "archive_dir"
Expand Down Expand Up @@ -165,26 +166,25 @@ def test_lifecycle(
err_count += 1

# Known filesystem
mocker.patch("shutil.disk_usage", return_value=(100, 200, 300))
res = client.get("/v1/filesystem/ws", headers=user_headers)
assert res.status_code == 200, res.json()
actual = sorted(res.json(), key=operator.itemgetter("name"))
# Both mount point are in the same filesystem, which is the `tmp_path` filesystem
total_bytes, used_bytes, free_bytes = shutil.disk_usage(tmp_path)
expected = [
{
"name": "default",
"path": str(default_workspace),
"total_bytes": total_bytes,
"used_bytes": used_bytes,
"free_bytes": free_bytes,
"total_bytes": 100,
"used_bytes": 200,
"free_bytes": 300,
"message": AnyDiskUsagePercent(),
},
{
"name": "ext",
"path": str(ext_workspace_path),
"total_bytes": total_bytes,
"used_bytes": used_bytes,
"free_bytes": free_bytes,
"total_bytes": 100,
"used_bytes": 200,
"free_bytes": 300,
"message": AnyDiskUsagePercent(),
},
]
Expand All @@ -206,9 +206,9 @@ def test_lifecycle(
expected = {
"name": "default",
"path": str(default_workspace),
"total_bytes": total_bytes,
"used_bytes": used_bytes,
"free_bytes": free_bytes,
"total_bytes": 100,
"used_bytes": 200,
"free_bytes": 300,
"message": AnyDiskUsagePercent(),
}
assert actual == expected
Expand Down
13 changes: 8 additions & 5 deletions tests/integration/filesystem_blueprint/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import shutil
from pathlib import Path

from pytest_mock import MockerFixture

from antarest.core.filesystem_blueprint import FileInfoDTO, FilesystemDTO, MountPointDTO


Expand Down Expand Up @@ -63,15 +65,16 @@ def test_from_path__missing_file(self) -> None:
assert dto.free_bytes == 0
assert dto.message.startswith("N/A:"), dto.message

def test_from_path__file(self, tmp_path: Path) -> None:
def test_from_path__file(self, tmp_path: Path, mocker: MockerFixture) -> None:
mocker.patch("shutil.disk_usage", return_value=(100, 200, 300))

name = "foo"
dto = asyncio.run(MountPointDTO.from_path(name, tmp_path))
total_bytes, used_bytes, free_bytes = shutil.disk_usage(tmp_path)
assert dto.name == name
assert dto.path == tmp_path
assert dto.total_bytes == total_bytes
assert dto.used_bytes == used_bytes
assert dto.free_bytes == free_bytes
assert dto.total_bytes == 100
assert dto.used_bytes == 200
assert dto.free_bytes == 300
assert re.fullmatch(r"\d+(?:\.\d+)?% used", dto.message), dto.message


Expand Down
4 changes: 2 additions & 2 deletions tests/storage/repository/filesystem/config/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ def test_transform_name_to_id__valid_chars(name):
assert transform_name_to_id(name, lower=False) == name


@pytest.mark.parametrize("name", set(string.punctuation) - set(VALID_CHARS))
@pytest.mark.parametrize("name", sorted(set(string.punctuation) - set(VALID_CHARS)))
def test_transform_name_to_id__punctuation(name):
assert not transform_name_to_id(name)


@pytest.mark.parametrize("name", set(string.whitespace) - set(VALID_CHARS))
@pytest.mark.parametrize("name", sorted(set(string.whitespace) - set(VALID_CHARS)))
def test_transform_name_to_id__whitespace(name):
assert not transform_name_to_id(name)

Expand Down
Loading
Loading