unit tests minus logger working

This commit is contained in:
Jesse Bannon 2023-02-24 23:22:02 -08:00
parent b6af2c8de7
commit b9bafc7fe0
7 changed files with 74 additions and 55 deletions

View file

@ -9,6 +9,7 @@ from ytdl_sub.utils.chapters import Chapters
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.file_handler import FileHandler from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
from ytdl_sub.utils.system import IS_WINDOWS
logger = Logger.get(name="ffmpeg") logger = Logger.get(name="ffmpeg")
@ -27,7 +28,7 @@ class FFMPEG:
@classmethod @classmethod
def _ensure_installed(cls): def _ensure_installed(cls):
try: try:
if sys.platform.startswith("win32"): if IS_WINDOWS:
subprocess.check_output([".\\ffmpeg", "-version"]) subprocess.check_output([".\\ffmpeg", "-version"])
else: else:
subprocess.check_output(["which", "ffmpeg"]) subprocess.check_output(["which", "ffmpeg"])

View file

@ -1,18 +1,29 @@
import errno import errno
import os import os
import sys
from contextlib import contextmanager from contextlib import contextmanager
from pathlib import Path from pathlib import Path
from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
from ytdl_sub.utils.system import IS_WINDOWS
logger = Logger.get() logger = Logger.get()
if IS_WINDOWS:
@contextmanager
def working_directory_lock(config: ConfigFile):
logger.info(
"Working directory lock not supported in Windows. "
"Ensure only one instance of ytdl-sub runs at once using working directory %s",
config.config_options.working_directory,
)
yield
else:
import fcntl
@contextmanager @contextmanager
def _working_directory_lock_unix(config: ConfigFile): def working_directory_lock(config: ConfigFile):
""" """
Create and try to lock the file /tmp/working_directory_name Create and try to lock the file /tmp/working_directory_name
@ -23,9 +34,6 @@ def _working_directory_lock_unix(config: ConfigFile):
OSError OSError
Other lock error occurred Other lock error occurred
""" """
# pylint: disable=import-outside-toplevel
import fcntl
working_directory_path = Path(os.getcwd()) / config.config_options.working_directory working_directory_path = Path(os.getcwd()) / config.config_options.working_directory
lock_file_path = ( lock_file_path = (
Path(os.getcwd()) Path(os.getcwd())
@ -52,16 +60,3 @@ def _working_directory_lock_unix(config: ConfigFile):
fcntl.flock(lock_file, fcntl.LOCK_UN) fcntl.flock(lock_file, fcntl.LOCK_UN)
lock_file.close() lock_file.close()
@contextmanager
def working_directory_lock(config: ConfigFile):
if sys.platform.startswith("win32"):
logger.info(
"Working directory lock not supported in Windows. "
"Ensure only one instance of ytdl-sub runs at once using working directory %s",
config.config_options.working_directory,
)
yield
else:
with _working_directory_lock_unix(config):
yield

View file

@ -0,0 +1,4 @@
import sys
IS_WINDOWS = sys.platform.startswith("win32")

View file

@ -1,5 +1,6 @@
import json import json
import os.path import os.path
import sys
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import List from typing import List
@ -9,15 +10,20 @@ from resources import REGENERATE_FIXTURES
from resources import RESOURCE_PATH from resources import RESOURCE_PATH
from ytdl_sub.utils.file_handler import get_file_md5_hash from ytdl_sub.utils.file_handler import get_file_md5_hash
from ytdl_sub.utils.system import IS_WINDOWS
_EXPECTED_DOWNLOADS_SUMMARY_PATH = RESOURCE_PATH / "expected_downloads_summaries" _EXPECTED_DOWNLOADS_SUMMARY_PATH = RESOURCE_PATH / "expected_downloads_summaries"
def _get_files_in_directory(relative_directory: Path | str) -> List[Path]: def _get_files_in_directory(relative_directory: Path | str) -> List[Path]:
relative_path_part_idx = 3 # Cuts /tmp/<tmp_folder>
if IS_WINDOWS:
relative_path_part_idx = 7 # Cuts C:\Users\<user>\AppData\Local\Temp\<tmp_folder>
relative_file_paths: List[Path] = [] relative_file_paths: List[Path] = []
for path in Path(relative_directory).rglob("*"): for path in Path(relative_directory).rglob("*"):
if path.is_file(): if path.is_file():
relative_path = Path(*path.parts[3:]) relative_path = Path(*path.parts[relative_path_part_idx:])
relative_file_paths.append(relative_path) relative_file_paths.append(relative_path)
return relative_file_paths return relative_file_paths
@ -70,7 +76,8 @@ class ExpectedDownloads:
full_path = Path(relative_directory) / path full_path = Path(relative_directory) / path
assert os.path.isfile(full_path), f"Expected {path} to be a file but it is not" assert os.path.isfile(full_path), f"Expected {path} to be a file but it is not"
if path in ignore_md5_hashes_for or path.endswith(".info.json"): # TODO: Implement file hash for tests in Windows
if IS_WINDOWS or path in ignore_md5_hashes_for or path.endswith(".info.json"):
continue continue
md5_hash = get_file_md5_hash(full_file_path=full_path) md5_hash = get_file_md5_hash(full_file_path=full_path)

View file

@ -6,6 +6,7 @@ import pytest
from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.file_lock import working_directory_lock from ytdl_sub.utils.file_lock import working_directory_lock
from ytdl_sub.utils.system import IS_WINDOWS
@pytest.fixture @pytest.fixture
@ -16,6 +17,9 @@ def config() -> ConfigFile:
def test_working_directory_lock(config: ConfigFile): def test_working_directory_lock(config: ConfigFile):
if IS_WINDOWS:
return
new_pid = os.fork() new_pid = os.fork()
if new_pid == 0: # is child if new_pid == 0: # is child
with working_directory_lock(config=config): with working_directory_lock(config=config):

View file

@ -95,6 +95,9 @@ class TestLogger:
assert lines == ["[ytdl-sub:name_test] info test\n", "[ytdl-sub:name_test] debug test\n"] assert lines == ["[ytdl-sub:name_test] info test\n", "[ytdl-sub:name_test] debug test\n"]
# Ensure the file cleans up too # Ensure the file cleans up too
for handler in logger.handlers:
handler.close()
Logger.cleanup(delete_debug_file=True) Logger.cleanup(delete_debug_file=True)
assert not os.path.isfile(Logger._DEBUG_LOGGER_FILE.name) assert not os.path.isfile(Logger._DEBUG_LOGGER_FILE.name)

View file

@ -1,3 +1,5 @@
import os
import re
import tempfile import tempfile
import pytest import pytest
@ -21,10 +23,13 @@ def bad_yaml() -> str:
@pytest.fixture @pytest.fixture
def bad_yaml_file_path(bad_yaml) -> str: def bad_yaml_file_path(bad_yaml) -> str:
with tempfile.NamedTemporaryFile(suffix=".yaml") as tmp_file: # Do not delete the file in the context manager - for Windows compatibility
with tempfile.NamedTemporaryFile(suffix=".yaml", delete=False) as tmp_file:
tmp_file.write(bad_yaml.encode("utf-8")) tmp_file.write(bad_yaml.encode("utf-8"))
tmp_file.flush() tmp_file.flush()
yield tmp_file.name yield tmp_file.name
os.remove(tmp_file.name)
def test_load_yaml_file_not_found(): def test_load_yaml_file_not_found():
@ -36,6 +41,6 @@ def test_load_yaml_file_not_found():
def test_load_yaml_invalid_syntax(bad_yaml_file_path): def test_load_yaml_invalid_syntax(bad_yaml_file_path):
with pytest.raises( with pytest.raises(
InvalidYamlException, InvalidYamlException,
match=f"'{bad_yaml_file_path}' has invalid YAML, copy-paste it into a YAML checker to find the issue.", match=re.escape(f"'{bad_yaml_file_path}' has invalid YAML, copy-paste it into a YAML checker to find the issue."),
): ):
load_yaml(file_path=bad_yaml_file_path) load_yaml(file_path=bad_yaml_file_path)