1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
from __future__ import annotations
from dataclasses import asdict
import os
import re
from unittest.mock import MagicMock, call, patch
import pytest
from con_duct.__main__ import LogPaths, Outputs
def test_log_paths_filesafe_datetime_prefix() -> None:
log_paths = LogPaths.create("start_{datetime_filesafe}")
pattern = r"^start_\d{4}\.\d{2}\.\d{2}T\d{2}\.\d{2}\.\d{2}.*"
for path in asdict(log_paths).values():
assert re.match(pattern, path) is not None
def test_log_paths_pid_prefix() -> None:
prefix = "prefix_{pid}_"
log_paths = LogPaths.create(prefix, pid=123456)
assert log_paths.prefix == prefix.format(pid=123456)
@pytest.mark.parametrize(
"path",
[
"directory/",
"nested/directory/",
"/abs/path/",
],
)
@patch("con_duct.__main__.os.makedirs")
@patch("con_duct.__main__.os.path.exists")
@patch("builtins.open")
def test_prepare_dir_paths_available(
_mock_open: MagicMock, mock_exists: MagicMock, mock_mkdir: MagicMock, path: str
) -> None:
mock_exists.return_value = False
log_paths = LogPaths.create(path)
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.ALL)
mock_mkdir.assert_called_once_with(path, exist_ok=True)
@pytest.mark.parametrize(
"path",
[
"directory/pre_",
"nested/directory/pre_",
"/abs/path/pre_",
],
)
@patch("con_duct.__main__.os.path.exists")
@patch("con_duct.__main__.os.makedirs")
@patch("builtins.open")
def test_prefix_with_filepart_and_directory_part(
mock_open: MagicMock, mock_mkdir: MagicMock, mock_exists: MagicMock, path: str
) -> None:
mock_exists.return_value = False
log_paths = LogPaths.create(path)
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.ALL)
mock_mkdir.assert_called_once_with(os.path.dirname(path), exist_ok=True)
expected_calls = [call(each, "w") for _name, each in log_paths]
mock_open.assert_has_calls(expected_calls, any_order=True)
@patch("con_duct.__main__.os.path.exists")
@patch("con_duct.__main__.os.makedirs")
@patch("builtins.open")
def test_prefix_with_filepart_only(
mock_open: MagicMock, mock_mkdir: MagicMock, mock_exists: MagicMock
) -> None:
mock_exists.return_value = False
log_paths = LogPaths.create("filepartonly")
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.ALL)
mock_mkdir.assert_not_called()
expected_calls = [call(each, "w") for _name, each in log_paths]
mock_open.assert_has_calls(expected_calls, any_order=True)
@patch("con_duct.__main__.os.path.exists")
@patch("con_duct.__main__.os.makedirs")
@patch("builtins.open")
def test_prepare_file_paths_available_all(
mock_open: MagicMock, _mock_mkdir: MagicMock, mock_exists: MagicMock
) -> None:
mock_exists.return_value = False
prefix = "prefix_"
log_paths = LogPaths.create(prefix)
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.ALL)
expected_calls = [call(each, "w") for _name, each in log_paths]
mock_open.assert_has_calls(expected_calls, any_order=True)
@patch("con_duct.__main__.os.path.exists")
@patch("con_duct.__main__.os.makedirs")
@patch("builtins.open")
def test_prepare_file_paths_available_stdout(
mock_open: MagicMock, _mock_mkdir: MagicMock, mock_exists: MagicMock
) -> None:
mock_exists.return_value = False
prefix = "prefix_"
log_paths = LogPaths.create(prefix)
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.STDOUT)
expected_calls = [
call(each, "w") for name, each in log_paths if name != Outputs.STDERR
]
mock_open.assert_has_calls(expected_calls, any_order=True)
@patch("con_duct.__main__.os.path.exists")
@patch("con_duct.__main__.os.makedirs")
@patch("builtins.open")
def test_prepare_file_paths_available_stderr(
mock_open: MagicMock, _mock_mkdir: MagicMock, mock_exists: MagicMock
) -> None:
mock_exists.return_value = False
prefix = "prefix_"
log_paths = LogPaths.create(prefix)
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.STDERR)
expected_calls = [
call(each, "w") for name, each in log_paths if name != Outputs.STDOUT
]
mock_open.assert_has_calls(expected_calls, any_order=True)
@patch("con_duct.__main__.os.path.exists")
@patch("con_duct.__main__.os.makedirs")
@patch("builtins.open")
def test_prepare_file_paths_available_no_streams(
mock_open: MagicMock, _mock_mkdir: MagicMock, mock_exists: MagicMock
) -> None:
mock_exists.return_value = False
prefix = "prefix_"
log_paths = LogPaths.create(prefix)
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.NONE)
streams = [Outputs.STDOUT, Outputs.STDERR]
expected_calls = [
call(each, "w") for name, each in log_paths if name not in streams
]
mock_open.assert_has_calls(expected_calls, any_order=True)
@patch("con_duct.__main__.os.makedirs")
@patch("con_duct.__main__.os.path.exists")
@patch("builtins.open")
def test_prepare_paths_not_available_no_clobber(
mock_open: MagicMock, mock_exists: MagicMock, mock_mkdir: MagicMock
) -> None:
mock_exists.return_value = True
log_paths = LogPaths.create("doesntmatter")
with pytest.raises(FileExistsError):
log_paths.prepare_paths(clobber=False, capture_outputs=Outputs.ALL)
mock_mkdir.assert_not_called()
mock_open.assert_not_called()
|