Skip to content

Commit

Permalink
test: review tests to improve coverage (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheCrab13 committed Nov 8, 2023
1 parent 4e47cbc commit c1e211a
Show file tree
Hide file tree
Showing 37 changed files with 1,296 additions and 168 deletions.
2 changes: 1 addition & 1 deletion pdbstore/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def exception_exit_error(exception: Optional[BaseException]) -> ExitCode:
if isinstance(exception, SystemExit):
if exception.code != 0:
output.error(f"Exiting with code: {exception.code}")
return exception.code
return ERROR_ENCOUNTERED

assert isinstance(exception, Exception)
output.error(traceback.format_exc())
Expand Down
1 change: 0 additions & 1 deletion pdbstore/cli/commands/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ def add(parser: PDBStoreArgumentParser, *args: Any) -> Any:
else:
summary = Summary(None, OpStatus.SKIPPED, TransactionType.ADD)

print(f"error count = {len(errors_list)}")
for error in errors_list:
summary.add_file(error[0], OpStatus.FAILED, error[1])
# Clean oldest version
Expand Down
14 changes: 7 additions & 7 deletions pdbstore/cli/commands/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from pdbstore.exceptions import (
CommandLineError,
FileNotExistsError,
InvalidPEFile,
PDBAbortExecution,
PDBStoreException,
UnknowFileTypeError,
)
from pdbstore.io.output import cli_out_write, PDBStoreOutput
from pdbstore.store import (
Expand Down Expand Up @@ -69,7 +69,7 @@ def fetch_text_formatter(summary: Summary) -> None:
f"{str(file_path):<{input_len}s}{'':^10s} {error_msg or 'File not found'}"
)

total = summary.failed(True) + summary.skipped(True)
total = summary.failed(True)
if total > 0:
raise PDBAbortExecution(total)

Expand All @@ -96,7 +96,7 @@ def fetch_json_formatter(summary: Summary) -> None:

cli_out_write(json.dumps(out, indent=4))

total = summary.failed(True) + summary.skipped(True)
total = summary.failed(True)
if total > 0:
raise PDBAbortExecution(total)

Expand Down Expand Up @@ -197,19 +197,19 @@ def fetch(parser: PDBStoreArgumentParser, *args: Any) -> Any:
OpStatus.FAILED,
f"Failed to extract from transaction {entry[0].transaction_id}",
)
except UnknowFileTypeError:
except InvalidPEFile:
summary.add_file(
util.path_to_str(file_path), OpStatus.SKIPPED, "Not a known file type"
util.path_to_str(file_path), OpStatus.SKIPPED, "Not a valid pe file"
)
except FileNotExistsError:
summary.add_file(
util.path_to_str(file_path), OpStatus.FAILED, "File not found"
)
except PDBStoreException as exp:
except PDBStoreException as exp: # pragma: no cover
summary.add_file(
util.path_to_str(file_path), OpStatus.FAILED, "ex:" + str(exp)
)
except Exception as exc: # pylint: disable=broad-except
except Exception as exc: # pylint: disable=broad-except # pragma: no cover
summary.add_file(util.path_to_str(file_path), OpStatus.FAILED, str(exc))
output.error(exc)
output.error("unexpected error when querying information for {file_path}")
Expand Down
7 changes: 7 additions & 0 deletions pdbstore/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ def __init__(self, pathname: PathLike) -> None:
PDBStoreException.__init__(self, f"{pathname} : not a known file type")


class InvalidPEFile(PDBStoreException):
"""Not a valid PE file"""

def __init__(self, pathname: PathLike) -> None:
PDBStoreException.__init__(self, f"{pathname} : not a valid pe file")


class FileNotExistsError(PDBStoreException):
"""File not found"""

Expand Down
2 changes: 1 addition & 1 deletion pdbstore/io/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def init_colorama(stream: object) -> None:
:param stream: The stream to be used to determine if colorred mode is supported not
"""
if color_enabled(stream):
if os.getenv("CLICOLOR_FORCE", "0") != "0":
if os.getenv(const.ENV_CLICOLOR_FORCE, "0") != "0":
# Otherwise it is not really forced if colorama doesn't feel it
colorama.init(strip=False, convert=False)
else:
Expand Down
8 changes: 6 additions & 2 deletions pdbstore/io/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pdbstore import util
from pdbstore.exceptions import (
FileNotExistsError,
InvalidPEFile,
ParseFileError,
PDBSignatureNotFoundError,
ReadFileError,
Expand Down Expand Up @@ -131,6 +132,8 @@ def extract_dbg_info(file_path: PathLike) -> Optional[Tuple[str, str]]:
:raise:
:FileNotExistsError: The specified file doesn't exists
:UnknowFileTypeError: Unsupported file type
:InvalidPEFile: Invalid pe file (ex: exe or dll)
"""
file_path = util.path_to_str(file_path)
if not file_path or not os.path.exists(file_path):
Expand Down Expand Up @@ -191,9 +194,10 @@ def extract_dbg_info(file_path: PathLike) -> Optional[Tuple[str, str]]:
)
else:
PDBStoreOutput().error(f"{symbol_type_data[:4]} unsupported symbol type")
return None

raise InvalidPEFile(file_path)
return pdb_filename, guid
except pe.PEFormatError as pef:
raise InvalidPEFile(file_path) from pef
except BaseException: # pylint: disable=broad-exception-caught
pass
return None
Expand Down
19 changes: 13 additions & 6 deletions pdbstore/io/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def define_log_level(cls, level_name: Optional[str] = None) -> None:
"warning": LEVEL_WARNING, # -Vwaring 60
"notice": LEVEL_NOTICE, # -Vnotice 50
"status": LEVEL_STATUS, # -Vstatus 40
"info": LEVEL_STATUS, # -Vstatus 40
None: LEVEL_VERBOSE, # -V 30
"verbose": LEVEL_VERBOSE, # -Vverbose 30
"debug": LEVEL_DEBUG, # -Vdebug 20
Expand Down Expand Up @@ -114,6 +115,15 @@ def level_allowed(cls, level: int) -> bool:
"""
return cls._pdbstore_output_level <= level

@classmethod
def output_level(cls) -> int:
"""Retrieve the current output level.
Returns:
int: The current output level
"""
return cls._pdbstore_output_level

@property
def color(self) -> bool:
"""
Expand Down Expand Up @@ -194,7 +204,7 @@ def _write_message(
ret = ""
if self._scope:
if self._color:
ret = f"{fore or ''}{back or ''}{self.scope}:{Style.RESET_ALL}"
ret = f"{fore or ''}{back or ''}{self.scope}:{Style.RESET_ALL} "
else:
ret = f"{self.scope}: "

Expand Down Expand Up @@ -235,22 +245,19 @@ def verbose(
self._write_message(msg, fore=fore, back=back)
return self

def status(
def info(
self,
msg: Union[str, Dict[str, str]],
fore: Optional[str] = None,
back: Optional[str] = None,
) -> "PDBStoreOutput":
"""
Prints a statis message.
Prints a status/informative message.
"""
if self._pdbstore_output_level <= LEVEL_STATUS:
self._write_message(msg, fore=fore, back=back)
return self

# Remove in a later refactor of all the output.info calls
info = status

def title(self, msg: Union[str, Dict[str, str]]) -> "PDBStoreOutput":
"""
Prints a title.
Expand Down
2 changes: 1 addition & 1 deletion pdbstore/io/pdbfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def __init__(self, file_path: PathLike):
:PDBInvalidStreamIndexError: if invalid pdb file content
"""
pdb_path = util.str_to_path(file_path)
if not pdb_path:
if not pdb_path or not pdb_path.is_file():
raise FileNotExistsError(f"{file_path} : invalid file pdb path")

with pdb_path.open("rb") as fppdb:
Expand Down
7 changes: 5 additions & 2 deletions pdbstore/io/portablepdbfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,18 @@ def __init__(self, file_path: PathLike):
:PDBInvalidStreamIndexError: if invalid pdb file content
"""
pdb_path = util.str_to_path(file_path)
if not pdb_path:
if not pdb_path or not pdb_path.is_file():
raise FileNotExistsError(f"{file_path} : invalid file pdb path")

with pdb_path.open("rb") as fppdb:
header = fppdb.read(len(PDB_HEADER_SIGNATURE))
if header != PDB_HEADER_SIGNATURE:
raise PDBSignatureNotFoundError(str(file_path))

self._root = RootStream(fppdb)
try:
self._root = RootStream(fppdb)
except struct.error as exs:
raise ParseFileError(file_path) from exs
try:
# Extract GUID and age
self._guid = self._root.parse_guid()
Expand Down
21 changes: 15 additions & 6 deletions pdbstore/store/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def _load_entries(self) -> List[TransactionEntry]:
)

entries.append(transaction_entry)
except Exception as exc:
except Exception as exc: # pragma: no cover
raise ReadFileError(self._entries_file_path()) from exc
return entries

Expand Down Expand Up @@ -242,7 +242,7 @@ def commit(
status,
TransactionType.ADD,
)
except PDBStoreException as exc:
except PDBStoreException as exc: # pragma: no cover
summary.status = OpStatus.FAILED
summary.add_entry(
entry,
Expand All @@ -256,7 +256,7 @@ def commit(
with open(self._entries_file_path(), "ab") as fpe:
for entry in self.entries:
fpe.write(f"{entry}{os.linesep}".encode("utf-8"))
except OSError as exo:
except OSError as exo: # pragma: no cover
raise WriteFileError(self._entries_file_path()) from exo
return summary

Expand All @@ -269,25 +269,34 @@ def mark_deleted(self) -> None:
:RenameFileError: Failed to update history file
"""
src: Path = self._entries_file_path()
if not os.path.exists(src):
if not src.is_file():
PDBStoreOutput().warning(
f"{src} : file not found, so not possible to mark it as deleted",
)
return
dest: Path = Path(f"{src}.deleted")
try:
os.rename(src, dest)
except OSError as ex:
except OSError as ex: # pragma: no cover
raise RenameFileError(src, dest) from ex

def __str__(self) -> str:
"""Get transaction as a string
:return: The string representation
"""
if not self.is_committed() or not self.timestamp:
if not self.is_committed():
return ""

if self.is_delete_operation():
if not self.deleted_id:
return ""
return (
f"{self.transaction_id},{self.transaction_type.value},{self.deleted_id}"
)

if not self.timestamp:
return ""
date_stamp = self.timestamp.strftime("%m/%d/%Y")
time_stamp = self.timestamp.strftime("%H:%M:%S")

Expand Down
51 changes: 34 additions & 17 deletions pdbstore/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
from pathlib import Path

from pdbstore.typing import Any, Generator, List, Optional, PathLike, Union
Expand Down Expand Up @@ -41,39 +42,55 @@ def abbreviate(input_path: PathLike, max_length: int = 40) -> PathLike:
:param file_path: The path to abbreviate.
:param max_length: The maximum length to the truncated path.
:return: The truncate path
:return: The truncated path
"""
file_path: Path = str_to_path(input_path)
cnt = 0
ref = 0
idx = int(len(file_path.parts) / 2)
mparts: List[Optional[str]] = [
*file_path.parts,
]
mfile_path_s: str = os.fspath(file_path)
file_path: str = str(input_path)
first: bool = True
ref: int = 0

mparts: List[str] = list(
filter(lambda e: e not in ["", "\\", "/"], re.split("(\\\\|/)", file_path))
)
file_name = mparts[-1]
del mparts[-1]
if re.match("^[a-zA-Z]:$", mparts[0]):
mparts[0] += "\\"

min_abb_len = 5 if mparts[0] == "/" else 6
if max_length < (len(file_name) + min_abb_len):
return file_name
idx = int(len(mparts) / 2)
mfile_path_s = file_path
while len(mfile_path_s) > max_length:
if (idx + ref) <= 1:
cnt += 1
elif (idx + ref) >= (idx * 2 + 1):
if (idx + ref) >= (idx * 2 + 1):
break
if cnt == 0:
if first:
mparts[idx + ref] = "..."
else:
mparts[idx + ref] = None
mparts[idx + ref] = ""

filtered: List[str] = []
filtered = [] if file_path[0] != "/" else ["/"]
for mpp in mparts:
if mpp:
filtered.append(mpp)
filtered.append(file_name)
mfile_path = Path(*tuple(filtered))
mfile_path_s = os.fspath(mfile_path)
if cnt != 0:
if not first:
ref *= -1
if ref < 0:
ref -= 1
else:
ref -= 1
cnt += 1
first = False

if idx + ref >= max_length:
ref -= 1

if file_path.find("/") != -1:
mfile_path_s = mfile_path_s.replace("\\", "/")
elif file_path.find("\\") != -1:
mfile_path_s = mfile_path_s.replace("\\/", "\\").replace("/", "\\")
return mfile_path_s


Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ max-args=15 # Maximum number of arguments for function / method.
max-attributes=20 # Maximum number of attributes for a class (see R0902).
max-local=25 # Maximum number of local variables
max-bool-expr=8 # Maximum number of boolean expressions in an if statement (see R0916).

max-public-methods = 25 # Maximum number of public methods for a class (see R0904).

[tool.pytest.ini_options]
xfail_strict = true
Expand Down
34 changes: 0 additions & 34 deletions tests/cli/conftest.py

This file was deleted.

0 comments on commit c1e211a

Please sign in to comment.