aiida.manage.tests package#

Testing infrastructure for easy testing of AiiDA plugins.

Submodules#

Testing infrastructure for easy testing of AiiDA plugins.

class aiida.manage.tests.main.ProfileManager(profile_name)[source]#

Bases: object

Wraps existing AiiDA profile.

__dict__ = mappingproxy({'__module__': 'aiida.manage.tests.main', '__doc__': '\n    Wraps existing AiiDA profile.\n    ', '__init__': <function ProfileManager.__init__>, 'ensure_default_user': <function ProfileManager.ensure_default_user>, 'clear_profile': <function ProfileManager.clear_profile>, 'has_profile_open': <function ProfileManager.has_profile_open>, 'destroy_all': <function ProfileManager.destroy_all>, '__dict__': <attribute '__dict__' of 'ProfileManager' objects>, '__weakref__': <attribute '__weakref__' of 'ProfileManager' objects>, '__annotations__': {}})#
__init__(profile_name)[source]#

Use an existing profile.

Parameters

profile_name – Name of the profile to be loaded

__module__ = 'aiida.manage.tests.main'#
__weakref__#

list of weak references to the object (if defined)

clear_profile()[source]#

Reset the global profile, clearing all its data and closing any open resources.

If the daemon is running, it will be stopped because it might be holding on to entities that will be cleared from the storage backend.

destroy_all()[source]#
ensure_default_user()[source]#

Ensure that the default user defined by the profile exists in the database.

has_profile_open()[source]#
class aiida.manage.tests.main.TemporaryProfileManager(backend='core.psql_dos', pgtest=None)[source]#

Bases: aiida.manage.tests.main.ProfileManager

Manage the life cycle of a completely separated and temporary AiiDA environment.

  • No profile / database setup required

  • Tests run via the TemporaryProfileManager never pollute the user’s working environment

Filesystem:

  • temporary .aiida configuration folder

  • temporary repository folder

Database:

  • temporary database cluster (via the pgtest package)

  • with aiida database user

  • with aiida_db database

AiiDA:

  • configured to use the temporary configuration

  • sets up a temporary profile for tests

All of this happens automatically when using the corresponding tests classes & tests runners (unittest) or fixtures (pytest).

Example:

tests = TemporaryProfileManager(backend=backend)
tests.create_aiida_db()  # set up only the database
tests.create_profile()  # set up a profile (creates the db too if necessary)

# ready for tests

# run tests 1

tests.clear_profile()
# database ready for independent tests 2

# run tests 2

tests.destroy_all()
# everything cleaned up
__init__(backend='core.psql_dos', pgtest=None)[source]#

Construct a TemporaryProfileManager

Parameters
  • backend – a database backend

  • pgtest – a dictionary of arguments to be passed to PGTest() for starting the postgresql cluster, e.g. {‘pg_ctl’: ‘/somepath/pg_ctl’}. Should usually not be necessary.

__module__ = 'aiida.manage.tests.main'#
_return_dir(dir_path)[source]#

Return a path to a directory from the fs environment

property backend#
property config_dir#
property config_dir_ok#
create_aiida_db()[source]#

Create the necessary database on the temporary postgres instance.

create_db_cluster()[source]#

Create the database cluster using PGTest.

create_profile()[source]#

Set AiiDA to use the tests config dir and create a default profile there

Warning: the AiiDA dbenv must not be loaded when this is called!

destroy_all()[source]#

Remove all traces of the tests run

has_profile_open()[source]#
property profile_dictionary#

Profile parameters.

Used to set up AiiDA profile from self.profile_info dictionary.

property repo#
repo_ok()[source]#
property root_dir#
property root_dir_ok#
class aiida.manage.tests.main.TestManager[source]#

Bases: object

Test manager for plugin tests.

Uses either ProfileManager for wrapping an existing profile or TemporaryProfileManager for setting up a complete temporary AiiDA environment.

For usage with pytest, see pytest_fixtures.

__dict__ = mappingproxy({'__module__': 'aiida.manage.tests.main', '__doc__': '\n    Test manager for plugin tests.\n\n    Uses either ProfileManager for wrapping an existing profile or TemporaryProfileManager for setting up a complete\n    temporary AiiDA environment.\n\n    For usage with pytest, see :py:class:`~aiida.manage.tests.pytest_fixtures`.\n    ', '__init__': <function TestManager.__init__>, 'manager': <property object>, 'use_temporary_profile': <function TestManager.use_temporary_profile>, 'use_profile': <function TestManager.use_profile>, 'has_profile_open': <function TestManager.has_profile_open>, 'reset_db': <function TestManager.reset_db>, 'clear_profile': <function TestManager.clear_profile>, 'destroy_all': <function TestManager.destroy_all>, '__dict__': <attribute '__dict__' of 'TestManager' objects>, '__weakref__': <attribute '__weakref__' of 'TestManager' objects>, '__annotations__': {}})#
__init__()[source]#
__module__ = 'aiida.manage.tests.main'#
__weakref__#

list of weak references to the object (if defined)

clear_profile()[source]#

Reset the global profile, clearing all its data and closing any open resources.

destroy_all()[source]#
has_profile_open()[source]#
property manager: aiida.manage.tests.main.ProfileManager#
reset_db()[source]#
use_profile(profile_name)[source]#

Set up Test manager to use existing profile.

Parameters

profile_name – Name of existing test profile to use.

use_temporary_profile(backend=None, pgtest=None)[source]#

Set up Test manager to use temporary AiiDA profile.

Parameters
  • backend – Backend to use.

  • pgtest – a dictionary of arguments to be passed to PGTest() for starting the postgresql cluster, e.g. {‘pg_ctl’: ‘/somepath/pg_ctl’}. Should usually not be necessary.

exception aiida.manage.tests.main.TestManagerError(msg)[source]#

Bases: Exception

Raised by TestManager in situations that may lead to inconsistent behaviour.

__init__(msg)[source]#
__module__ = 'aiida.manage.tests.main'#
__str__()[source]#

Return str(self).

__weakref__#

list of weak references to the object (if defined)

aiida.manage.tests.main.get_test_backend_name() str[source]#

Read name of storage backend from environment variable or the specified test profile.

Reads storage backend from ‘AIIDA_TEST_BACKEND’ environment variable, or the backend configured for the ‘AIIDA_TEST_PROFILE’.

Returns

name of storage backend

Raises

ValueError if unknown backend name detected.

Raises

ValueError if both ‘AIIDA_TEST_BACKEND’ and ‘AIIDA_TEST_PROFILE’ are set, and the two backends do not match.

aiida.manage.tests.main.get_test_profile_name()[source]#

Read name of test profile from environment variable.

Reads name of existing test profile ‘AIIDA_TEST_PROFILE’ environment variable. If specified, this profile is used for running the tests (instead of setting up a temporary profile).

Returns

content of environment variable or None

aiida.manage.tests.main.test_manager(backend='core.psql_dos', profile_name=None, pgtest=None)[source]#

Context manager for TestManager objects.

Sets up temporary AiiDA environment for testing or reuses existing environment, if AIIDA_TEST_PROFILE environment variable is set.

Example pytest fixture:

def aiida_profile():
    with test_manager(backend) as test_mgr:
        yield fixture_mgr

Example unittest test runner:

with test_manager(backend) as test_mgr:
    # ready for tests
# everything cleaned up
Parameters
  • backend – storage backend type name

  • profile_name – name of test profile to be used or None (to use temporary profile)

  • pgtest – a dictionary of arguments to be passed to PGTest() for starting the postgresql cluster, e.g. {‘pg_ctl’: ‘/somepath/pg_ctl’}. Should usually not be necessary.

Collection of pytest fixtures that are intended for use in plugin packages.

To use these fixtures, simply create a conftest.py in the tests folder and add the following line:

pytest_plugins = [‘aiida.manage.tests.pytest_fixtures’]

This will make all the fixtures in this file available and ready for use. Simply use them as you would any other pytest fixture.

class aiida.manage.tests.pytest_fixtures.EntryPointManager[source]#

Bases: object

Manager to temporarily add or remove entry points.

__dict__ = mappingproxy({'__module__': 'aiida.manage.tests.pytest_fixtures', '__doc__': 'Manager to temporarily add or remove entry points.', 'eps': <staticmethod object>, '_validate_entry_point': <staticmethod object>, 'add': <FunctionWrapper at 0x7faa36c89760 for function>, 'remove': <FunctionWrapper at 0x7faa36c897c0 for function>, '__dict__': <attribute '__dict__' of 'EntryPointManager' objects>, '__weakref__': <attribute '__weakref__' of 'EntryPointManager' objects>, '__annotations__': {}})#
__module__ = 'aiida.manage.tests.pytest_fixtures'#
__weakref__#

list of weak references to the object (if defined)

static _validate_entry_point(entry_point_string: str | None, group: str | None, name: str | None) tuple[str, str][source]#

Validate the definition of the entry point.

Parameters
  • entry_point_string – Fully qualified entry point string.

  • name – Entry point name.

  • group – Entry point group.

Returns

The entry point group and name.

Raises
  • TypeError – If entry_point_string, group or name are not a string, when defined.

  • ValueError – If entry_point_string is not defined, nor a group and name.

  • ValueError – If entry_point_string is not a complete entry point string with group and name.

add(value: type | str, entry_point_string: str | None = None, *, name: str | None = None, group: str | None = None) None[source]#

Add an entry point.

Parameters
  • value – The class or function to register as entry point. The resource needs to be importable, so it can’t be inlined. Alternatively, the fully qualified name can be passed as a string.

  • entry_point_string – Fully qualified entry point string.

  • name – Entry point name.

  • group – Entry point group.

Returns

The entry point group and name.

Raises
  • TypeError – If entry_point_string, group or name are not a string, when defined.

  • ValueError – If entry_point_string is not defined, nor a group and name.

  • ValueError – If entry_point_string is not a complete entry point string with group and name.

static eps()[source]#
remove(entry_point_string: str | None = None, *, name: str | None = None, group: str | None = None) None[source]#

Remove an entry point.

Parameters
  • value – Entry point value, fully qualified import path name.

  • entry_point_string – Fully qualified entry point string.

  • name – Entry point name.

  • group – Entry point group.

Returns

The entry point group and name.

Raises
  • TypeError – If entry_point_string, group or name are not a string, when defined.

  • ValueError – If entry_point_string is not defined, nor a group and name.

  • ValueError – If entry_point_string is not a complete entry point string with group and name.

aiida.manage.tests.pytest_fixtures.aiida_caplog(caplog)[source]#

A copy of pytest’s caplog fixture, which allows AIIDA_LOGGER to propagate.

aiida.manage.tests.pytest_fixtures.aiida_computer(tmp_path) Callable[[], aiida.orm.computers.Computer][source]#

Factory to return a aiida.orm.computers.Computer instance.

aiida.manage.tests.pytest_fixtures.aiida_computer_local(aiida_computer) Callable[[], aiida.orm.computers.Computer][source]#

Factory to return a aiida.orm.computers.Computer instance with core.local transport.

aiida.manage.tests.pytest_fixtures.aiida_computer_ssh(aiida_computer, ssh_key) Callable[[], aiida.orm.computers.Computer][source]#

Factory to return a aiida.orm.computers.Computer instance with core.ssh transport.

aiida.manage.tests.pytest_fixtures.aiida_instance(tmp_path_factory: pytest.TempPathFactory, aiida_manager: Manager, aiida_test_profile: str | None) t.Generator[Config, None, None][source]#

Return the Config instance that is used for the test session.

If an existing test profile is defined through the aiida_test_profile fixture, the configuration of the actual AiiDA instance is loaded and returned. If no test profile is defined, a completely independent and temporary AiiDA instance is generated in a temporary directory with a clean .aiida folder and basic configuration file. The currently loaded configuration and profile are stored in memory and are automatically restored at the end of the test session. The temporary instance is automatically deleted.

Returns

The configuration the AiiDA instance loaded for this test session.

aiida.manage.tests.pytest_fixtures.aiida_local_code_factory(aiida_localhost)[source]#

Get an AiiDA code on localhost.

Searches in the PATH for a given executable and creates an AiiDA code with provided entry point.

Usage:

def test_1(aiida_local_code_factory):
    code = aiida_local_code_factory('quantumespresso.pw', '/usr/bin/pw.x')
    # use code for testing ...
Returns

A function get_code(entry_point, executable) that returns the Code node.

Return type

object

aiida.manage.tests.pytest_fixtures.aiida_localhost(aiida_computer_local) aiida.orm.computers.Computer[source]#

Return a aiida.orm.computers.Computer instance representing localhost with core.local transport.

Usage:

def test(aiida_localhost):
    assert aiida_localhost.transport_type == 'core.local'
Returns

The computer.

aiida.manage.tests.pytest_fixtures.aiida_manager() aiida.manage.manager.Manager[source]#

Return the global instance of the Manager.

Returns

The global manager instance.

aiida.manage.tests.pytest_fixtures.aiida_profile(aiida_manager: Manager, aiida_test_profile: str | None, aiida_profile_factory: t.Callable[[dict[str, t.Any] | None], Profile], config_psql_dos: t.Callable[[dict[str, t.Any] | None], dict[str, t.Any]]) t.Generator[Profile, None, None][source]#

Return a loaded AiiDA test profile.

If a test profile has been declared, as returned by the aiida_test_profile fixture, that is loaded and yielded. Otherwise, a temporary and fully isolated AiiDA instance is created, complete with a loaded test profile, that are all automatically cleaned up at the end of the test session. The storage backend used for the profile is PsqlDosBackend.

aiida.manage.tests.pytest_fixtures.aiida_profile_clean(aiida_profile)[source]#

Provide an AiiDA test profile, with the storage reset at test function setup.

aiida.manage.tests.pytest_fixtures.aiida_profile_clean_class(aiida_profile)[source]#

Provide an AiiDA test profile, with the storage reset at test class setup.

aiida.manage.tests.pytest_fixtures.aiida_profile_factory(aiida_instance: Config, aiida_manager: Manager) t.Callable[[dict[str, t.Any]], Profile][source]#

Create a temporary profile, add it to the config of the loaded AiiDA instance and load the profile.

The default configuration is complete except for the configuration of the storage, which should be provided through the custom_configuration argument. The storage will be fully reset and initalised, destroying all data that it contains and recreate the default user, making the profile ready for use.

aiida.manage.tests.pytest_fixtures.aiida_test_profile() str | None[source]#

Return the name of the AiiDA test profile if defined.

The name is taken from the AIIDA_TEST_PROFILE environment variable.

Returns

The name of the profile to you for the test session or None if not defined.

aiida.manage.tests.pytest_fixtures.clear_database(clear_database_after_test)[source]#

Alias for ‘clear_database_after_test’.

Clears the database after each test. Use of the explicit ‘clear_database_after_test’ is preferred.

aiida.manage.tests.pytest_fixtures.clear_database_after_test(aiida_profile)[source]#

Clear the database after the test.

aiida.manage.tests.pytest_fixtures.clear_database_before_test(aiida_profile)[source]#

Clear the database before the test.

aiida.manage.tests.pytest_fixtures.clear_database_before_test_class(aiida_profile)[source]#

Clear the database before a test class.

aiida.manage.tests.pytest_fixtures.clear_profile()[source]#

Clear the currently loaded profile.

This ensures that the contents of the profile are reset as well as the Manager, which may hold references to data that will be destroyed. The daemon will also be stopped if it was running.

aiida.manage.tests.pytest_fixtures.config_psql_dos(tmp_path_factory: pytest.TempPathFactory, postgres_cluster: dict[str, str]) t.Callable[[dict[str, t.Any] | None], dict[str, t.Any]][source]#

Return a profile configuration for the PsqlDosBackend.

aiida.manage.tests.pytest_fixtures.daemon_client(aiida_profile)[source]#

Return a daemon client for the configured test profile for the test session.

The daemon will be automatically stopped at the end of the test session.

aiida.manage.tests.pytest_fixtures.entry_points(monkeypatch) aiida.manage.tests.pytest_fixtures.EntryPointManager[source]#

Return an instance of the EntryPointManager which allows to temporarily add or remove entry points.

This fixture creates a deep copy of the entry point cache returned by the aiida.plugins.entry_point.eps() method and then monkey patches that function to return the deepcopy. This ensures that the changes on the entry point cache performed during the test through the manager are undone at the end of the function scope.

Note

This fixture does not use the suppress_deprecations decorator on purpose, but instead adds it manually inside the fixture’s body. The reason is that otherwise all deprecations would be suppressed for the entire scope of the fixture, including those raised by the code run in the test using the fixture, which is not desirable.

aiida.manage.tests.pytest_fixtures.postgres_cluster(database_name: str | None = None, database_username: str | None = None, database_password: str | None = None) t.Generator[dict[str, str], None, None][source]#

Create a temporary and isolated PostgreSQL cluster using pgtest and cleanup after the yield.

Parameters
  • database_name – Name of the database.

  • database_username – Username to use for authentication.

  • database_password – Password to use for authentication.

Returns

Dictionary with parameters to connect to the PostgreSQL cluster.

aiida.manage.tests.pytest_fixtures.recursive_merge(left: dict[t.Any, t.Any], right: dict[t.Any, t.Any]) None[source]#

Recursively merge the right dictionary into the left dictionary.

Parameters
  • left – Base dictionary.

  • right – Dictionary to recurisvely merge on top of left dictionary.

aiida.manage.tests.pytest_fixtures.ssh_key(tmp_path_factory) Generator[pathlib.Path, None, None][source]#

Generate a temporary SSH key pair for the test session and return the filepath of the private key.

The filepath of the public key is the same as the private key, but it adds the .pub file extension.

aiida.manage.tests.pytest_fixtures.started_daemon_client(daemon_client)[source]#

Ensure that the daemon is running for the test profile and return the associated client.

aiida.manage.tests.pytest_fixtures.stopped_daemon_client(daemon_client)[source]#

Ensure that the daemon is not running for the test profile and return the associated client.

aiida.manage.tests.pytest_fixtures.submit_and_await(started_daemon_client)[source]#

Submit a process and wait for it to achieve the given state.

aiida.manage.tests.pytest_fixtures.suppress_deprecations(wrapper=None, enabled=None, adapter=None, proxy=<class 'FunctionWrapper'>)[source]#

Decorator that suppresses all DeprecationWarning.

aiida.manage.tests.pytest_fixtures.temp_dir()[source]#

Get a temporary directory.

E.g. to use as the working directory of an AiiDA computer.

Returns

The path to the directory

Return type

str

aiida.manage.tests.pytest_fixtures.temporary_event_loop()[source]#

Create a temporary loop for independent test case