Skip to content

Plugins


Style

Setting dd_check_style to true will enable 2 environments for enforcing our style conventions:

  1. style - This will check the formatting and will error if any issues are found. You may use the -s/--style flag of ddev test to execute only this environment.
  2. format_style - This will format the code for you, resolving the most common issues caught by style environment. You can run the formatter by using the -fs/--format-style flag of ddev test.

pytest

Our pytest plugin makes a few fixtures available globally for use during tests. Also, it's responsible for managing the control flow of E2E environments.

Fixtures

Agent stubs

The stubs provided by each fixture will automatically have their state reset before each test.

Check execution

Most tests will execute checks via the run method of the AgentCheck interface (if the check is stateful).

A consequence of this is that, unlike the check method, exceptions are not propagated to the caller meaning not only can an exception not be asserted, but also errors are silently ignored.

The dd_run_check fixture takes a check instance and executes it while also propagating any exceptions like normal.

def test_metrics(aggregator, dd_run_check):
    check = AwesomeCheck('awesome', {}, [{'port': 8080}])
    dd_run_check(check)
    ...

You can use the extract_message option to condense any exception message to just the original message rather than the full traceback.

def test_config(dd_run_check):
    check = AwesomeCheck('awesome', {}, [{'port': 'foo'}])

    with pytest.raises(Exception, match='^Option `port` must be an integer$'):
        dd_run_check(check, extract_message=True)

E2E

Agent check runner

The dd_agent_check fixture will run the integration with a given configuration on a live Agent and return a populated aggregator. It accepts a single dict configuration representing either:

  • a single instance
  • a full configuration with top level keys instances, init_config, etc.

Internally, this is a wrapper around ddev env check and you can pass through any supported options or flags.

This fixture can only be used from tests marked as e2e. For example:

@pytest.mark.e2e
def test_e2e_metrics(dd_agent_check, instance):
    aggregator = dd_agent_check(instance, rate=True)
    ...
State

Occasionally, you will need to persist some data only known at the time of environment creation (like a generated token) through the test and environment tear down phases.

To do so, use the following fixtures:

  • dd_save_state - When executing the necessary steps to spin up an environment you may use this to save any object that can be serialized to JSON. For example:

    dd_save_state('my_data', {'foo': 'bar'})
    
  • dd_get_state - This may be used to retrieve the data:

    my_data = dd_get_state('my_data', default={})
    

Mock HTTP response

The mock_http_response fixture mocks HTTP requests for the lifetime of a test.

The fixture can be used to mock the response of an endpoint. In the following example, we can mock the Prometheus output.

def test(mock_http_response):
    mock_http_response(
        """
        # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
        # TYPE go_memstats_alloc_bytes gauge
        go_memstats_alloc_bytes 6.396288e+06
        """
    )
    ...

Environment manager

The fixture dd_environment_runner manages communication between environments and the ddev env command group. You will never use it directly as it runs automatically.

It acts upon a fixture named dd_environment that every integration's test suite will define if E2E testing on a live Agent is desired. This fixture is responsible for starting and stopping environments and must adhere to the following requirements:

  1. It yields a single dict representing the default configuration the Agent will use. It must be either:

    • a single instance
    • a full configuration with top level keys instances, init_config, etc.

    Additionally, you can pass a second dict containing metadata.

  2. The setup logic must occur before the yield and the tear down logic must occur after it. Also, both steps must only execute based on the value of environment variables.

    • Setup - only if DDEV_E2E_UP is not set to false
    • Tear down - only if DDEV_E2E_DOWN is not set to false

    Note

    The provided Docker and Terraform environment runner utilities will do this automatically for you.

Metadata

  • env_type - This is the type of interface that will be used to interact with the Agent. Currently, we support docker (default) and local.
  • env_vars - A dict of environment variables and their values that will be present when starting the Agent.
  • docker_volumes - A list of str representing Docker volume mounts if env_type is docker e.g. /local/path:/agent/container/path:ro.
  • docker_platform - The container architecture to use if env_type is docker. Currently, we support linux (default) and windows.
  • logs_config - A list of configs that will be used by the Logs Agent. You will never need to use this directly, but rather via higher level abstractions.

Last update: March 7, 2024