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

test: Add github actions for Windows #62

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions .github/workflows/reuse_python_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11']
os: [ubuntu-latest, macOS-latest]
os: [ubuntu-latest, macOS-latest, windows-latest]
env:
PYTHON: ${{ matrix.python-version }}
CODEARTIFACT_REGION: "us-west-2"
Expand Down Expand Up @@ -45,19 +45,28 @@ jobs:
aws-region: us-west-2
mask-aws-account-id: true

- name: Install Hatch
- name: Install Hatch Posix
if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'macOS-latest'}}
shell: bash
run: |
CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token --domain ${{ secrets.CODEARTIFACT_DOMAIN }} --domain-owner ${{ secrets.CODEARTIFACT_ACCOUNT_ID }} --query authorizationToken --output text --region us-west-2)
echo "::add-mask::$CODEARTIFACT_AUTH_TOKEN"
echo CODEARTIFACT_AUTH_TOKEN=$CODEARTIFACT_AUTH_TOKEN >> $GITHUB_ENV
pip install --upgrade hatch
- name: Install Hatch Windows
if: ${{ matrix.os == 'windows-latest'}}
run: |
$CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token --domain ${{ secrets.CODEARTIFACT_DOMAIN }} --domain-owner ${{ secrets.CODEARTIFACT_ACCOUNT_ID }} --query authorizationToken --output text --region us-west-2)
echo "::add-mask::$CODEARTIFACT_AUTH_TOKEN"
echo CODEARTIFACT_AUTH_TOKEN=$CODEARTIFACT_AUTH_TOKEN >> $env:GITHUB_ENV
pip install --upgrade hatch
- name: Run Linting
run: hatch run lint

- name: Run Build
run: hatch build

- name: Run Tests
run: hatch run test
run: hatch run test
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,4 @@ source = [ "src/" ]

[tool.coverage.report]
show_missing = true
fail_under = 78
fail_under = 69
4 changes: 2 additions & 2 deletions src/deadline_worker_agent/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def __init__(
signal.signal(signal.SIGTERM, self._signal_handler)
signal.signal(signal.SIGINT, self._signal_handler)
# TODO: Remove this once WA is stable or put behind a debug flag
signal.signal(signal.SIGUSR1, self._output_thread_stacks)
signal.signal(signal.SIGUSR1, self._output_thread_stacks) # type: ignore

def _signal_handler(self, signum: int, frame: FrameType | None = None) -> None:
"""
Expand All @@ -147,7 +147,7 @@ def _output_thread_stacks(self, signum: int, frame: FrameType | None = None) ->
This signal is designated for application-defined behaviors. In our case, we want to output
stack traces for all running threads.
"""
if signum in (signal.SIGUSR1,):
if signum in (signal.SIGUSR1,): # type: ignore
logger.info(f"Received signal {signum}. Initiating application shutdown.")
# OUTPUT STACK TRACE FOR ALL THREADS
print("\n*** STACKTRACE - START ***\n", file=sys.stderr)
Expand Down
20 changes: 16 additions & 4 deletions test/unit/aws_credentials/test_aws_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
_setup_file,
_setup_parent_dir,
)
from openjd.sessions import PosixSessionUser, SessionUser
import os

if os.name == "posix":
from openjd.sessions import PosixSessionUser
from openjd.sessions import SessionUser


@pytest.fixture
Expand All @@ -27,11 +31,15 @@ def mock_run_cmd_as() -> Generator[MagicMock, None, None]:
yield mock_run_cmd_as


@pytest.fixture(params=(PosixSessionUser(user="some-user", group="some-group"), None))
def os_user(request: pytest.FixtureRequest) -> Optional[SessionUser]:
return request.param
@pytest.fixture()
def os_user() -> Optional[SessionUser]:
if os.name == "posix":
return PosixSessionUser(user="some-user", group="some-group")
else:
return None


@pytest.mark.skipif(os.name == "nt", reason="Windows is not yet supported.")
class TestSetupParentDir:
"""Tests for the _setup_parent_dir() function"""

Expand Down Expand Up @@ -92,6 +100,7 @@ def test_sets_group_ownership(
mock_run_cmd_as.assert_not_called()


@pytest.mark.skipif(os.name == "nt", reason="Windows is not yet supported.")
class TestSetupFile:
"""Tests for the _setup_file() function"""

Expand Down Expand Up @@ -199,6 +208,7 @@ def test_changes_group_ownership(
mock_run_cmd_as.assert_not_called()


@pytest.mark.skipif(os.name == "nt", reason="Windows is not yet supported.")
class AWSConfigTestBase:
"""Base class for common testing logic of AWSConfig and AWSCredentials classes"""

Expand Down Expand Up @@ -381,6 +391,7 @@ def test_write(
)


@pytest.mark.skipif(os.name == "nt", reason="Windows is not yet supported.")
class TestAWSConfig(AWSConfigTestBase):
"""
Test class derrived from AWSConfigTestBase for AWSConfig.
Expand All @@ -402,6 +413,7 @@ def expected_path(self, os_user: Optional[SessionUser]) -> str:
return f"~{os_user.user if os_user is not None else ''}/.aws/config"


@pytest.mark.skipif(os.name == "nt", reason="Windows is not yet supported.")
class TestAWSCredentials(AWSConfigTestBase):
"""
Test class derrived from AWSConfigTestBase for AWSCredentials.
Expand Down
26 changes: 20 additions & 6 deletions test/unit/aws_credentials/test_queue_boto3_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
)
import deadline_worker_agent.aws_credentials.queue_boto3_session as queue_boto3_session_mod
from deadline_worker_agent.aws_credentials.queue_boto3_session import QueueBoto3Session
from openjd.sessions import PosixSessionUser, SessionUser
from openjd.sessions import SessionUser

if os.name == "posix":
from openjd.sessions import PosixSessionUser


@pytest.fixture(autouse=True)
Expand Down Expand Up @@ -51,11 +54,15 @@ def deadline_client() -> MagicMock:
return MagicMock()


@pytest.fixture(params=(PosixSessionUser(user="some-user", group="some-group"), None))
def os_user(request: pytest.FixtureRequest) -> Optional[SessionUser]:
return request.param
@pytest.fixture()
def os_user() -> Optional[SessionUser]:
if os.name == "posix":
return PosixSessionUser(user="some-user", group="some-group") # type: ignore # noqa
else:
return None


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestInit:
def test_construction(
self,
Expand Down Expand Up @@ -146,6 +153,7 @@ def test_refresh_raises(
assert exc_context.value is mock_refresh.side_effect


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestCleanup:
def test(
self,
Expand Down Expand Up @@ -189,6 +197,7 @@ def test(
mock_delete_dir.assert_called_once()


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestHasCredentials:
@pytest.mark.parametrize("expired", [True, False])
def test(
Expand Down Expand Up @@ -241,6 +250,7 @@ def test(
SAMPLE_ASSUME_ROLE_RESPONSE = {"credentials": SAMPLE_DEADLINE_CREDENTIALS}


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestRefreshCredentials:
def test_uses_bootstrap_credentials(
self,
Expand Down Expand Up @@ -426,6 +436,7 @@ def test_reraises_from_parse(
assert exc_context.value.inner_exc is exception


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestCreateCredentialsDirectory:
def test_success(
self,
Expand Down Expand Up @@ -470,7 +481,7 @@ def test_success(
parents=True,
mode=0o750,
)
if isinstance(os_user, PosixSessionUser):
if isinstance(os_user, PosixSessionUser): # type: ignore # noqa
mock_chown.assert_called_once_with(mock_path, group=os_user.group)
else:
mock_chown.assert_not_called()
Expand Down Expand Up @@ -516,6 +527,7 @@ def test_reraises_oserror(
assert exc_context.value is mock_path.mkdir.side_effect


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestDeleteCredentialsDirectory:
@pytest.mark.parametrize("exists", [True, False])
def test_success(
Expand Down Expand Up @@ -564,6 +576,7 @@ def test_success(
mock_rmtree.assert_not_called()


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestInstallCredentialProcess:
def test_success(
self,
Expand Down Expand Up @@ -636,7 +649,7 @@ def test_success(
mock_chown.assert_not_called()
else:
# This assert for type checking. Expand the if-else chain when adding new user kinds.
assert isinstance(os_user, PosixSessionUser)
assert isinstance(os_user, PosixSessionUser) # type: ignore # noqa
mock_chown.assert_called_once_with(credentials_process_script_path, group=os_user.group)
aws_config_mock.install_credential_process.assert_called_once_with(
session._profile_name, credentials_process_script_path
Expand All @@ -646,6 +659,7 @@ def test_success(
)


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on Windows")
class TestUninstallCredentialProcess:
def test_success(
self,
Expand Down
3 changes: 3 additions & 0 deletions test/unit/aws_credentials/test_worker_boto3_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Optional, Generator
from unittest.mock import MagicMock, patch
from datetime import datetime, timezone, timedelta
import os

import pytest

Expand Down Expand Up @@ -99,6 +100,7 @@ def temporary_credentials_cls_mock() -> Generator[MagicMock, None, None]:
yield mock


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on windows")
class TestInit:
def test_without_loading(
self,
Expand Down Expand Up @@ -169,6 +171,7 @@ def test_with_loading(
SAMPLE_ASSUME_ROLE_RESPONSE = {"credentials": SAMPLE_DEADLINE_CREDENTIALS}


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on windows")
class TestRefreshCredentials:
def test_uses_own_credentials(
self,
Expand Down
34 changes: 26 additions & 8 deletions test/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,34 @@ def logs_client() -> MagicMock:
return MagicMock()


@pytest.fixture(params=(PosixSessionUser(user="some-user", group="some-group"),))
def posix_job_user(request: pytest.FixtureRequest) -> Optional[SessionUser]:
return request.param
if os.name == "posix":

@pytest.fixture(params=(PosixSessionUser(user="some-user", group="some-group"),))
def os_user(request: pytest.FixtureRequest) -> Optional[SessionUser]:
return request.param

@pytest.fixture(params=(False,))
def impersonation(
request: pytest.FixtureRequest, posix_job_user: Optional[SessionUser]
) -> ImpersonationOverrides:
return ImpersonationOverrides(inactive=request.param, posix_job_user=posix_job_user)
else:

@pytest.fixture()
def os_user() -> Optional[SessionUser]:
return None


if os.name == "posix":

@pytest.fixture(params=(False,))
def impersonation(
request: pytest.FixtureRequest, os_user: Optional[SessionUser]
) -> ImpersonationOverrides:
return ImpersonationOverrides(inactive=request.param, posix_job_user=os_user)

else:

@pytest.fixture(params=(True,))
def impersonation(
request: pytest.FixtureRequest,
) -> ImpersonationOverrides:
return ImpersonationOverrides(inactive=request.param)


@pytest.fixture
Expand Down
3 changes: 1 addition & 2 deletions test/unit/install/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from subprocess import CalledProcessError
from typing import Generator, Optional
from unittest.mock import MagicMock, patch
import os
import sysconfig

import pytest
Expand Down Expand Up @@ -288,4 +287,4 @@ def test_unsupported_platform_raises(platform: str, capsys: pytest.CaptureFixtur
assert raise_ctx.value.code == 1
capture = capsys.readouterr()

assert capture.out == f"ERROR: Unsupported platform {platform}{os.linesep}"
assert capture.out == f"ERROR: Unsupported platform {platform}\n"
6 changes: 6 additions & 0 deletions test/unit/log_sync/test_cloudwatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from threading import Event
from typing import Any, Generator, Optional
from unittest.mock import MagicMock, PropertyMock, call, patch
import pytest

from pytest import fixture, mark, param, raises

Expand All @@ -33,6 +34,7 @@ def mock_module_logger() -> Generator[MagicMock, None, None]:
yield mock_module_logger


@pytest.mark.skipif(os.name == "nt", reason="Windows is not yet supported.")
class TestCloudWatchLogEventBatch:
@fixture(autouse=True)
def now(self) -> datetime:
Expand Down Expand Up @@ -161,6 +163,7 @@ def test_size_includes_padding(
# THEN
assert actual_size == expected_size

@pytest.mark.xfail(os.name == "nt", reason="Windows is not yet supported.")
class TestValidateLogEventCanBeAdded:
@patch.object(module, "datetime", wraps=datetime)
def test_valid_log_event(
Expand All @@ -182,6 +185,7 @@ def test_valid_log_event(
# THEN
# The function did not throw, test passed

@pytest.mark.xfail(os.name == "nt", reason="Windows is not yet supported.")
def test_too_many_events(self):
# GIVEN
with patch.object(
Expand Down Expand Up @@ -212,6 +216,7 @@ def test_too_many_events(self):
),
),
)
@pytest.mark.xfail(os.name == "nt", reason="Windows is not yet supported.")
def test_over_batch_size(
self,
batch_size: int,
Expand Down Expand Up @@ -282,6 +287,7 @@ def test_too_far_future(self, now: datetime):
),
),
)
@pytest.mark.xfail(os.name == "nt", reason="Windows is not yet supported.")
def test_exceed_batch_timespan(
self,
event_time: datetime,
Expand Down
2 changes: 2 additions & 0 deletions test/unit/scheduler/test_session_cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Generator
from unittest.mock import MagicMock, patch
import subprocess
import os

from openjd.sessions import SessionUser, PosixSessionUser
import pytest
Expand All @@ -20,6 +21,7 @@ def __init__(self, user: str):
self.user = user


@pytest.mark.skipif(os.name == "nt", reason="Expected to fail on windows")
class TestSessionUserCleanupManager:
@pytest.fixture
def manager(self) -> SessionUserCleanupManager:
Expand Down
Loading