Skip to content

Commit 32cc030

Browse files
committed
install: add a first README for automated installs
Signed-off-by: Yann Dirson <[email protected]>
1 parent 7c6f9b8 commit 32cc030

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

tests/install/README.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# Automated XCP-ng installation tests
2+
3+
Note: this is a first iteration, which is bound to evolve a lot, when
4+
we find the time.
5+
6+
Those tests cover installation, upgrade, and restore, using the
7+
official installation ISO. There is a small number of actual tests,
8+
but a large number of parameters to apply the same testing steps to
9+
various situations (UEFI or BIOS, choice of a release to upgrade from,
10+
install purely from ISO or from a network pacakge repository, local SR
11+
type to create).
12+
13+
## Terminology
14+
15+
In their current state, those tests can only install XCP-ng nested
16+
inside a pre-existing XCP-ng pool. In standard terminology of
17+
hypervisor nesting, we have:
18+
19+
* L0: the pre-existing XCP-ng pool
20+
* L1: the XCP-ng host(s) exercised by the tests
21+
* L2: VMs launched by the hosts under test
22+
23+
As far as those install tests are concerned, L2 is out of scope, L0 is
24+
simply refered to as "host" and L1 as "guest".
25+
26+
When it comes to running tests against our L1, the perspective is
27+
shifting, with L1 being the "host", and L0 is then refered to as the
28+
"nest" (which for the test itself is a hidden detail of the execution
29+
environment).
30+
31+
## Prerequisites
32+
33+
L0 host must have
34+
- a default SR (where the disk images for L1 hosts will be stored)
35+
- one ISO SR (where the install images will be copied during install)
36+
37+
## Quick start
38+
39+
Use `data.py-dist` as usual as a reference to craft your `data.py`.
40+
Especially important here are:
41+
* `NETWORKS['MGMT']`, which should match the name of the network in
42+
your L0, which you want to use for the L1's management networks
43+
* `TEST_SSH_PUBKEY`, a multiline string to be used as a
44+
`.ssh/authorized_keys` in the hosts to be installed (you must have
45+
access to one of the matching private keys)
46+
* `ARP_SERVER`, a machine on the `NETWORKS['MGMT']` local network,
47+
with root access for one of the keys in `TEST_SSH_PUBKEY`, for use
48+
to determine the IP address of guests
49+
* `TOOLS['iso-remaster']`, as local path to
50+
`scripts/iso-remaster/iso-remaster.sh` from the `xcp` repo
51+
* `ISO_IMAGES_CACHE`, to specify where to cache the official ISO
52+
images
53+
* `ISO_IMAGES_BASE`, to specify the base URL under which the images in
54+
`IMAGES_ISO` can be downloaded (defaults to the official XCP-ng
55+
public download server)
56+
* `OBJECTS_NAME_PREFIX` (optional) will allow you to use a unique
57+
prefix to easily filter out *your* VMs in a shared lab
58+
59+
```
60+
XCPNG83_NIGHTLY=xcp-ng-8.3-ci-nightly-20250311.iso \
61+
pytest \
62+
--log-file-level=DEBUG --log-file=test-install.log \
63+
@tests/install/test-sequences/inst{,+upg,+upg+rst}.lst \
64+
--hosts=<L0-host-IP>
65+
```
66+
67+
The above command instructs `pytest` to:
68+
* run the test sequences as defined by the specified `.lst` files
69+
(which were specially written to chain an installation, an upgrade
70+
to same version, and a restore, all using a single nightly image)
71+
* specify
72+
* to save detailed logs in a file, while during execution only
73+
high-level progress messages are shown to avoid flooding
74+
75+
Tests to be executed can always be listed by adding to `pytest`
76+
options `--co -q`, which for the above command should show:
77+
78+
```
79+
tests/install/test.py::TestNested::test_install[uefi-83nightly-iso-ext]
80+
tests/install/test.py::TestNested::test_tune_firstboot[None-uefi-83nightly-host1-iso-ext]
81+
tests/install/test.py::TestNested::test_boot_inst[uefi-83nightly-host1-iso-ext]
82+
tests/install/test.py::TestNested::test_upgrade[uefi-83nightly-83nightly-host1-iso-ext]
83+
tests/install/test.py::TestNested::test_boot_upg[uefi-83nightly-83nightly-host1-iso-ext]
84+
tests/install/test.py::TestNested::test_restore[uefi-83nightly-83nightly-83nightly-iso-ext]
85+
tests/install/test.py::TestNested::test_boot_rst[uefi-83nightly-83nightly-83nightly-iso-ext]
86+
```
87+
88+
In order those are:
89+
* running an XCP-ng installation in a UEFI guest, using a "8.3
90+
nightly" ISO (which when using the provided `data.py-dist` will take
91+
a path or URL to an ISO from envvar `XCPNG83_NIGHTLY`), using the
92+
ISO itself as RPM source, and creating an `EXT` local SR. The ISO
93+
is first remastered to include an answerfile, as well as enable ssh
94+
access using the test key, and to shutdown instead of rebooting once
95+
installation is done.
96+
* running a helper VM to modify the firstboot configuration set by the
97+
installer, so we can select hostname, and set unique UUIDs for our
98+
L1 host
99+
* booting the installed host for the first time, check that XAPI
100+
properly starts up, that all firstboot services are starting OK, and
101+
that host is running the expected product version
102+
* running an upgrade, similarly to install test, also specifying in
103+
parameters the version of the installed host we're upgrading
104+
* booting the upgraded host for the first time, similarly to install test
105+
* running a restore, similarly to install test, also specifying in
106+
parameters the version of the upgraded host we're upgrading
107+
("version" which includes the version it was upgraded from, which
108+
still lives in the backup partition, and which is the one getting
109+
restored)
110+
* booting the restored host for the first time, similarly to install test
111+
112+
Note: the selected management network configuration uses DHCP.
113+
114+
## Caching installs and chaining tests
115+
116+
Note: some of this section applies to tests that need to manipulate
117+
the L0 host, but the cache concepts is also useful to those that just
118+
mean to launch a test against an install host from the cache. This
119+
section can possibly been split to separate those concerns.
120+
121+
To allow launching all those install steps one by one, and applying
122+
tests on the resulting L1 hosts, the state of those hosts are cached
123+
in L0 as a clone of the L1 (seen from L0 as a guest).
124+
125+
The test-chaining mechanism uses the `name-description` field to
126+
identify the output of a given test, for example `[Cache for
127+
install.test::Nested::upgrade[uefi-83nightly-83nightly-host1-iso-ext]-vm1-1857a3f0ef69640d10348e9f0adef09f6e9a7c5d]`.
128+
This includes a the shortened test name with its full test arguments,
129+
the ID of the L1 "host VM" (as a test can launch more than one), and
130+
the git revision of the test repo.
131+
132+
Currently the tests producing the image necessary for a given test are
133+
recorded using `pytest-dependencies`. As a consequence, when running
134+
a test that needs the image produced by an earlier test, the
135+
`--ignore-unknown-dependency` flag must be used, or the test will be
136+
skipped, as in:
137+
```
138+
$ XCPNG83_NIGHTLY=~/iso/xcp-ng-8.3.0.iso pytest --hosts=172.16.210.11 tests/install/test.py::TestNested::test_boot_inst[uefi-83nightly-host1-iso-ext]
139+
...
140+
SKIPPED (test_boot_inst[uefi-83nightly-host1-iso-ext] depends on TestNested::test_tune_firstboot[None-uefi-83nightly-host1-iso-ext])
141+
```
142+
143+
This git revision ensures consistency of the test runs, avoiding
144+
during test development the inadvertent use of the output of an
145+
outdated version of a given test. It thus creates a strong
146+
constraint, that all changes be committed before the test is launched.
147+
As a consequence when working on a test that needs a VM from the
148+
cache, as we don't want to rerun all the preceding tests, it requires
149+
an explicit waiver to use an image with a different revision; this is
150+
done in `data.py` in a dict specifying an equivalent cache ID to be
151+
used when one is not found:
152+
153+
IMAGE_EQUIVS = {
154+
'install.test::Nested::upgrade[bios-75-821.1-host1-iso-nosr]-vm1-6ab478747815979b22e0d0555aa2782bf33850ed':
155+
'install.test::Nested::upgrade[bios-75-821.1-host1-iso-nosr]-vm1-17ba75d798499b563bfadca98f8d22a2cb81efdc',
156+
}
157+
158+
Note: the git revision is read at the start of the test run, so you
159+
can safely go on working with your codebase while you have a test
160+
running.
161+
162+
If you're not sure of the cache IDs to put in there:
163+
* attempt to run your test, it will disclose the missing cache ID, you
164+
can paste it as a key in `IMAGE_EQUIVS`:
165+
```
166+
Mar 17 14:53:51.599 INFO Could not find a VM in cache for 'install.test::Nested::tune_firstboot[None-uefi-83nightly-host1-iso-ext]-vm1-ce73023e06d680355dbfb0b726aae8eeee0c07ff'
167+
Mar 17 14:53:51.600 ERROR exception caught...
168+
```
169+
* for the value, use the same string and just replace the git revision
170+
with the one you want to use, which must exist in your cache.
171+
Depending on the situation, you may find the revision using `git
172+
log` or `git revlog`, or possibly list the ones available in your
173+
cache with something like:
174+
```
175+
xe vm-list params=name-description | grep -F 'install.test::Nested::upgrade[bios-75-821.1-host1-iso-nosr]-vm1-'
176+
```
177+
178+
Note: this mechanism can surely be improved, suggestions welcomed.
179+
Note that a pending PR introduces the notion of "default git revision
180+
to try for a given list of images".
181+
182+
## Running classical XCP-ng tests
183+
184+
Running classical XCP-ng tests, which in our case are meant to run
185+
against the L1 host, uses a specific syntax for the `--hosts` flag,
186+
along with the `--nest=<L0-host>` flag, as in:
187+
188+
```
189+
pytest --nest=172.16.210.11 \
190+
--hosts=cache://install.test::Nested::boot_inst[uefi-83nightly-host1-iso-ext]-vm1-1857a3f0ef69640d10348e9f0adef09f6e9a7c5d \
191+
tests/misc/test_basic_without_ssh.py::test_vm_start_stop
192+
```

0 commit comments

Comments
 (0)