From 6ff4dab073791bdc35fb922f4f3958816e781fdb Mon Sep 17 00:00:00 2001 From: Jericho Tolentino <68654047+jericht@users.noreply.github.com> Date: Tue, 21 May 2024 16:23:41 +0000 Subject: [PATCH] fix macos tests Signed-off-by: Jericho Tolentino <68654047+jericht@users.noreply.github.com> --- src/openjd/adaptor_runtime/_http/sockets.py | 18 ++++++++++-------- test/openjd/adaptor_runtime/conftest.py | 19 ++++++++++++++++--- .../adaptor_runtime/unit/http/test_sockets.py | 14 +++++++------- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/openjd/adaptor_runtime/_http/sockets.py b/src/openjd/adaptor_runtime/_http/sockets.py index 7f821f8..73ce4f3 100644 --- a/src/openjd/adaptor_runtime/_http/sockets.py +++ b/src/openjd/adaptor_runtime/_http/sockets.py @@ -112,15 +112,17 @@ def gen_socket_path(dir: str, base_name: str): return os.path.join(dir, name) if not base_dir: - socket_dir = tempfile.gettempdir() - # Check that the sticky bit is set on the temp dir - if not os.stat(socket_dir).st_mode & stat.S_ISVTX: - raise NoSocketPathFoundException( - f"Cannot use temporary directory {socket_dir} because it does not have the " - "sticky bit (restricted deletion flag) set" - ) + socket_dir = os.path.realpath(tempfile.gettempdir()) else: - socket_dir = base_dir + socket_dir = os.path.realpath(base_dir) + + # Check that the sticky bit is set if the dir is world writable + socket_dir_stat = os.stat(socket_dir) + if socket_dir_stat.st_mode & stat.S_IWOTH and not socket_dir_stat.st_mode & stat.S_ISVTX: + raise NoSocketPathFoundException( + f"Cannot use directory {socket_dir} because it is world writable and does not " + "have the sticky bit (restricted deletion flag) set" + ) if namespace: socket_dir = os.path.join(socket_dir, namespace) diff --git a/test/openjd/adaptor_runtime/conftest.py b/test/openjd/adaptor_runtime/conftest.py index 83e282a..642d94a 100644 --- a/test/openjd/adaptor_runtime/conftest.py +++ b/test/openjd/adaptor_runtime/conftest.py @@ -1,12 +1,15 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. import platform +import random +import string from typing import Generator +from unittest.mock import MagicMock, patch -from openjd.adaptor_runtime._osname import OSName -import string -import random import pytest +from openjd.adaptor_runtime._osname import OSName +from openjd.adaptor_runtime._http import sockets + if OSName.is_windows(): import win32net import win32netcon @@ -92,3 +95,13 @@ def delete_user() -> None: yield username, password # Delete the user after test completes delete_user() + + +@pytest.fixture(scope="session", autouse=OSName().is_macos()) +def mock_sockets_py_tempfile_gettempdir_to_slash_tmp() -> Generator[MagicMock, None, None]: + """ + Mock that is automatically used on Mac to override the tempfile.gettempdir() usages in sockets.py + because the folder returned by it on Mac is too long for the socket name to fit (max 104 bytes, see sockets.py) + """ + with patch.object(sockets.tempfile, "gettempdir", return_value="/tmp") as m: + yield m diff --git a/test/openjd/adaptor_runtime/unit/http/test_sockets.py b/test/openjd/adaptor_runtime/unit/http/test_sockets.py index 23632c3..3566295 100644 --- a/test/openjd/adaptor_runtime/unit/http/test_sockets.py +++ b/test/openjd/adaptor_runtime/unit/http/test_sockets.py @@ -1,9 +1,9 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. import os +import pathlib import re import stat -import tempfile from typing import Generator from unittest.mock import MagicMock, patch @@ -115,10 +115,10 @@ def test_create_dir(self, mock_makedirs: MagicMock, create: bool) -> None: else: mock_makedirs.assert_not_called() - def test_uses_base_dir(self) -> None: + def test_uses_base_dir(self, tmp_path: pathlib.Path) -> None: # GIVEN subject = SocketPathsStub() - base_dir = os.path.join(os.sep, "base", "dir") + base_dir = str(tmp_path) # WHEN result = subject.get_socket_path("sock", base_dir=base_dir) @@ -160,7 +160,7 @@ def test_raises_when_no_tmpdir_sticky_bit( ) -> None: # GIVEN mock_verify_socket_path.side_effect = [NonvalidSocketPathException(), None] - mock_stat.return_value.st_mode = 0 + mock_stat.return_value.st_mode = stat.S_IWOTH subject = SocketPathsStub() # WHEN @@ -170,8 +170,8 @@ def test_raises_when_no_tmpdir_sticky_bit( # THEN assert raised_exc.match( re.escape( - f"Cannot use temporary directory {tempfile.gettempdir()} because it does not have the " - "sticky bit (restricted deletion flag) set" + f"Cannot use directory {os.path.realpath(sockets.tempfile.gettempdir())} because it is world writable" + " and does not have the sticky bit (restricted deletion flag) set" ) ) @@ -193,7 +193,7 @@ def test_handles_socket_name_collisions( # THEN assert result.endswith(expected_sock_name) - mock_exists.call_count == len(existing_sock_names) + 1 + assert mock_exists.call_count == (len(existing_sock_names) + 1) class TestLinuxSocketPaths: