Skip to content

Commit

Permalink
test: Enable all adaptor_runtime_client tests in Windows. (#60)
Browse files Browse the repository at this point in the history
Signed-off-by: Hongli Chen <[email protected]>
  • Loading branch information
Honglichenn authored Jan 29, 2024
1 parent 76c2b07 commit 160a75f
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 37 deletions.
3 changes: 1 addition & 2 deletions hatch.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ pre-install-commands = [
[envs.default.scripts]
sync = "pip install -r requirements-testing.txt"
test = "pytest --cov-config pyproject.toml {args:test}"
test-windows = """pytest --cov-config pyproject.toml {args:} \
test/openjd/adaptor_runtime --cov-fail-under=77"""
test-windows = "pytest --cov-config pyproject.toml {args:test} --cov-fail-under=90"
typing = "mypy {args:src test}"
style = [
"ruff {args:.}",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,4 @@ is-posix = "sys_platform != 'win32'"

[tool.coverage.report]
show_missing = true
fail_under = 93
fail_under = 92
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ def send_response(self, status: HTTPStatus, body: str = ""):
body: A string containing the message body to be sent back to the client.
"""
response = {"status": status, "body": body}
_logger.debug(f"NamedPipe Server: Send Response: {response}")
NamedPipeHelper.write_to_pipe(self.pipe_handle, json.dumps(response))
_logger.debug("NamedPipe Server: Sent Response.")

def validate_request_path_and_method(self, request_path: str, request_method) -> bool:
"""
Expand Down
2 changes: 1 addition & 1 deletion src/openjd/adaptor_runtime_client/win_client_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self, server_path: str) -> None:
server_path (str): Used as pipe name in Named Pipe Server.
"""
super().__init__(server_path)
_signal.signal(_signal.SIGTERM, self.graceful_shutdown) # type: ignore[attr-defined]
_signal.signal(_signal.SIGBREAK, self.graceful_shutdown) # type: ignore[attr-defined]

def _send_request(
self,
Expand Down
15 changes: 0 additions & 15 deletions test/openjd/adaptor_runtime/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
import platform
import os
from typing import Generator

from openjd.adaptor_runtime._osname import OSName
Expand All @@ -13,20 +12,6 @@
import win32netcon


# TODO: Remove this one after Windows Development finish
# https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest.hookspec.pytest_collection_modifyitems
def pytest_collection_modifyitems(items):
if OSName.is_windows():
# Add the tests' paths that we want to enable in Windows
do_not_skip_paths = [
os.path.abspath(os.path.dirname(__file__)),
]
skip_marker = pytest.mark.skip(reason="Skipping tests on Windows")
for item in items:
if not any(not_skip_path in item.fspath.strpath for not_skip_path in do_not_skip_paths):
item.add_marker(skip_marker)


# List of platforms that can be used to mark tests as specific to that platform
# See [tool.pytest.ini_options] -> markers in pyproject.toml
_PLATFORMS = set(
Expand Down
7 changes: 4 additions & 3 deletions test/openjd/adaptor_runtime_client/integ/fake_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

from __future__ import annotations

from signal import Signals
from time import sleep as _sleep
from types import FrameType as _FrameType
from typing import Any as _Any
from typing import Dict as _Dict
from typing import Optional as _Optional

from openjd.adaptor_runtime_client import HTTPClientInterface as _HTTPClientInterface
from openjd.adaptor_runtime_client import ClientInterface as _ClientInterface


class FakeClient(_HTTPClientInterface):
class FakeClient(_ClientInterface):
shutdown: bool

def __init__(self, port: str) -> None:
Expand All @@ -22,7 +23,7 @@ def close(self, args: _Optional[_Dict[str, _Any]]) -> None:
print("closing")

def graceful_shutdown(self, signum: int, frame: _Optional[_FrameType]) -> None:
print("Received SIGTERM signal.")
print(f"Received {Signals(signum).name} signal.")
self.shutdown = True

def run(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,49 @@
from __future__ import annotations

import os as _os
import signal
import sys
import subprocess as _subprocess
from time import sleep as _sleep
from typing import Dict, Any

from openjd.adaptor_runtime._osname import OSName


class TestIntegrationClientInterface:
""" "These are the integration tests for the client interface."""

def test_graceful_shutdown(self) -> None:
client_subprocess = _subprocess.Popen(
[
"python",
# Create the subprocess
popen_params: Dict[str, Any] = dict(
args=[
sys.executable,
_os.path.join(_os.path.dirname(_os.path.realpath(__file__)), "fake_client.py"),
],
stdin=_subprocess.PIPE,
stderr=_subprocess.PIPE,
stdout=_subprocess.PIPE,
encoding="utf-8",
)
if OSName.is_windows():
# In Windows, this is required for signal. SIGBREAK will be sent to the entire process group.
# Without this one, current process will also get the SIGBREAK and may react incorrectly.
popen_params.update(creationflags=_subprocess.CREATE_NEW_PROCESS_GROUP) # type: ignore[attr-defined]
client_subprocess = _subprocess.Popen(**popen_params)

# To avoid a race condition, giving some extra time for the logging subprocess to start.
_sleep(0.5)
client_subprocess.terminate()
_sleep(0.5 if OSName.is_posix() else 4)
if OSName.is_windows():
signal_type = signal.CTRL_BREAK_EVENT # type: ignore[attr-defined]
else:
signal_type = signal.SIGTERM

client_subprocess.send_signal(signal_type)

# To avoid a race condition, giving some extra time for the log to be updated after
# receiving the signal.
_sleep(0.5)
_sleep(0.5 if OSName.is_posix() else 4)

out, _ = client_subprocess.communicate()

assert "Received SIGTERM signal." in out
assert f"Received {'SIGBREAK' if OSName.is_windows() else 'SIGTERM'} signal." in out
Loading

0 comments on commit 160a75f

Please sign in to comment.