File: README.rst

package info (click to toggle)
pytest-multihost 3.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 164 kB
  • sloc: python: 801; makefile: 4
file content (213 lines) | stat: -rw-r--r-- 6,752 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
A pytest plugin for multi-host testing.


Downloading
-----------

Release tarballs will be made available for download from Pagure Releases:
    https://pagure.io/releases/python-pytest-multihost/

The goal is to include this project in Fedora repositories. Until that happens,
you can use testing builds from COPR – see "Developer links" below.

You can also install using pip:
    https://pypi.python.org/pypi/pytest-multihost


Usage
-----

This plugin takes a description of your infrastructure,
and provides, via a fixture, Host objects that commands can be called on.

It is intended as a general base for a framework; any project using it will
need to extend it for its own needs.


The object provided to tests is a Config object, which has (among others)
these attributes::

    test_dir – directory to store test-specific data in,
               defaults to /root/multihost_tests
    ipv6 – true if connecting via IPv6

    domains – the list of domains

Hosts to run on are arranged in domains, which have::

    name – the DNS name of the domain
    type – a string specifying the type of the domain ('default' by default)

    config – the Config this domain is part of
    hosts – list of hosts in this domain

And the hosts have::

    role – type of this host; should encode the OS and installed packages
    hostname – fully qualified hostname, usually reachable from other hosts
    shortname – first component of hostname
    external_hostname – hostname used to connect to this host
    ip – IP address

    domain – the Domain this host is part of

    transport – allows operations like uploading and downloading files
    run_command() – runs the given command on the host

For each object – Config, Domain, Host – one can provide subclasses
to modify the behavior (for example, FreeIPA would add Host methods
to run a LDAP query or to install an IPA server).
Each object has from_dict and to_dict methods, which can add additional
attributes – for example, Config.ntp_server.


To use the multihost plugin in tests, create a fixture listing the domains
and what number of which host role is needed::

    import pytest
    from pytest_multihost import make_multihost_fixture

    @pytest.fixture(scope='class')
    def multihost(request):
        mh = make_multihost_fixture(
            request,
            descriptions=[
                {
                    'type': 'ipa',
                    'hosts': {
                        'master': 1,
                        'replica': 2,
                    },
                },
            ],
        )
        return mh

If not enough hosts are available, all tests that use the fixture are skipped.

The object returned from ``make_multihost_fixture`` only has the "config"
attribute.
Users are expected to add convenience attributes.
For example, FreeIPA, which typically uses a single domain with one master,
several replicas and some clients, would do::

    from pytest_multihost import make_multihost_fixture

    @pytest.fixture(scope='class')
    def multihost(request):
        mh = make_multihost_fixture(request, descriptions=[
                {
                    'type': 'ipa',
                    'hosts': {
                        'master': 1,
                        'replica': 1,
                        'client': 1,
                    },
                },
            ],
        )

        # Set convenience attributes
        mh.domain = mh.config.domains[0]
        [mh.master] = mh.domain.hosts_by_role('master')
        mh.replicas = mh.domain.hosts_by_role('replica')
        mh.clients = mh.domain.hosts_by_role('client')

        # IPA-specific initialization/teardown of the hosts
        request.cls().install(mh)
        request.addfinalizer(lambda: request.cls().uninstall(mh))

        # Return the fixture
        return mh


As with any pytest fixture, this can be used by getting it as
a function argument.
For a simplified example, FreeIPA usage could look something like this::

    class TestMultihost(object):
        def install(self, multihost):
            multihost.master.run_command(['ipa-server-install'])

        def uninstall(self, multihost):
            multihost.master.run_command(['ipa-server-install', '--uninstall'])

        def test_installed(self, multihost):
            multihost.master.run_command(['ipa', 'ping'])


The description of infrastructure is provided in a JSON or YAML file,
which is named on the py.test command line. For example::

    ssh_key_filename: ~/.ssh/id_rsa
    domains:
      - name: adomain.test
        type: test-a
        hosts:
          - name: master
            ip: 192.0.2.1
            role: master
          - name: replica1
            ip: 192.0.2.2
            role: replica
          - name: replica2
            ip: 192.0.2.3
            role: replica
            external_hostname: r2.adomain.test
          - name: client1
            ip: 192.0.2.4
            role: client
          - name: extra
            ip: 192.0.2.6
            role: extrarole
      - name: bdomain.test
        type: test-b
        hosts:
          - name: master.bdomain.test
            ip='192.0.2.65
            role: master

$ py.test --multihost-config=/path/to/configfile.yaml

To use YAML files, the PyYAML package is required. Without it only JSON files
can be used.


Encoding and bytes/text
-----------------------

When writing files or issuing commands, bytestrings are passed through
unchanged, and text strings (``unicode`` in Python 2) are encoded using
a configurable encoding (``utf-8`` by default).

When reading files, bytestrings are returned by default,
but an encoding can be given to get a test string.

For command output, separate ``stdout_bytes`` and ``stdout_text`` attributes
are provided.
The latter uses a configurable encoding (``utf-8`` by default).


Contributing
------------

The project is happy to accept patches!
Please file any patches as Pull Requests on the project's `Pagure repo`_.
Any development discussion should be in Pagure Pull Requests and Issues.


Developer links
---------------

  * Bug tracker: https://pagure.io/python-pytest-multihost/issues
  * Code browser: https://pagure.io/python-pytest-multihost/tree/master
  * git clone https://pagure.io/python-pytest-multihost.git
  * Unstable packages for Fedora: https://copr.fedoraproject.org/coprs/pviktori/pytest-plugins/

To release, update version in setup.py, add a Git tag like "v0.3",
and run `make tarball`.
Running `make upload` will put the tarball to Fedora Hosted and PyPI,
and a SRPM on Fedorapeople, if you have the rights.
Running `make release` will upload and fire a COPR build.

.. _Pagure repo: https://pagure.io/python-pytest-multihost