diff --git a/.github/workflows/linux-tests.yml b/.github/workflows/linux-tests.yml new file mode 100644 index 0000000..e34cc2d --- /dev/null +++ b/.github/workflows/linux-tests.yml @@ -0,0 +1,26 @@ +name: Linux + +on: [push, pull_request] + +jobs: + pytests: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + pip install --upgrade pip + pip install . + pip install pytest + pip install -r requirements.txt + - name: Run unit tests + run: | + pytest -v diff --git a/.github/workflows/macos-tests.yml b/.github/workflows/macos-tests.yml new file mode 100644 index 0000000..e6851d0 --- /dev/null +++ b/.github/workflows/macos-tests.yml @@ -0,0 +1,28 @@ +name: macOS + +on: [push, pull_request] + +jobs: + pytests: + runs-on: macOS-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + pip install --upgrade pip + pip install . + pip install pytest + pip install -r requirements.txt + - name: Run unit tests + run: | + mkdir ~/testfolder + sudo chmod -R u-rwx ~/testfolder + pytest -v diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml new file mode 100644 index 0000000..28419c0 --- /dev/null +++ b/.github/workflows/windows-tests.yml @@ -0,0 +1,26 @@ +name: Windows + +on: [push, pull_request] + +jobs: + pytest: + runs-on: windows-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + pip install --upgrade pip + pip install . + pip install pytest + pip install -r requirements.txt + - name: Run unit tests + run: | + pytest -v diff --git a/README.md b/README.md index de90966..44ed843 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # livelog -Work in progress +[![Linux](https://github.com/PabloLec/livelog/actions/workflows/linux-tests.yml/badge.svg)](https://github.com/PabloLec/livelog/actions/workflows/linux-tests.yml)[![macOS](https://github.com/PabloLec/livelog/actions/workflows/macos-tests.yml/badge.svg)](https://github.com/PabloLec/livelog/actions/workflows/macos-tests.yml)[![Windows](https://github.com/PabloLec/livelog/actions/workflows/windows-tests.yml/badge.svg)](https://github.com/PabloLec/livelog/actions/workflows/windows-tests.yml) diff --git a/livelog/__main__.py b/livelog/__main__.py index 0f2792a..6bf10b9 100644 --- a/livelog/__main__.py +++ b/livelog/__main__.py @@ -41,11 +41,11 @@ def _parse_args(): args = parser.parse_args() if args.file is not None: - file = Path(args.file) + file = Path(args.file).resolve() else: file = ( Path("/tmp/livelog.log") - if system() == "Darwin" + if "darwin" in system().lower() else Path(gettempdir()) / "livelog.log" ) diff --git a/livelog/logger.py b/livelog/logger.py index e24594a..c15370e 100644 --- a/livelog/logger.py +++ b/livelog/logger.py @@ -55,7 +55,7 @@ def __init__( if file is None: self._file = Path( "/tmp/livelog.log" - if system() == "Darwin" + if "darwin" in system().lower() else Path(gettempdir()) / "livelog.log" ) else: @@ -95,10 +95,13 @@ def _verify_file(self): """ dir = self._file.parent.resolve() - if self._file.is_dir(): - raise LogFileIsADirectory(path=self._file) - if not dir.is_dir(): - raise LogPathDoesNotExist(path=dir) + try: + if self._file.is_dir(): + raise LogFileIsADirectory(path=self._file) + if not dir.is_dir(): + raise LogPathDoesNotExist(path=dir) + except PermissionError: + raise LogPathInsufficientPermissions(path=dir) if not access(dir, X_OK): raise LogPathInsufficientPermissions(path=dir) self._clear_file() diff --git a/livelog/reader.py b/livelog/reader.py index 1b38e34..e105b9a 100644 --- a/livelog/reader.py +++ b/livelog/reader.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- -from os import system, access, name, R_OK +from os import getenv, system, access, R_OK +from sys import exit as _exit +from platform import system as system_ from time import sleep from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler @@ -29,7 +31,12 @@ class Reader(FileSystemEventHandler): write to output path """ - CLEAR_CMD = "cls" if name == "nt" else "clear" + if getenv("LIVELOG_ENV") == "TEST": + CLEAR_CMD = "" + elif "windows" in system_().lower(): + CLEAR_CMD = "cls" + else: + CLEAR_CMD = "clear" LEVEL_COLORS = { "ERR!": Fore.RED, "WARN": Fore.YELLOW, @@ -38,7 +45,7 @@ class Reader(FileSystemEventHandler): } LONG_LEVEL_TO_SHORT = { "ERROR": "ERR!", - "WARN": "WARNING", + "WARNING": "WARN", "INFO": "INFO", "DEBUG": "DBUG", } @@ -69,6 +76,9 @@ def __init__(self, file: str, level: str, nocolors: bool): self.read_index = 0 system(self.CLEAR_CMD) + if not self.file_exists() and getenv("LIVELOG_ENV") == "TEST": + print("FILE NOT FOUND:", self.file) + _exit() while not self.file_exists(): print("File not found, waiting for creation.") sleep(1) @@ -80,10 +90,13 @@ def verify_file(self): """Verify if provided file path is a valid log file.""" dir = self.file.parent.resolve() - if self.file.is_dir(): - raise LogFileIsADirectory(path=self.file) - if not dir.is_dir(): - raise LogPathDoesNotExist(path=dir) + try: + if self.file.is_dir(): + raise LogFileIsADirectory(path=self.file) + if not dir.is_dir(): + raise LogPathDoesNotExist(path=dir) + except PermissionError: + raise LogPathInsufficientPermissions(path=dir) if not access(dir, R_OK): raise LogPathInsufficientPermissions(path=dir) @@ -148,10 +161,14 @@ def filter_log_level(self, lines: list): list: Filtered lines """ - for i, line in enumerate(lines): - level = line[:4] + i = 0 + for _ in range(len(lines)): + level = lines[i][:4] if self.LEVELS[self.level] > self.LEVELS[level]: del lines[i] + continue + i += 1 + return lines def color_line(self, line: str): @@ -180,6 +197,10 @@ def on_modified(self, *args, **kwargs): def loop_without_event(self): """If inotify instance limit reached, loop without watching file.""" + if getenv("LIVELOG_ENV") == "TEST": + self.print_output() + _exit() + while True: self.print_output() sleep(1) @@ -199,7 +220,11 @@ def start_reader(file: str, level: str, nocolors: bool): observer.schedule(event_handler, file, recursive=True) try: observer.start() - input("") + if getenv("LIVELOG_ENV") == "TEST": + sleep(2) + _exit() + else: + input("") observer.stop() observer.join() except OSError: diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..7543266 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,3 @@ +from os import environ + +environ["LIVELOG_ENV"] = "TEST" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..c88b9cd --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,41 @@ +import pytest +from os import getenv +from pathlib import Path +from livelog import Logger +from platform import system + + +@pytest.fixture(scope="session") +def restricted_dir(): + if "darwin" in system().lower(): + return getenv("HOME") + "/testfolder/" + else: + return "/root/" + + +@pytest.fixture(scope="session") +def system_is_windows(): + return "windows" in system().lower() + + +@pytest.fixture(scope="session") +def log_file(tmpdir_factory): + return tmpdir_factory.mktemp("tmp").join("test.log") + + +@pytest.fixture(scope="function") +def default_log_file(): + logger = Logger() + logger.debug("It works!") + + +@pytest.fixture(scope="function") +def reader_test_file(tmpdir_factory): + log_file = tmpdir_factory.mktemp("tmp").join("test.log") + logger = Logger(file=log_file) + logger.debug("debug") + logger.info("info") + logger.warn("warning") + logger.error("error") + + return Path(log_file) diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..5a687de --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,39 @@ +from subprocess import Popen, PIPE + + +def test_default(default_log_file): + print("python3 -m livelog".split()) + process = Popen("python3 -m livelog".split(), stdout=PIPE) + out, _ = process.communicate() + assert "It works" in str(out) + + +def test_custom_file(reader_test_file): + process = Popen( + f"python3 -m livelog -f {reader_test_file}".split(), + stdout=PIPE, + ) + out, _ = process.communicate() + assert "debug" in str(out) + + +def test_nocolors(reader_test_file): + process = Popen( + f"python3 -m livelog -f {reader_test_file} --nocolors".split(), + stdout=PIPE, + ) + out, _ = process.communicate() + assert "DBUG" in str(out) + assert "INFO" in str(out) + assert "WARN" in str(out) + assert "ERR!" in str(out) + + +def test_custom_level(reader_test_file): + process = Popen( + f"python3 -m livelog -f {reader_test_file} --level=INFO --nocolors".split(), + stdout=PIPE, + ) + out, _ = process.communicate() + assert "INFO" in str(out) + assert "DBUG" not in str(out) diff --git a/tests/test_logger.py b/tests/test_logger.py new file mode 100644 index 0000000..b709c19 --- /dev/null +++ b/tests/test_logger.py @@ -0,0 +1,236 @@ +from pytest import raises +from pathlib import Path +from re import findall +from livelog import Logger, LoggerSingleton, errors + + +def test_default(log_file): + logger = Logger(file=log_file) + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 1 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 1 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 1 + ) + + +def test_without_erasing(log_file): + logger = Logger(file=log_file, erase=False) + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 2 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 2 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 2 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 2 + ) + + +def test_with_erasing(log_file): + logger = Logger(file=log_file) + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 1 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 1 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 1 + ) + + +def test_log_level_info(log_file): + logger = Logger(file=log_file, level="INFO") + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 0 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 1 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 1 + ) + + +def test_log_level_warning(log_file): + logger = Logger(file=log_file, level="WARNING") + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 0 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 0 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 1 + ) + + +def test_log_level_error(log_file): + logger = Logger(file=log_file, level="ERROR") + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 0 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 0 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 0 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 1 + ) + + +def test_log_level_custom_case(log_file): + logger = Logger(file=log_file, level="iNfO") + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 0 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 1 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 1 + ) + + +def test_log_disabled(log_file): + logger = Logger(file=log_file, enabled=False) + logger.debug("0") + logger.info("1") + logger.warn("2") + logger.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 0 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 0 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 0 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 0 + ) + + +def test_singleton(log_file): + logger1 = LoggerSingleton(file=log_file) + logger1.debug("0") + logger1.info("1") + logger2 = LoggerSingleton() + logger2.warn("2") + logger2.error("3") + with open(log_file, "r") as f: + logs = f.read() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 0)", logs)) == 1 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 1)", logs)) == 1 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 2)", logs)) == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - 3)", logs)) == 1 + ) + + +def test_log_file_is_directory(log_file): + dir = Path(log_file).parent + with raises(errors.LogFileIsADirectory): + Logger(file=dir) + + +def test_wrong_log_path(): + with raises(errors.LogPathDoesNotExist): + Logger(file="/foo/bar/test.log") + + +def test_insufficient_permissions(restricted_dir, system_is_windows): + if system_is_windows: + return + + with raises(errors.LogPathInsufficientPermissions): + Logger(file=restricted_dir + "test.log") + + +def test_unknow_log_level(log_file): + with raises(errors.LogLevelDoesNotExist): + Logger(file=log_file, level="TEST") diff --git a/tests/test_reader.py b/tests/test_reader.py new file mode 100644 index 0000000..da17a58 --- /dev/null +++ b/tests/test_reader.py @@ -0,0 +1,159 @@ +from re import findall +from pytest import raises +from pathlib import Path +from colorama import Style, Fore +from livelog.reader import Reader +from livelog import errors + + +def escape(string): + return string.replace("\\", "\\\\") + + +DIM = escape(Style.DIM) +BRIGHT = escape(Style.BRIGHT) +NORMAL = escape(Style.NORMAL) +WHITE = escape(Fore.WHITE) +BLUE = escape(Fore.BLUE) +YELLOW = escape(Fore.YELLOW) +RED = escape(Fore.RED) +RESET_ALL = escape(Style.RESET_ALL) + + +def test_reader_default(reader_test_file, capfd): + Reader( + file=reader_test_file, + level="DEBUG", + nocolors=False, + ) + out, _ = capfd.readouterr() + + debug_line = findall(r"(^.* - .*debug.*\n)", out)[0] + info_line = findall(r"(\n.* - .*info.*\n)", out)[0] + warning_line = findall(r"(\n.* - .*warning.*\n)", out)[0] + error_line = findall(r"(\n.* - .*error.*\n)", out)[0] + + assert all(x in debug_line for x in (DIM, BRIGHT, NORMAL, WHITE, RESET_ALL)) + assert all(x in info_line for x in (DIM, BRIGHT, NORMAL, BLUE, RESET_ALL)) + assert all(x in warning_line for x in (DIM, BRIGHT, NORMAL, YELLOW, RESET_ALL)) + assert all(x in error_line for x in (DIM, BRIGHT, NORMAL, RED, RESET_ALL)) + + +def test_reader_level_info(reader_test_file, capfd): + Reader( + file=reader_test_file, + level="INFO", + nocolors=False, + ) + out, _ = capfd.readouterr() + + assert len(findall(r"(.* - .*debug.*\n)", out)) == 0 + assert len(findall(r"(^.* - .*info.*\n)", out)) == 1 + assert len(findall(r"(\n.* - .*warning.*\n)", out)) == 1 + assert len(findall(r"(\n.* - .*error.*\n)", out)) == 1 + + +def test_reader_level_warning(reader_test_file, capfd): + Reader( + file=reader_test_file, + level="WARNING", + nocolors=False, + ) + out, _ = capfd.readouterr() + + print(out) + + assert len(findall(r"(.* - .*debug.*\n)", out)) == 0 + assert len(findall(r"(.* - .*info.*\n)", out)) == 0 + assert len(findall(r"^(.* - .*warning.*\n)", out)) == 1 + assert len(findall(r"(\n.* - .*error.*\n)", out)) == 1 + + +def test_reader_level_error(reader_test_file, capfd): + Reader( + file=reader_test_file, + level="ERROR", + nocolors=False, + ) + out, _ = capfd.readouterr() + + print(out) + + assert len(findall(r"(.* - .*debug.*\n)", out)) == 0 + assert len(findall(r"(.* - .*info.*\n)", out)) == 0 + assert len(findall(r"(.* - .*warning.*\n)", out)) == 0 + assert len(findall(r"(^.* - .*error.*\n)", out)) == 1 + + +def test_reader_nocolors(reader_test_file, capfd): + Reader( + file=reader_test_file, + level="DEBUG", + nocolors=True, + ) + out, _ = capfd.readouterr() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - debug)", out)) + == 1 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - info)", out)) == 1 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - warning)", out)) + == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - error)", out)) + == 1 + ) + + +def test_reader_level_custom_case(reader_test_file, capfd): + Reader( + file=reader_test_file, + level="iNfO", + nocolors=True, + ) + out, _ = capfd.readouterr() + + assert ( + len(findall(r"(DBUG \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - debug)", out)) + == 0 + ) + assert ( + len(findall(r"(INFO \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - info)", out)) == 1 + ) + assert ( + len(findall(r"(WARN \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - warning)", out)) + == 1 + ) + assert ( + len(findall(r"(ERR! \\| [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} - error)", out)) + == 1 + ) + + +def test_reader_log_file_is_directory(reader_test_file): + dir = Path(reader_test_file).parent + with raises(errors.LogFileIsADirectory): + Reader(file=dir, level="DEBUG", nocolors=True) + + +def test_reader_wrong_log_path(): + with raises(errors.LogPathDoesNotExist): + Reader(file=Path("/foo/bar/test.log"), level="DEBUG", nocolors=True) + + +def test_reader_insufficient_permissions(restricted_dir, system_is_windows): + if system_is_windows: + return + + with raises(errors.LogPathInsufficientPermissions): + Reader(file=Path(restricted_dir + "test.log"), level="DEBUG", nocolors=True) + + +def test_reader_unknow_log_level(reader_test_file): + with raises(errors.LogLevelDoesNotExist): + Reader(file=reader_test_file, level="TEST", nocolors=True)