blob: 7a2b42f25af2cd6e3488d706276d52f0cc6ebae9 [file] [log] [blame]
Andrew Geissler517393d2023-01-13 08:55:19 -06001.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
2
3Performing Automated Runtime Testing
4************************************
5
6The OpenEmbedded build system makes available a series of automated
7tests for images to verify runtime functionality. You can run these
8tests on either QEMU or actual target hardware. Tests are written in
9Python making use of the ``unittest`` module, and the majority of them
10run commands on the target system over SSH. This section describes how
11you set up the environment to use these tests, run available tests, and
12write and add your own tests.
13
14For information on the test and QA infrastructure available within the
15Yocto Project, see the ":ref:`ref-manual/release-process:testing and quality assurance`"
16section in the Yocto Project Reference Manual.
17
18Enabling Tests
19==============
20
21Depending on whether you are planning to run tests using QEMU or on the
22hardware, you have to take different steps to enable the tests. See the
23following subsections for information on how to enable both types of
24tests.
25
26Enabling Runtime Tests on QEMU
27------------------------------
28
29In order to run tests, you need to do the following:
30
31- *Set up to avoid interaction with sudo for networking:* To
32 accomplish this, you must do one of the following:
33
34 - Add ``NOPASSWD`` for your user in ``/etc/sudoers`` either for all
35 commands or just for ``runqemu-ifup``. You must provide the full
36 path as that can change if you are using multiple clones of the
37 source repository.
38
39 .. note::
40
41 On some distributions, you also need to comment out "Defaults
42 requiretty" in ``/etc/sudoers``.
43
44 - Manually configure a tap interface for your system.
45
46 - Run as root the script in ``scripts/runqemu-gen-tapdevs``, which
47 should generate a list of tap devices. This is the option
48 typically chosen for Autobuilder-type environments.
49
50 .. note::
51
52 - Be sure to use an absolute path when calling this script
53 with sudo.
54
Patrick Williams73bd93f2024-02-20 08:07:48 -060055 - Ensure that your host has the package ``iptables`` installed.
56
Andrew Geissler517393d2023-01-13 08:55:19 -060057 - The package recipe ``qemu-helper-native`` is required to run
58 this script. Build the package using the following command::
59
60 $ bitbake qemu-helper-native
61
62- *Set the DISPLAY variable:* You need to set this variable so that
63 you have an X server available (e.g. start ``vncserver`` for a
64 headless machine).
65
66- *Be sure your host's firewall accepts incoming connections from
67 192.168.7.0/24:* Some of the tests (in particular DNF tests) start an
68 HTTP server on a random high number port, which is used to serve
69 files to the target. The DNF module serves
70 ``${WORKDIR}/oe-rootfs-repo`` so it can run DNF channel commands.
71 That means your host's firewall must accept incoming connections from
72 192.168.7.0/24, which is the default IP range used for tap devices by
73 ``runqemu``.
74
75- *Be sure your host has the correct packages installed:* Depending
76 your host's distribution, you need to have the following packages
77 installed:
78
79 - Ubuntu and Debian: ``sysstat`` and ``iproute2``
80
81 - openSUSE: ``sysstat`` and ``iproute2``
82
83 - Fedora: ``sysstat`` and ``iproute``
84
85 - CentOS: ``sysstat`` and ``iproute``
86
87Once you start running the tests, the following happens:
88
89#. A copy of the root filesystem is written to ``${WORKDIR}/testimage``.
90
91#. The image is booted under QEMU using the standard ``runqemu`` script.
92
93#. A default timeout of 500 seconds occurs to allow for the boot process
94 to reach the login prompt. You can change the timeout period by
95 setting
96 :term:`TEST_QEMUBOOT_TIMEOUT`
97 in the ``local.conf`` file.
98
99#. Once the boot process is reached and the login prompt appears, the
100 tests run. The full boot log is written to
101 ``${WORKDIR}/testimage/qemu_boot_log``.
102
103#. Each test module loads in the order found in :term:`TEST_SUITES`. You can
104 find the full output of the commands run over SSH in
105 ``${WORKDIR}/testimgage/ssh_target_log``.
106
107#. If no failures occur, the task running the tests ends successfully.
108 You can find the output from the ``unittest`` in the task log at
109 ``${WORKDIR}/temp/log.do_testimage``.
110
111Enabling Runtime Tests on Hardware
112----------------------------------
113
114The OpenEmbedded build system can run tests on real hardware, and for
115certain devices it can also deploy the image to be tested onto the
116device beforehand.
117
118For automated deployment, a "controller image" is installed onto the
119hardware once as part of setup. Then, each time tests are to be run, the
120following occurs:
121
122#. The controller image is booted into and used to write the image to be
123 tested to a second partition.
124
125#. The device is then rebooted using an external script that you need to
126 provide.
127
128#. The device boots into the image to be tested.
129
130When running tests (independent of whether the image has been deployed
131automatically or not), the device is expected to be connected to a
132network on a pre-determined IP address. You can either use static IP
133addresses written into the image, or set the image to use DHCP and have
134your DHCP server on the test network assign a known IP address based on
135the MAC address of the device.
136
137In order to run tests on hardware, you need to set :term:`TEST_TARGET` to an
138appropriate value. For QEMU, you do not have to change anything, the
139default value is "qemu". For running tests on hardware, the following
140options are available:
141
142- *"simpleremote":* Choose "simpleremote" if you are going to run tests
143 on a target system that is already running the image to be tested and
144 is available on the network. You can use "simpleremote" in
145 conjunction with either real hardware or an image running within a
146 separately started QEMU or any other virtual machine manager.
147
148- *"SystemdbootTarget":* Choose "SystemdbootTarget" if your hardware is
149 an EFI-based machine with ``systemd-boot`` as bootloader and
150 ``core-image-testmaster`` (or something similar) is installed. Also,
151 your hardware under test must be in a DHCP-enabled network that gives
152 it the same IP address for each reboot.
153
154 If you choose "SystemdbootTarget", there are additional requirements
155 and considerations. See the
156 ":ref:`dev-manual/runtime-testing:selecting systemdboottarget`" section, which
157 follows, for more information.
158
159- *"BeagleBoneTarget":* Choose "BeagleBoneTarget" if you are deploying
160 images and running tests on the BeagleBone "Black" or original
161 "White" hardware. For information on how to use these tests, see the
162 comments at the top of the BeagleBoneTarget
163 ``meta-yocto-bsp/lib/oeqa/controllers/beaglebonetarget.py`` file.
164
Andrew Geissler517393d2023-01-13 08:55:19 -0600165- *"GrubTarget":* Choose "GrubTarget" if you are deploying images and running
166 tests on any generic PC that boots using GRUB. For information on how
167 to use these tests, see the comments at the top of the GrubTarget
168 ``meta-yocto-bsp/lib/oeqa/controllers/grubtarget.py`` file.
169
170- *"your-target":* Create your own custom target if you want to run
171 tests when you are deploying images and running tests on a custom
172 machine within your BSP layer. To do this, you need to add a Python
173 unit that defines the target class under ``lib/oeqa/controllers/``
174 within your layer. You must also provide an empty ``__init__.py``.
175 For examples, see files in ``meta-yocto-bsp/lib/oeqa/controllers/``.
176
177Selecting SystemdbootTarget
178---------------------------
179
180If you did not set :term:`TEST_TARGET` to "SystemdbootTarget", then you do
181not need any information in this section. You can skip down to the
182":ref:`dev-manual/runtime-testing:running tests`" section.
183
184If you did set :term:`TEST_TARGET` to "SystemdbootTarget", you also need to
185perform a one-time setup of your controller image by doing the following:
186
187#. *Set EFI_PROVIDER:* Be sure that :term:`EFI_PROVIDER` is as follows::
188
189 EFI_PROVIDER = "systemd-boot"
190
191#. *Build the controller image:* Build the ``core-image-testmaster`` image.
192 The ``core-image-testmaster`` recipe is provided as an example for a
193 "controller" image and you can customize the image recipe as you would
194 any other recipe.
195
Patrick Williams39653562024-03-01 08:54:02 -0600196 Image recipe requirements are:
Andrew Geissler517393d2023-01-13 08:55:19 -0600197
198 - Inherits ``core-image`` so that kernel modules are installed.
199
200 - Installs normal linux utilities not BusyBox ones (e.g. ``bash``,
201 ``coreutils``, ``tar``, ``gzip``, and ``kmod``).
202
203 - Uses a custom :term:`Initramfs` image with a custom
204 installer. A normal image that you can install usually creates a
205 single root filesystem partition. This image uses another installer that
206 creates a specific partition layout. Not all Board Support
207 Packages (BSPs) can use an installer. For such cases, you need to
208 manually create the following partition layout on the target:
209
210 - First partition mounted under ``/boot``, labeled "boot".
211
212 - The main root filesystem partition where this image gets installed,
213 which is mounted under ``/``.
214
215 - Another partition labeled "testrootfs" where test images get
216 deployed.
217
218#. *Install image:* Install the image that you just built on the target
219 system.
220
221The final thing you need to do when setting :term:`TEST_TARGET` to
222"SystemdbootTarget" is to set up the test image:
223
224#. *Set up your local.conf file:* Make sure you have the following
225 statements in your ``local.conf`` file::
226
227 IMAGE_FSTYPES += "tar.gz"
Andrew Geissler20137392023-10-12 04:59:14 -0600228 IMAGE_CLASSES += "testimage"
Andrew Geissler517393d2023-01-13 08:55:19 -0600229 TEST_TARGET = "SystemdbootTarget"
230 TEST_TARGET_IP = "192.168.2.3"
231
232#. *Build your test image:* Use BitBake to build the image::
233
234 $ bitbake core-image-sato
235
236Power Control
237-------------
238
239For most hardware targets other than "simpleremote", you can control
240power:
241
242- You can use :term:`TEST_POWERCONTROL_CMD` together with
243 :term:`TEST_POWERCONTROL_EXTRA_ARGS` as a command that runs on the host
244 and does power cycling. The test code passes one argument to that
245 command: off, on or cycle (off then on). Here is an example that
246 could appear in your ``local.conf`` file::
247
248 TEST_POWERCONTROL_CMD = "powercontrol.exp test 10.11.12.1 nuc1"
249
250 In this example, the expect
251 script does the following:
252
253 .. code-block:: shell
254
255 ssh test@10.11.12.1 "pyctl nuc1 arg"
256
257 It then runs a Python script that controls power for a label called
258 ``nuc1``.
259
260 .. note::
261
262 You need to customize :term:`TEST_POWERCONTROL_CMD` and
263 :term:`TEST_POWERCONTROL_EXTRA_ARGS` for your own setup. The one requirement
264 is that it accepts "on", "off", and "cycle" as the last argument.
265
266- When no command is defined, it connects to the device over SSH and
267 uses the classic reboot command to reboot the device. Classic reboot
268 is fine as long as the machine actually reboots (i.e. the SSH test
269 has not failed). It is useful for scenarios where you have a simple
270 setup, typically with a single board, and where some manual
271 interaction is okay from time to time.
272
273If you have no hardware to automatically perform power control but still
274wish to experiment with automated hardware testing, you can use the
275``dialog-power-control`` script that shows a dialog prompting you to perform
276the required power action. This script requires either KDialog or Zenity
277to be installed. To use this script, set the
278:term:`TEST_POWERCONTROL_CMD`
279variable as follows::
280
281 TEST_POWERCONTROL_CMD = "${COREBASE}/scripts/contrib/dialog-power-control"
282
283Serial Console Connection
284-------------------------
285
286For test target classes requiring a serial console to interact with the
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600287bootloader (e.g. BeagleBoneTarget and GrubTarget),
Andrew Geissler517393d2023-01-13 08:55:19 -0600288you need to specify a command to use to connect to the serial console of
289the target machine by using the
290:term:`TEST_SERIALCONTROL_CMD`
291variable and optionally the
292:term:`TEST_SERIALCONTROL_EXTRA_ARGS`
293variable.
294
295These cases could be a serial terminal program if the machine is
296connected to a local serial port, or a ``telnet`` or ``ssh`` command
297connecting to a remote console server. Regardless of the case, the
298command simply needs to connect to the serial console and forward that
299connection to standard input and output as any normal terminal program
300does. For example, to use the picocom terminal program on serial device
301``/dev/ttyUSB0`` at 115200bps, you would set the variable as follows::
302
303 TEST_SERIALCONTROL_CMD = "picocom /dev/ttyUSB0 -b 115200"
304
305For local
306devices where the serial port device disappears when the device reboots,
307an additional "serdevtry" wrapper script is provided. To use this
308wrapper, simply prefix the terminal command with
309``${COREBASE}/scripts/contrib/serdevtry``::
310
311 TEST_SERIALCONTROL_CMD = "${COREBASE}/scripts/contrib/serdevtry picocom -b 115200 /dev/ttyUSB0"
312
313Running Tests
314=============
315
316You can start the tests automatically or manually:
317
318- *Automatically running tests:* To run the tests automatically after the
319 OpenEmbedded build system successfully creates an image, first set the
320 :term:`TESTIMAGE_AUTO` variable to "1" in your ``local.conf`` file in the
321 :term:`Build Directory`::
322
323 TESTIMAGE_AUTO = "1"
324
325 Next, build your image. If the image successfully builds, the
326 tests run::
327
328 bitbake core-image-sato
329
330- *Manually running tests:* To manually run the tests, first globally
331 inherit the :ref:`ref-classes-testimage` class by editing your
332 ``local.conf`` file::
333
Andrew Geissler20137392023-10-12 04:59:14 -0600334 IMAGE_CLASSES += "testimage"
Andrew Geissler517393d2023-01-13 08:55:19 -0600335
336 Next, use BitBake to run the tests::
337
338 bitbake -c testimage image
339
340All test files reside in ``meta/lib/oeqa/runtime/cases`` in the
341:term:`Source Directory`. A test name maps
342directly to a Python module. Each test module may contain a number of
343individual tests. Tests are usually grouped together by the area tested
344(e.g tests for systemd reside in ``meta/lib/oeqa/runtime/cases/systemd.py``).
345
346You can add tests to any layer provided you place them in the proper
347area and you extend :term:`BBPATH` in
348the ``local.conf`` file as normal. Be sure that tests reside in
349``layer/lib/oeqa/runtime/cases``.
350
351.. note::
352
353 Be sure that module names do not collide with module names used in
354 the default set of test modules in ``meta/lib/oeqa/runtime/cases``.
355
356You can change the set of tests run by appending or overriding
357:term:`TEST_SUITES` variable in
358``local.conf``. Each name in :term:`TEST_SUITES` represents a required test
359for the image. Test modules named within :term:`TEST_SUITES` cannot be
360skipped even if a test is not suitable for an image (e.g. running the
361RPM tests on an image without ``rpm``). Appending "auto" to
362:term:`TEST_SUITES` causes the build system to try to run all tests that are
363suitable for the image (i.e. each test module may elect to skip itself).
364
365The order you list tests in :term:`TEST_SUITES` is important and influences
366test dependencies. Consequently, tests that depend on other tests should
367be added after the test on which they depend. For example, since the
368``ssh`` test depends on the ``ping`` test, "ssh" needs to come after
369"ping" in the list. The test class provides no re-ordering or dependency
370handling.
371
372.. note::
373
374 Each module can have multiple classes with multiple test methods.
375 And, Python ``unittest`` rules apply.
376
377Here are some things to keep in mind when running tests:
378
379- The default tests for the image are defined as::
380
381 DEFAULT_TEST_SUITES:pn-image = "ping ssh df connman syslog xorg scp vnc date rpm dnf dmesg"
382
383- Add your own test to the list of the by using the following::
384
385 TEST_SUITES:append = " mytest"
386
387- Run a specific list of tests as follows::
388
389 TEST_SUITES = "test1 test2 test3"
390
391 Remember, order is important. Be sure to place a test that is
392 dependent on another test later in the order.
393
394Exporting Tests
395===============
396
397You can export tests so that they can run independently of the build
398system. Exporting tests is required if you want to be able to hand the
399test execution off to a scheduler. You can only export tests that are
400defined in :term:`TEST_SUITES`.
401
402If your image is already built, make sure the following are set in your
403``local.conf`` file::
404
405 INHERIT += "testexport"
406 TEST_TARGET_IP = "IP-address-for-the-test-target"
407 TEST_SERVER_IP = "IP-address-for-the-test-server"
408
409You can then export the tests with the
410following BitBake command form::
411
412 $ bitbake image -c testexport
413
414Exporting the tests places them in the :term:`Build Directory` in
415``tmp/testexport/``\ image, which is controlled by the :term:`TEST_EXPORT_DIR`
416variable.
417
418You can now run the tests outside of the build environment::
419
420 $ cd tmp/testexport/image
421 $ ./runexported.py testdata.json
422
423Here is a complete example that shows IP addresses and uses the
424``core-image-sato`` image::
425
426 INHERIT += "testexport"
427 TEST_TARGET_IP = "192.168.7.2"
428 TEST_SERVER_IP = "192.168.7.1"
429
430Use BitBake to export the tests::
431
432 $ bitbake core-image-sato -c testexport
433
434Run the tests outside of
435the build environment using the following::
436
437 $ cd tmp/testexport/core-image-sato
438 $ ./runexported.py testdata.json
439
440Writing New Tests
441=================
442
443As mentioned previously, all new test files need to be in the proper
444place for the build system to find them. New tests for additional
445functionality outside of the core should be added to the layer that adds
446the functionality, in ``layer/lib/oeqa/runtime/cases`` (as long as
447:term:`BBPATH` is extended in the
448layer's ``layer.conf`` file as normal). Just remember the following:
449
450- Filenames need to map directly to test (module) names.
451
452- Do not use module names that collide with existing core tests.
453
454- Minimally, an empty ``__init__.py`` file must be present in the runtime
455 directory.
456
457To create a new test, start by copying an existing module (e.g.
Patrick Williams169d7bc2024-01-05 11:33:25 -0600458``oe_syslog.py`` or ``gcc.py`` are good ones to use). Test modules can use
Andrew Geissler517393d2023-01-13 08:55:19 -0600459code from ``meta/lib/oeqa/utils``, which are helper classes.
460
461.. note::
462
463 Structure shell commands such that you rely on them and they return a
464 single code for success. Be aware that sometimes you will need to
465 parse the output. See the ``df.py`` and ``date.py`` modules for examples.
466
467You will notice that all test classes inherit ``oeRuntimeTest``, which
468is found in ``meta/lib/oetest.py``. This base class offers some helper
469attributes, which are described in the following sections:
470
471Class Methods
472-------------
473
474Class methods are as follows:
475
476- *hasPackage(pkg):* Returns "True" if ``pkg`` is in the installed
477 package list of the image, which is based on the manifest file that
478 is generated during the :ref:`ref-tasks-rootfs` task.
479
480- *hasFeature(feature):* Returns "True" if the feature is in
481 :term:`IMAGE_FEATURES` or
482 :term:`DISTRO_FEATURES`.
483
484Class Attributes
485----------------
486
487Class attributes are as follows:
488
489- *pscmd:* Equals "ps -ef" if ``procps`` is installed in the image.
490 Otherwise, ``pscmd`` equals "ps" (busybox).
491
492- *tc:* The called test context, which gives access to the
493 following attributes:
494
495 - *d:* The BitBake datastore, which allows you to use stuff such
496 as ``oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager")``.
497
498 - *testslist and testsrequired:* Used internally. The tests
499 do not need these.
500
501 - *filesdir:* The absolute path to
502 ``meta/lib/oeqa/runtime/files``, which contains helper files for
503 tests meant for copying on the target such as small files written
504 in C for compilation.
505
506 - *target:* The target controller object used to deploy and
507 start an image on a particular target (e.g. Qemu, SimpleRemote,
508 and SystemdbootTarget). Tests usually use the following:
509
510 - *ip:* The target's IP address.
511
512 - *server_ip:* The host's IP address, which is usually used
513 by the DNF test suite.
514
515 - *run(cmd, timeout=None):* The single, most used method.
516 This command is a wrapper for: ``ssh root@host "cmd"``. The
517 command returns a tuple: (status, output), which are what their
518 names imply - the return code of "cmd" and whatever output it
519 produces. The optional timeout argument represents the number
520 of seconds the test should wait for "cmd" to return. If the
521 argument is "None", the test uses the default instance's
522 timeout period, which is 300 seconds. If the argument is "0",
523 the test runs until the command returns.
524
525 - *copy_to(localpath, remotepath):*
526 ``scp localpath root@ip:remotepath``.
527
528 - *copy_from(remotepath, localpath):*
529 ``scp root@host:remotepath localpath``.
530
531Instance Attributes
532-------------------
533
534There is a single instance attribute, which is ``target``. The ``target``
535instance attribute is identical to the class attribute of the same name,
536which is described in the previous section. This attribute exists as
537both an instance and class attribute so tests can use
538``self.target.run(cmd)`` in instance methods instead of
539``oeRuntimeTest.tc.target.run(cmd)``.
540
541Installing Packages in the DUT Without the Package Manager
542==========================================================
543
544When a test requires a package built by BitBake, it is possible to
545install that package. Installing the package does not require a package
546manager be installed in the device under test (DUT). It does, however,
547require an SSH connection and the target must be using the
548``sshcontrol`` class.
549
550.. note::
551
552 This method uses ``scp`` to copy files from the host to the target, which
553 causes permissions and special attributes to be lost.
554
555A JSON file is used to define the packages needed by a test. This file
556must be in the same path as the file used to define the tests.
557Furthermore, the filename must map directly to the test module name with
558a ``.json`` extension.
559
560The JSON file must include an object with the test name as keys of an
561object or an array. This object (or array of objects) uses the following
562data:
563
564- "pkg" --- a mandatory string that is the name of the package to be
565 installed.
566
567- "rm" --- an optional boolean, which defaults to "false", that specifies
568 to remove the package after the test.
569
570- "extract" --- an optional boolean, which defaults to "false", that
571 specifies if the package must be extracted from the package format.
572 When set to "true", the package is not automatically installed into
573 the DUT.
574
Patrick Williams39653562024-03-01 08:54:02 -0600575Here is an example JSON file that handles test "foo" installing
Andrew Geissler517393d2023-01-13 08:55:19 -0600576package "bar" and test "foobar" installing packages "foo" and "bar".
577Once the test is complete, the packages are removed from the DUT::
578
579 {
580 "foo": {
581 "pkg": "bar"
582 },
583 "foobar": [
584 {
585 "pkg": "foo",
586 "rm": true
587 },
588 {
589 "pkg": "bar",
590 "rm": true
591 }
592 ]
593 }
594