API Reference#

Common Module#

BaseTestCase

A base class for test case.

CommandResult

is_debug_mode

Return True if the DEBUG environment variable is presence with value representing ‘True’.

run_executable

Run a command at the cwd.

get_mtime_as_datetime

has_file_changed

populate_folder_with_filenames

class grading_lib.common.BaseTestCase(methodName='runTest')#

Bases: unittest.TestCase

A base class for test case.

Variables:

with_temporary_dir – When True, create a temporary directory for each test.

Initialization

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

with_temporary_dir: bool#

None

setUp() None#
tearDown() None#
assertArchiveFileIsGzip(path: str | pathlib.Path) None#
assertFileExists(path: pathlib.Path, msg_template: str = FILE_NOT_EXIST_TEXT_TEMPLATE) None#

Pass if the file at path exist.

assertAllFilesExist(paths: list[pathlib.Path], msg: str | None = None) None#

Pass if all the listed files exist.

assertCommandSuccessful(result: grading_lib.common.CommandResult, msg_template: str = COMMAND_FAILED_TEXT_TEMPLATE) None#

Pass if the command run successfully.

assertCommandOutputEqual(result: grading_lib.common.CommandResult, expected_output: str, msg: str | None = None) None#

Pass if the command’s output is equal to output.

The msg will be formatted with command, expected_output, output

grading_lib.common.CommandResult#

‘namedtuple(…)’

grading_lib.common.is_debug_mode(variable_name: str = 'DEBUG', vals_for_true: tuple[str, ...] = ('true', 't', 'on', '1')) bool#

Return True if the DEBUG environment variable is presence with value representing ‘True’.

grading_lib.common.run_executable(args: list[str], cwd: str | pathlib.Path | None = None, timeout: float = 15.0) grading_lib.common.CommandResult#

Run a command at the cwd.

Return

  • (True, command, output) when the command completes without any error.

  • (False, command, output) when the command completes with error.

It will redirect stderr to stdout and capture stdout as output.

grading_lib.common.get_mtime_as_datetime(path: pathlib.Path | str) datetime.datetime#
grading_lib.common.has_file_changed(last_known_mtime: datetime.datetime, path: pathlib.Path | str) bool#
grading_lib.common.populate_folder_with_filenames(path: pathlib.Path | str, filnames: list[str]) None#

Makefile Module#

MakefileBaseTestCase

run_targets

Invoke the target(s) in the Makefile.

Makefile

A high-level representation of a Makefile.

Rule

VariableDefinition

class grading_lib.makefile.MakefileBaseTestCase(methodName='runTest')#

Bases: grading_lib.common.BaseTestCase

makefile_path: str | pathlib.Path#

None

makefile: grading_lib.makefile.Makefile#

None

classmethod setUpClass() None#
copy_makefile(dest: pathlib.Path | None = None, as_name: str = 'answer.mk') None#

Copy the student’s Makefile.

When dest is None, make a copy of the student’s Makefile in the same folder but with the name answer.mk.

assertHasRuleForTarget(target_name: str, msg_template: str = "Rule for a target '{target_name}' does not exist. Its behavior cannot be verified.") None#

The Makefile must have target target_name.

assertRuleRecipeIsEmpty(target_name: str, msg_template: str = "Recipe of the rule for a target '{target_name}' is not empty.") None#
grading_lib.makefile.run_targets(targets: list[str], makefile_name: str = 'answer.mk', cwd: str | pathlib.Path | None = None, timeout: float = 15.0) grading_lib.common.CommandResult#

Invoke the target(s) in the Makefile.

Return True if the call is successful, False otherwise. Also return the output of the execution.

class grading_lib.makefile.Makefile(path: pathlib.Path | str, rules: list[grading_lib.makefile.Rule])#

A high-level representation of a Makefile.

Alternative includes a tree-sitter’s one (https://github.com/alemuller/tree-sitter-make) via its python binding at https://github.com/tree-sitter/py-tree-sitter.

A Python one https://github.com/linuxlizard/pymake.

Initialization

classmethod from_path(path: pathlib.Path | str) grading_lib.makefile.Makefile#
classmethod from_text(text: str) grading_lib.makefile.Makefile#
get_rule(targets: str | list[str]) grading_lib.makefile.Rule | None#
has_rule(targets: str | list[str]) bool#
class grading_lib.makefile.Rule(targets: str | list[str], prerequisites: list[str], recipe: list[str])#

Initialization

property prereqs: list[str]#

Alias for prerequisites.

__str__() str#
__repr__() str#
is_empty() bool#
class grading_lib.makefile.VariableDefinition(name: str, value: str)#

Initialization

(Git) Repository Module#

Repository

A wrapper over git.Repo with our own utilities.

class grading_lib.repository.Repository(path: str | pathlib.Path, *args, **kwargs)#

A wrapper over git.Repo with our own utilities.

Parameters:

path – A path to repository folder. A path to a .tar.gz file is also acceptable, but cleanup() must be called to delete the temporary directory. The name of the folder inside the archive file must be “repo”.

Raises:

ValueError – When the repository does not have a working tree directory.

Initialization

__enter__() typing_extensions.Self#
__exit__(exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None) None#
cleanup() None#

Remove the temporary directory.

Must be called when the path given to the __init__ is a gzipped archive file.

to_gzip_archive(path: pathlib.Path) None#

Create an archive file of the repository.

This function will not clean up the archive file. However, if this repository is part of the temporary directory self.temp_dir, the archive will get deleted when the temporary directory is deleted.

run_executable(args: list[str], timeout: float = 15.0) grading_lib.common.CommandResult#

Run a command using repository’s working directory as cwd.

create_and_add_random_file(name: str | None = None, content: str | None = None) str#

Create a file with name and content then add it to the index.

Parameters:
  • name – If specified, this name will be used instead of the uuid4.

  • content – If specified, this will be used as content of the file. Otherwise, the name will be used.

create_random_commits(amount: int, branch: git.Head | None = None) None#

Create random commits on current branch.

Parameters:
  • amount – The amount of commits to be created.

  • head – If specified, this branch will be checked out before any commit is made. Once done, the current branch will be checked out.

get_all_tag_refs() list[git.Tag]#
get_tag_refs_at(commit_hash: str) list[git.Tag]#
visualize() str#

Run ‘git log –oneline –all –graph –decorate’ and returns the output.