pytest-dev / pytest-testinfra

Testinfra test your infrastructures
https://testinfra.readthedocs.io
Apache License 2.0
2.37k stars 355 forks source link

How to extend a testinfra module? #181

Open conorsch opened 7 years ago

conorsch commented 7 years ago

Hello @philpep, thanks for the great project. I'm struggling to write custom testinfra modules that extend the builtins, e.g. File. Right now I'm trying to write a module for checking attributes for X509 SSL certs, similar to what serverspec already provides. The example docs are too simple for this use case:

Here's the class-based approach I'm taking:

$ cat tests/test_x509_certificates.py 
from testinfra.modules.file import File
from testinfra.modules.command import Command
import pytest

class _X509Certificate(File):
    """
    Inspect X509 SSL certificates and expose their attributes.
    """

    def _run_openssl_command(self, params):
        """
        Private method for running openssl against certificate file.
        Used by most class properties as a helper method.
        The `.path` attribute is inherited from File().
        """
        c = Command("openssl -in {} %s".format(self.path), params)
        return c

    @property
    def email(self):
        """
        Return `email` field from X509 certificate.
        """
        return self._run_openssl_command("-email -noout").stdout

@pytest.fixture()
def X509Certificate():
    x = _X509Certificate
    return x

def test_x509_debugging(X509Certificate):
    path = '/usr/share/ca-certificates/mozilla/thawte_Primary_Root_CA.crt'
    c = X509Certificate(path)
    assert c.email == 'foo'

Can you point me in the right direction here? I've been banging my head against this for a while now. Happy to submit a docs PR once I have a working example!

philpep commented 7 years ago

Hi,

Instead of

@pytest.fixture()
def X509Certificate():
    x = _X509Certificate
    return x

Try

X509Certificate = _X509Certificate.as_fixture()

And instead of c = Command(...): c = self.run(...)

Agree that extending modules is not simple, maybe a monkeypatch could be even simple ?

mihai-satmarean commented 5 years ago

Have you got it working?

conorsch commented 5 years ago

Never did cobble together an implementation to my liking, currently using a hodge-podge of other tools to get the job done. Very interested in your results if you're successful, @mihai-satmarean !

decentral1se commented 5 years ago

Given the discussion in https://github.com/philpep/testinfra/issues/233#issue-252744553, it seems like this is a duplicate and somehow outdated since the recommended solution API has been removed?

awalker125 commented 5 years ago

I came across this today. I followed your example and got this working. https://github.com/awalker125/testinfra-extension-poc/blob/master/tests/fixtures/kubectl_binary.py

Its not exactly the same usecase but it does the job for me.