Mocking

Concourse Tools contains a number of utility functions for mocking various parts of the process for testing purposes.

Environment Variables

concoursetools.mocking.mock_environ(new_environ)[source]

Mock os.environ in a context manager.

Parameters:

new_environ (dict[str, str]) – The new environment variables. No existing environment variables are carried forward.

Example:
>>> with mock_environ({"ENV_VAR": "my-env"}):
...     for key, value in os.environ.items():
...         print(key, value)
ENV_VAR my-env
Return type:

Generator[None]

concoursetools.mocking.create_env_vars(one_off_build=False, instance_vars=None, **env_vars)[source]

Create fake environment variables for a Concourse stage.

Parameters:
  • one_off_build (bool) – Set to True if you are testing a one-off build.

  • instance_vars (dict[str, str] | None) – Pass optional instance vars to emulate an instanced pipeline.

  • env_vars (str) – Pass additional environment variables, or overload the default ones.

Example:
>>> for key, value in create_env_vars().items():
...     print(key, value)
BUILD_ID 12345678
BUILD_NAME 42
BUILD_TEAM_NAME my-team
ATC_EXTERNAL_URL https://ci.myconcourse.com
BUILD_JOB_NAME my-job
BUILD_PIPELINE_NAME my-pipeline
>>> for key, value in create_env_vars(one_off_build=True).items():
...     print(key, value)
BUILD_ID 12345678
BUILD_NAME 42
BUILD_TEAM_NAME my-team
ATC_EXTERNAL_URL https://ci.myconcourse.com
Return type:

dict[str, str]

class concoursetools.mocking.TestBuildMetadata(one_off_build=False, instance_vars=None, **env_vars)[source]

Build metadata for testing Concourse resources.

Equivalent to:

>>> metadata = BuildMetadata(**create_env_vars(...))
Parameters:
  • one_off_build (bool) – Set to True if you are testing a one-off build.

  • instance_vars (dict[str, str] | None) – Pass optional instance vars to emulate an instanced pipeline.

  • env_vars (str) – Pass additional environment variables, or overload the default ones.

Input / Output

concoursetools.mocking.mock_argv(*args)[source]

Mock sys.argv in a context manager.

Parameters:

args (str) – New args to be used.

Example:
>>> with mock_argv("/my/script.py", "input1"):
...     print(sys.argv)
['/my/script.py', 'input1']
Return type:

Generator[None]

concoursetools.mocking.mock_stdin(stdin)[source]

Mock stdin in a context manager.

Parameters:

stdin (str) – A new string to be used for the stdin.

Example:
>>> with mock_stdin("new_stdin"):
...     print(sys.stdin.read())
new_stdin
Return type:

Generator[None]

Warning

As it’s a file object, sys.stdin is only mocked once by this decorator, and subsequent calls to read() will return None.

class concoursetools.mocking.StringIOWrapper[source]

A basic wrapper around a StringIO instance for capturing stdout and stderr.

An instance of this class acts a bit like a string, to the extent that == will compare the value of the instance to a string.

Example:

Capture stderr with capture_stderr():

>>> output = StringIOWrapper()
>>> with output.capture_stderr():
...     print("abc")
...     print("def", file=sys.stderr)
abc
>>> output == "def\n"
True

Or capture both stdout and stderr with capture_stdout_and_stderr():

>>> output = StringIOWrapper()
>>> with output.capture_stdout_and_stderr():
...     print("abc")
...     print("def", file=sys.stderr)
>>> output == "abc\ndef\n"
True
property value: str

Return the current value of the inner buffer.

Seealso:

io.StringIO.getvalue()

clear()[source]

Clear the buffer.

Return type:

None

capture_stdout_and_stderr()[source]

Capture both stdout and stderr.

Seealso:

contextlib.redirect_stdout(), contextlib.redirect_stderr()

Return type:

Generator[StringIOWrapper]

capture_stderr()[source]

Capture stderr.

Seealso:

contextlib.redirect_stderr()

Return type:

Generator[StringIOWrapper]

Directory State

Often you need to mock certain files when testing your resource, which are usually accessible in the resource folders. Rather than set this up manually, you can pass a directory state to TemporaryDirectoryState to make this easier.

class concoursetools.mocking.TemporaryDirectoryState(starting_state=None, max_depth=2, encoding=None, **kwargs)[source]

A class representing the state of a temporary directory, to be used as a context manager.

Parameters:
  • starting_state (dict[str, Any] | None) –

    The starting state of the directory.Keys of the dictionary are strings (relative to that level, so the name of a folder instead of a full path.) For the values, we have the following:

    • A file is represented by a string containing the contents of the file. An empty string represents an empty file.

    • A folder is represented by a dictionary yielding more files and folders.

  • max_depth (int) – The maximum depth into which the function can descend. A value of 1 will not enter any subdirectories, a value of 2 will not enter any sub-subdirectories etc.

  • encoding (str | None) – The encoding to be used to open the files. Will use the system by default when not set.

  • kwargs (Any) – Keyword arguments to be passed to TemporaryDirectory.

Example:
>>> folder_state = {
...     "folder_1": {},
...     "folder_2": {
...         "folder_3": {
...             "file_3": "Testing 3",
...         },
...         "file_2": "Testing 2",
...     },
...     "file_1": "Testing 1",
... }
>>> with TemporaryDirectoryState(folder_state) as temp_dir:
...     file_2 = temp_dir.path / "folder_2" / "file_2"
...     print(file_2.read_text())
Testing 2
>>> file_2.read_text()
Traceback (most recent call last):
...
FileNotFoundError: [Errno 2] No such file or directory: '.../folder_2/file_2'
property path: Path

Return the path to the temporary directory.

Raises:

RuntimeError – If the temporary directory is currently closed.

property final_state: dict[str, Any]

Return the final state of the directory when it closed.

Raises:

RuntimeError – If the temporary directory is currently open.