Skip to content

Commit

Permalink
test: Add github actions for Windows
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Luttrell <[email protected]>
  • Loading branch information
roblutt committed Oct 19, 2023
1 parent 2fd6c47 commit d41d035
Show file tree
Hide file tree
Showing 16 changed files with 221 additions and 94 deletions.
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

0 comments on commit d41d035

Please sign in to comment.