Writing tests for your plugins

In order to make sure your plugins don’t break when there is an architectural change in the core of the program, or to allow you some peace of mind when upgrading them, it is highly recommended to write tests.

We use the pytest library for all tests. Each plugin should have a corresponding test_[plugin].py in the tests/ directory.

In order to not have to create your own hives when testing your plugins, we have developed classes mocking all classes from python-registry. You can build a fake registry tree using these and pass it to your plugin constructor.

import pytest
from Registry.Registry import RegSZ

from regrippy.plugins.rdphint import Plugin as plugin

from .reg_mock import (LoggerMock, RegistryKeyMock, RegistryMock,
                       RegistryValueMock)


@pytest.fixture
def mock_reg():
    key = RegistryKeyMock.build("Software\\Microsoft\\Terminal Server Client\\Servers")
    reg = RegistryMock("NTUSER.DAT", "ntuser.dat", key.root())

    srv1 = RegistryKeyMock("server1.com", key)
    srv2 = RegistryKeyMock("server2.com", key)

    key.add_child(srv1)
    key.add_child(srv2)

    srv1username = RegistryValueMock("UsernameHint", "root", RegSZ)
    srv1.add_value(srv1username)

    return reg


def test_rdphint(mock_reg):
    p = plugin(mock_reg, LoggerMock(), "NTUSER.DAT", "-")

    results = list(p.run())

    assert len(results) == 2, "There should only be 2 results"
    assert results[0].key_name == "server1.com", "First server should be server1.com"
    assert results[0].custom["username"] == "root", "First server should have user hint"
    assert results[1].key_name == "server2.com", "Second server should be server2.com"
    assert results[1].custom["username"] == "", "Second server should not have username"
class reg_mock.RegistryMock

Mocks the Registry.Registry class.

Parameters
  • hive_name (str) – the “internal name” of the hive

  • hive_type (str) – the type of the hive. Usually a standard hive name in lowercase

  • root (reg_mock.RegistryKeyMock) – the root key. Use root() to get it.

hive_type()
Return type

str

hive_name()
Return type

str

root()

Returns the root key

Returns

this hive’s root key

Return type

reg_mock.RegistryKeyMock

open(path)

Opens a child key.

Parameters

path (str) – the path to the child key

Returns

the child key.

Return type

reg_mock.RegistryKeyMock

Raises

RegistryKeyNotFoundException – if the key doesn’t exist

set_ccs(number)

Helper function to create the Select key which determines which ControlSet00X key to open.

Parameters

number (int) – the current ControlSet number

class reg_mock.RegistryKeyMock

Mocks the Registry.RegistryKey class.

Parameters
  • name (str) – the name of the key

  • parent (reg_mock.RegistryKeyMock) – the parent key. If None, this means this key is the root key.

static build(path)

Build the set of keys forming the given path.

Parameters

path (str) – the path to the leaf key

Returns

the leaf key within the there

Return type

reg_mock.RegistryKeyMock

root()

Find the top-most key accessible from this key.

Returns

the root key of the hive

Return type

reg_mock.RegistryKeyMock

open(path)

Opens a child key.

Parameters

path (str) – the path to the child key

Returns

the child key.

Return type

reg_mock.RegistryKeyMock

Raises

RegistryKeyNotFoundException – if the key doesn’t exist

add_child(key)

Add a child key to this key.

Parameters

key (reg_mock.RegistryKeyMock) – The child key to add. Make sure you correctly set its parent attribute.

add_value(value)

Add a value to this key.

Parameters

value (reg_mock.RegistryValueMock) – the value to add.

path()
subkeys()
values()
name()
value(name)
class reg_mock.RegistryValueMock

Mocks the Registry.RegistryValue class.

Parameters
  • name (str) – the value name

  • data (variable) – the data contained in this value

  • type (Registry.[RegSZ, RegDWord, ...]) – the data type

name()
value()
value_type()
value_type_str()