artifact - File Management

Artifact module.

This module provides the Artifact class, which represents a file artifact that can be or is stored on a remote node or locally.

Example usage of the Artifact class:

from framework.testbed_model.artifact import Artifact

# Create an artifact on a remote node
artifact = Artifact(node="sut", file_name="example.txt")
# Open the artifact file in write mode
with artifact.open("w") as f:
    f.write("Hello, World!")
# Pull the artifact to the local output directory
artifact.save_locally() # This is also done automatically on object deletion
                        # if save_local_copy is set to True
# Check if the artifact exists
if artifact.exists():
    print(f"Artifact exists at {artifact.path}")
# Delete the artifact
artifact.delete()

# Create an artifact from a local file
local_artifact = Artifact.create_from(
    original_file="local_file.txt",
    node="sut",
    file_name="copied_file.txt",
)
# Copy the content of the local artifact to another artifact
another_artifact = Artifact("sut", "another_file.txt")
another_artifact.copy_contents_from(local_artifact)
TextMode

Open text mode for artifacts.

alias of Union[Literal[‘r’, ‘r+’, ‘w’, ‘w+’, ‘a’, ‘a+’, ‘x’, ‘x+’], Literal[‘rt’, ‘r+t’, ‘wt’, ‘w+t’, ‘at’, ‘a+t’, ‘xt’, ‘x+t’]]

BinaryMode

Open binary mode for artifacts.

alias of Literal[‘rb’, ‘r+b’, ‘wb’, ‘w+b’, ‘ab’, ‘a+b’, ‘xb’, ‘x+b’]

OpenMode

Open mode for artifacts, can be either text or binary mode.

alias of Union[Literal[‘r’, ‘r+’, ‘w’, ‘w+’, ‘a’, ‘a+’, ‘x’, ‘x+’], Literal[‘rt’, ‘r+t’, ‘wt’, ‘w+t’, ‘at’, ‘a+t’, ‘xt’, ‘x+t’], Literal[‘rb’, ‘r+b’, ‘wb’, ‘w+b’, ‘ab’, ‘a+b’, ‘xb’, ‘x+b’]]

make_file_path(node: Node, file_name: str, custom_path: pathlib.PurePath | None = None) PurePath
make_file_path(node: None, file_name: str, custom_path: pathlib.PurePath | None = None) Path

Make a file path for the artifact.

make_unique_file_name() str

Generate a unique filename for the artifact.

class Artifact

Bases: object

Artifact class.

Represents a file artifact that can be or is stored on a remote node or locally. It provides methods to open, read, write, and manage the artifact file, in the same familiar Python API. It also provides functionality to save a local copy of the artifact if it is remote – saved in the test run output directory. It can be used to manage files that are part of the test run, such as logs, reports, or any other files that need to be stored for later analysis.

By default, the artifact is created in the temporary directory of the node, following the tree directory structure defined by DirectoryTree and managed by the test run states.

The artifact file is not created automatically upon instantiation. The methods open() – with either w or a modes – and touch() can be used to create it.

If save_local_copy is True and there already exist a local file with the same name, it will be overwritten. If this is undesired, make sure to give distinct names to the artifacts.

save_local_copy

If True, a local copy of the artifact will be saved at the end of the lifetime of the object automatically.

Type:

bool

DIRECTORY_PERMISSIONS: ClassVar[int] = 493

Permission mode for directories created by the artifact.

TEXT_MODE_ENCODING: ClassVar[str] = 'utf-8'

Encoding used for text mode artifacts.

TEXT_MODE_NEWLINE: ClassVar[str] = '\n'

Newline character used for text mode artifacts.

__init__(node: Literal['local', 'sut', 'tg'], file_name: str = '', save_local_copy: bool = True, custom_path: pathlib.PurePath | None = None)

Constructor for an artifact.

Parameters:
  • node (Literal['local', 'sut', 'tg']) – The node identifier on which the file is.

  • file_name (str) – The name of the file. If not provided, a unique filename will be generated.

  • save_local_copy (bool) – If True, makes a local copy of the artifact in the output directory. Applies only to remote artifacts.

  • custom_path (pathlib.PurePath | None) – A custom path to save the artifact. If None, the default path will be used based on the node identifier. If a relative path is provided, it will be relative to the remote temporary directory (for remote artifacts) and local output directory (for local artifacts and copies).

open(file_mode: Literal['rb', 'r+b', 'wb', 'w+b', 'ab', 'a+b', 'xb', 'x+b'] = 'rb', buffering: int = -1) ArtifactFile
open(file_mode: Union[Literal['r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+'], Literal['rt', 'r+t', 'wt', 'w+t', 'at', 'a+t', 'xt', 'x+t']] = 'r', buffering: int = -1) TextIOWrapper

Open the artifact file.

Parameters:
  • file_mode – The mode of file opening.

  • buffering – The size of the buffer to use. If -1, the default buffer size is used.

Returns:

An instance of ArtifactFile or TextIOWrapper.

classmethod create_from(original_file: Union[Path, Artifact], node: Literal['local', 'sut', 'tg'], /, new_file_name: str = '', save_local_copy: bool = False, custom_path: pathlib.PurePath | None = None) Artifact

Create a new artifact from a local file or another artifact.

Parameters:
  • node (Literal['local', 'sut', 'tg']) – The node identifier on which the file is.

  • original_file (Union[Path, Artifact]) – The local file or artifact to copy.

  • new_file_name (str) – The name of the new file. If not provided, the name of the original file will be used.

  • save_local_copy (bool) – Makes a local copy of the artifact if True. Applies only to remote files.

  • custom_path (pathlib.PurePath | None) – A custom path to save the artifact. If None, the default path will be used based on the node identifier.

Returns:

An instance of Artifact.

Return type:

Artifact

copy_contents_from(original_file: Union[Path, Artifact]) None

Copy the content of another file or artifact into this artifact.

This action will close the file descriptor associated with self or original_file if open.

Parameters:

original_file (Union[Path, Artifact]) – The local file or artifact to copy.

Raises:

InternalError – If the provided original_file does not exist.

property path: PurePath

Return the actual path of the artifact.

property local_path: Path

Return the local path of the artifact.

save_locally() None

Copy remote artifact file and save it locally. Does nothing on local artifacts.

If there already exist a local file with the same name, it will be overwritten. If this is undesired, make sure to give distinct names to the artifacts.

delete(remove_local_copy: bool = True) None

Delete the artifact file. It also prevents a local copy from being saved.

Parameters:

remove_local_copy (bool) – If True, the local copy of the artifact will be deleted if it already exists.

touch(mode: int = 420) None

Touch the artifact file, creating it if it does not exist.

Parameters:

mode (int) – The permission mode to set for the artifact file, if just created.

chmod(mode: int = 420) None

Change the permissions of the artifact file.

Parameters:

mode (int) – The permission mode to set for the artifact file.

exists() bool

Check if the artifact file exists.

Returns:

True if the artifact file exists, False otherwise.

Return type:

bool

mkdir() None

Create all the intermediate file path directories.

class ArtifactFile

Bases: RawIOBase, BinaryIO

Artifact file wrapper class.

Provides a single interface for either local or remote files. This class implements the RawIOBase interface, allowing it to be used interchangeably with standard file objects.

__init__(fd: Union[BinaryIO, paramiko.SFTPFile], path: PurePath, mode: Union[Literal['r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+'], Literal['rt', 'r+t', 'wt', 'w+t', 'at', 'a+t', 'xt', 'x+t'], Literal['rb', 'r+b', 'wb', 'w+b', 'ab', 'a+b', 'xb', 'x+b']])

Initialize the artifact file wrapper.

Parameters:
  • fd (Union[BinaryIO, paramiko.SFTPFile]) – The file descriptor of the artifact.

  • path (PurePath) – The path of the artifact file.

  • mode (Union[Literal['r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+'], ~typing.Literal['rt', 'r+t', 'wt', 'w+t', 'at', 'a+t', 'xt', 'x+t'], ~typing.Literal['rb', 'r+b', 'wb', 'w+b', 'ab', 'a+b', 'xb', 'x+b']]) – The mode in which the artifact file was opened.

close() None

Close artifact file.

This method implements close().

read(size: int | None = -1) bytes

Read bytes from the artifact file.

This method implements read().

readline(size: int | None = -1) bytes

Read line from the artifact file.

This method implements readline().

readlines(hint: int = -1) list[bytes]

Read lines from the artifact file.

This method implements readlines().

write(data: typing_extensions.Buffer) int

Write bytes to the artifact file.

Returns the number of bytes written if available, otherwise -1.

This method implements write().

writelines(lines: Iterable[typing_extensions.Buffer])

Write lines to the artifact file.

This method implements writelines().

flush() None

Flush the write buffers to the artifact file if applicable.

This method implements flush().

seek(offset: int, whence: int = 0) int

Change the file position to the given byte offset.

This method implements seek().

tell() int

Return the current absolute file position.

This method implements tell().

truncate(size: int | None = None) int

Change the size of the file to size or to the current position.

This method implements truncate().

property name: str

Return the name of the artifact file.

This method implements name().

property mode: str

Return the mode in which the artifact file was opened.

This method implements mode().

property closed: bool

True if the file is closed.

fileno() int

Return the underlying file descriptor.

This method implements fileno().

isatty() bool

Return True if the file is connected to a terminal device.

This method implements isatty().

readable() bool

Return True if the file is readable.

This method implements readable().

writable() bool

Return True if the file is writable.

This method implements writable().

seekable() bool

Return True if the file is seekable.

This method implements seekable().