summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bonnans <laurent.bonnans@here.com>2019-03-19 16:45:34 +0100
committerLaurent Bonnans <laurent.bonnans@here.com>2019-03-20 14:13:41 +0100
commit8b98e1e0f908ef30f5a4459f2bd62442d2b6649b (patch)
tree59d17466158dbba27c0371294819fa52e94861e1
parentececedcbd58a7cd04eea0a7faf7b04939536a555 (diff)
downloadmeta-updater-8b98e1e0f908ef30f5a4459f2bd62442d2b6649b.tar.gz
Split oe-selftests by target machines
To allow for more targeted testing Signed-off-by: Laurent Bonnans <laurent.bonnans@here.com>
-rw-r--r--README.adoc2
-rw-r--r--lib/oeqa/selftest/cases/testutils.py103
-rw-r--r--lib/oeqa/selftest/cases/updater_minnowboard.py71
-rw-r--r--lib/oeqa/selftest/cases/updater_native.py47
-rw-r--r--lib/oeqa/selftest/cases/updater_qemux86_64.py (renamed from lib/oeqa/selftest/cases/updater.py)269
-rw-r--r--lib/oeqa/selftest/cases/updater_raspberrypi.py78
6 files changed, 303 insertions, 267 deletions
diff --git a/README.adoc b/README.adoc
index 0ce1069..cc01612 100644
--- a/README.adoc
+++ b/README.adoc
@@ -228,7 +228,7 @@ sudo apt install ovmf
2285. Run oe-selftest: 2285. Run oe-selftest:
229+ 229+
230``` 230```
231oe-selftest --run-tests updater 231oe-selftest -r updater_native updater_qemux86_64 updater_minnowboard updater_raspberrypi
232``` 232```
233 233
234For more information about oe-selftest, including details about how to run individual test modules or classes, please refer to the https://wiki.yoctoproject.org/wiki/Oe-selftest[Yocto Project wiki]. 234For more information about oe-selftest, including details about how to run individual test modules or classes, please refer to the https://wiki.yoctoproject.org/wiki/Oe-selftest[Yocto Project wiki].
diff --git a/lib/oeqa/selftest/cases/testutils.py b/lib/oeqa/selftest/cases/testutils.py
new file mode 100644
index 0000000..77bcad7
--- /dev/null
+++ b/lib/oeqa/selftest/cases/testutils.py
@@ -0,0 +1,103 @@
1import os
2import logging
3import re
4import subprocess
5from time import sleep
6
7from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
8from qemucommand import QemuCommand
9
10
11def qemu_launch(efi=False, machine=None, imagename=None):
12 logger = logging.getLogger("selftest")
13 logger.info('Running bitbake to build core-image-minimal')
14 bitbake('core-image-minimal')
15 # Create empty object.
16 args = type('', (), {})()
17 if imagename:
18 args.imagename = imagename
19 else:
20 args.imagename = 'core-image-minimal'
21 args.mac = None
22 # Could use DEPLOY_DIR_IMAGE here but it's already in the machine
23 # subdirectory.
24 args.dir = 'tmp/deploy/images'
25 args.efi = efi
26 args.machine = machine
27 qemu_use_kvm = get_bb_var("QEMU_USE_KVM")
28 if qemu_use_kvm and \
29 (qemu_use_kvm == 'True' and 'x86' in machine or
30 get_bb_var('MACHINE') in qemu_use_kvm.split()):
31 args.kvm = True
32 else:
33 args.kvm = None # Autodetect
34 args.no_gui = True
35 args.gdb = False
36 args.pcap = None
37 args.overlay = None
38 args.dry_run = False
39 args.secondary_network = False
40
41 qemu = QemuCommand(args)
42 cmdline = qemu.command_line()
43 print('Booting image with run-qemu-ota...')
44 s = subprocess.Popen(cmdline)
45 sleep(10)
46 return qemu, s
47
48
49def qemu_terminate(s):
50 try:
51 s.terminate()
52 except KeyboardInterrupt:
53 pass
54
55
56def qemu_send_command(port, command):
57 command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' +
58 str(port) + ' "' + command + '"']
59 s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
60 stdout, stderr = s2.communicate(timeout=60)
61 return stdout, stderr, s2.returncode
62
63
64def akt_native_run(testInst, cmd, **kwargs):
65 # run a command supplied by aktualizr-native and checks that:
66 # - the executable exists
67 # - the command runs without error
68 # NOTE: the base test class must have built aktualizr-native (in
69 # setUpClass, for example)
70 bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'],
71 'aktualizr-native')
72 sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix']
73 sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir']
74 libdir = bb_vars['libdir']
75
76 program, *_ = cmd.split(' ')
77 p = '{}/{}'.format(sysrootbin, program)
78 testInst.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p))
79 env = dict(os.environ)
80 env['LD_LIBRARY_PATH'] = libdir
81 result = runCmd(cmd, env=env, native_sysroot=sysroot, ignore_status=True, **kwargs)
82 testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
83
84
85def verifyProvisioned(testInst, machine):
86 # Verify that device HAS provisioned.
87 for delay in [5, 5, 5, 5, 10, 10, 10, 10]:
88 stdout, stderr, retcode = testInst.qemu_command('aktualizr-info')
89 if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0:
90 break
91 sleep(delay)
92 testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
93 testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout,
94 'Provisioning failed: ' + stderr.decode() + stdout.decode())
95 testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
96 p = re.compile(r'Device ID: ([a-z0-9-]*)\n')
97 m = p.search(stdout.decode())
98 testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
99 testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
100 logger = logging.getLogger("selftest")
101 logger.info('Device successfully provisioned with ID: ' + m.group(1))
102
103# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater_minnowboard.py b/lib/oeqa/selftest/cases/updater_minnowboard.py
new file mode 100644
index 0000000..97b2a86
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_minnowboard.py
@@ -0,0 +1,71 @@
1import os
2import re
3from time import sleep
4
5from oeqa.selftest.case import OESelftestTestCase
6from oeqa.utils.commands import runCmd, bitbake, get_bb_var
7from testutils import qemu_launch, qemu_send_command, qemu_terminate, verifyProvisioned
8
9
10class MinnowTests(OESelftestTestCase):
11
12 def setUpLocal(self):
13 layer_intel = "meta-intel"
14 layer_minnow = "meta-updater-minnowboard"
15 result = runCmd('bitbake-layers show-layers')
16 # Assume the directory layout for finding other layers. We could also
17 # make assumptions by using 'show-layers', but either way, if the
18 # layers we need aren't where we expect them, we are out of luck.
19 path = os.path.abspath(os.path.dirname(__file__))
20 metadir = path + "/../../../../../"
21 if re.search(layer_intel, result.output) is None:
22 self.meta_intel = metadir + layer_intel
23 runCmd('bitbake-layers add-layer "%s"' % self.meta_intel)
24 else:
25 self.meta_intel = None
26 if re.search(layer_minnow, result.output) is None:
27 self.meta_minnow = metadir + layer_minnow
28 runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow)
29 else:
30 self.meta_minnow = None
31 self.append_config('MACHINE = "intel-corei7-64"')
32 self.append_config('OSTREE_BOOTLOADER = "grub"')
33 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
34 self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64')
35
36 def tearDownLocal(self):
37 qemu_terminate(self.s)
38 if self.meta_intel:
39 runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True)
40 if self.meta_minnow:
41 runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True)
42
43 def qemu_command(self, command):
44 return qemu_send_command(self.qemu.ssh_port, command)
45
46 def test_provisioning(self):
47 print('Checking machine name (hostname) of device:')
48 stdout, stderr, retcode = self.qemu_command('hostname')
49 self.assertEqual(retcode, 0, "Unable to check hostname. " +
50 "Is an ssh daemon (such as dropbear or openssh) installed on the device?")
51 machine = get_bb_var('MACHINE', 'core-image-minimal')
52 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
53 # Strip off line ending.
54 value = stdout.decode()[:-1]
55 self.assertEqual(value, machine,
56 'MACHINE does not match hostname: ' + machine + ', ' + value +
57 '\nIs TianoCore ovmf installed on your host machine?')
58 print(value)
59 print('Checking output of aktualizr-info:')
60 ran_ok = False
61 for delay in [1, 2, 5, 10, 15]:
62 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
63 if retcode == 0 and stderr == b'':
64 ran_ok = True
65 break
66 sleep(delay)
67 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
68
69 verifyProvisioned(self, machine)
70
71# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater_native.py b/lib/oeqa/selftest/cases/updater_native.py
new file mode 100644
index 0000000..1fc9cb8
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_native.py
@@ -0,0 +1,47 @@
1# pylint: disable=C0111,C0325
2import logging
3
4from oeqa.selftest.case import OESelftestTestCase
5from oeqa.utils.commands import runCmd, bitbake, get_bb_var
6from testutils import akt_native_run
7
8
9class SotaToolsTests(OESelftestTestCase):
10
11 @classmethod
12 def setUpClass(cls):
13 super(SotaToolsTests, cls).setUpClass()
14 logger = logging.getLogger("selftest")
15 logger.info('Running bitbake to build aktualizr-native tools')
16 bitbake('aktualizr-native')
17
18 def test_push_help(self):
19 akt_native_run(self, 'garage-push --help')
20
21 def test_deploy_help(self):
22 akt_native_run(self, 'garage-deploy --help')
23
24 def test_garagesign_help(self):
25 akt_native_run(self, 'garage-sign --help')
26
27
28class GeneralTests(OESelftestTestCase):
29
30 def test_feature_sota(self):
31 result = get_bb_var('DISTRO_FEATURES').find('sota')
32 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
33
34 def test_feature_usrmerge(self):
35 result = get_bb_var('DISTRO_FEATURES').find('usrmerge')
36 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
37
38 def test_feature_systemd(self):
39 result = get_bb_var('DISTRO_FEATURES').find('systemd')
40 self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES')
41
42 def test_java(self):
43 result = runCmd('which java', ignore_status=True)
44 self.assertEqual(result.status, 0,
45 "Java not found. Do you have a JDK installed on your host machine?")
46
47# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater_qemux86_64.py
index 473b2a8..9310841 100644
--- a/lib/oeqa/selftest/cases/updater.py
+++ b/lib/oeqa/selftest/cases/updater_qemux86_64.py
@@ -2,48 +2,16 @@
2import os 2import os
3import logging 3import logging
4import re 4import re
5import subprocess
6import unittest 5import unittest
7from time import sleep 6from time import sleep
8 7
9from oeqa.selftest.case import OESelftestTestCase 8from oeqa.selftest.case import OESelftestTestCase
10from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars 9from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
11from qemucommand import QemuCommand 10from testutils import qemu_launch, qemu_send_command, qemu_terminate, \
12 11 akt_native_run, verifyProvisioned
13
14class SotaToolsTests(OESelftestTestCase):
15
16 @classmethod
17 def setUpClass(cls):
18 super(SotaToolsTests, cls).setUpClass()
19 logger = logging.getLogger("selftest")
20 logger.info('Running bitbake to build aktualizr-native tools')
21 bitbake('aktualizr-native')
22
23 def test_push_help(self):
24 akt_native_run(self, 'garage-push --help')
25
26 def test_deploy_help(self):
27 akt_native_run(self, 'garage-deploy --help')
28
29 def test_garagesign_help(self):
30 akt_native_run(self, 'garage-sign --help')
31 12
32 13
33class GeneralTests(OESelftestTestCase): 14class GeneralTests(OESelftestTestCase):
34
35 def test_feature_sota(self):
36 result = get_bb_var('DISTRO_FEATURES').find('sota')
37 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
38
39 def test_feature_usrmerge(self):
40 result = get_bb_var('DISTRO_FEATURES').find('usrmerge')
41 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
42
43 def test_feature_systemd(self):
44 result = get_bb_var('DISTRO_FEATURES').find('systemd')
45 self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES')
46
47 def test_credentials(self): 15 def test_credentials(self):
48 logger = logging.getLogger("selftest") 16 logger = logging.getLogger("selftest")
49 logger.info('Running bitbake to build core-image-minimal') 17 logger.info('Running bitbake to build core-image-minimal')
@@ -62,11 +30,6 @@ class GeneralTests(OESelftestTestCase):
62 (deploydir, imagename), ignore_status=True) 30 (deploydir, imagename), ignore_status=True)
63 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) 31 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
64 32
65 def test_java(self):
66 result = runCmd('which java', ignore_status=True)
67 self.assertEqual(result.status, 0,
68 "Java not found. Do you have a JDK installed on your host machine?")
69
70 33
71class AktualizrToolsTests(OESelftestTestCase): 34class AktualizrToolsTests(OESelftestTestCase):
72 35
@@ -201,136 +164,6 @@ class ManualControlTests(OESelftestTestCase):
201 'Aktualizr should have run' + stderr.decode() + stdout.decode()) 164 'Aktualizr should have run' + stderr.decode() + stdout.decode())
202 165
203 166
204class RpiTests(OESelftestTestCase):
205
206 def setUpLocal(self):
207 # Add layers before changing the machine type, otherwise the sanity
208 # checker complains loudly.
209 layer_rpi = "meta-raspberrypi"
210 layer_upd_rpi = "meta-updater-raspberrypi"
211 result = runCmd('bitbake-layers show-layers')
212 # Assume the directory layout for finding other layers. We could also
213 # make assumptions by using 'show-layers', but either way, if the
214 # layers we need aren't where we expect them, we are out of luck.
215 path = os.path.abspath(os.path.dirname(__file__))
216 metadir = path + "/../../../../../"
217 if re.search(layer_rpi, result.output) is None:
218 self.meta_rpi = metadir + layer_rpi
219 runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi)
220 else:
221 self.meta_rpi = None
222 if re.search(layer_upd_rpi, result.output) is None:
223 self.meta_upd_rpi = metadir + layer_upd_rpi
224 runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi)
225 else:
226 self.meta_upd_rpi = None
227
228 # This is trickier that I would've thought. The fundamental problem is
229 # that the qemu layer changes the u-boot file extension to .rom, but
230 # raspberrypi still expects .bin. To prevent this, the qemu layer must
231 # be temporarily removed if it is present. It has to be removed by name
232 # without the complete path, but to add it back when we are done, we
233 # need the full path.
234 p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s')
235 m = p.search(result.output)
236 if m and m.lastindex > 0:
237 self.meta_qemu = m.group(1)
238 runCmd('bitbake-layers remove-layer meta-updater-qemux86-64')
239 else:
240 self.meta_qemu = None
241
242 self.append_config('MACHINE = "raspberrypi3"')
243 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
244
245 def tearDownLocal(self):
246 if self.meta_qemu:
247 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True)
248 if self.meta_upd_rpi:
249 runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True)
250 if self.meta_rpi:
251 runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True)
252
253 def test_rpi(self):
254 logger = logging.getLogger("selftest")
255 logger.info('Running bitbake to build core-image-minimal')
256 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"')
257 bitbake('core-image-minimal')
258 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
259 # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set.
260 if credentials is None:
261 raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.")
262 # Check if the file exists.
263 self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials)
264 deploydir = get_bb_var('DEPLOY_DIR_IMAGE')
265 imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal')
266 # Check if the credentials are included in the output image.
267 result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' %
268 (deploydir, imagename), ignore_status=True)
269 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
270
271
272class GrubTests(OESelftestTestCase):
273
274 def setUpLocal(self):
275 layer_intel = "meta-intel"
276 layer_minnow = "meta-updater-minnowboard"
277 result = runCmd('bitbake-layers show-layers')
278 # Assume the directory layout for finding other layers. We could also
279 # make assumptions by using 'show-layers', but either way, if the
280 # layers we need aren't where we expect them, we are out of luck.
281 path = os.path.abspath(os.path.dirname(__file__))
282 metadir = path + "/../../../../../"
283 if re.search(layer_intel, result.output) is None:
284 self.meta_intel = metadir + layer_intel
285 runCmd('bitbake-layers add-layer "%s"' % self.meta_intel)
286 else:
287 self.meta_intel = None
288 if re.search(layer_minnow, result.output) is None:
289 self.meta_minnow = metadir + layer_minnow
290 runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow)
291 else:
292 self.meta_minnow = None
293 self.append_config('MACHINE = "intel-corei7-64"')
294 self.append_config('OSTREE_BOOTLOADER = "grub"')
295 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
296 self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64')
297
298 def tearDownLocal(self):
299 qemu_terminate(self.s)
300 if self.meta_intel:
301 runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True)
302 if self.meta_minnow:
303 runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True)
304
305 def qemu_command(self, command):
306 return qemu_send_command(self.qemu.ssh_port, command)
307
308 def test_grub(self):
309 print('Checking machine name (hostname) of device:')
310 stdout, stderr, retcode = self.qemu_command('hostname')
311 self.assertEqual(retcode, 0, "Unable to check hostname. " +
312 "Is an ssh daemon (such as dropbear or openssh) installed on the device?")
313 machine = get_bb_var('MACHINE', 'core-image-minimal')
314 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
315 # Strip off line ending.
316 value = stdout.decode()[:-1]
317 self.assertEqual(value, machine,
318 'MACHINE does not match hostname: ' + machine + ', ' + value +
319 '\nIs TianoCore ovmf installed on your host machine?')
320 print(value)
321 print('Checking output of aktualizr-info:')
322 ran_ok = False
323 for delay in [1, 2, 5, 10, 15]:
324 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
325 if retcode == 0 and stderr == b'':
326 ran_ok = True
327 break
328 sleep(delay)
329 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
330
331 verifyProvisioned(self, machine)
332
333
334class ImplProvTests(OESelftestTestCase): 167class ImplProvTests(OESelftestTestCase):
335 168
336 def setUpLocal(self): 169 def setUpLocal(self):
@@ -474,7 +307,7 @@ class HsmTests(OESelftestTestCase):
474 softhsm2_command = 'softhsm2-util --show-slots' 307 softhsm2_command = 'softhsm2-util --show-slots'
475 stdout, stderr, retcode = self.qemu_command(softhsm2_command) 308 stdout, stderr, retcode = self.qemu_command(softhsm2_command)
476 self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' + 309 self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' +
477 stdout.decode() + stderr.decode()) 310 stdout.decode() + stderr.decode())
478 311
479 # Run aktualizr-cert-provider. 312 # Run aktualizr-cert-provider.
480 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 313 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
@@ -605,100 +438,4 @@ class PrimaryTests(OESelftestTestCase):
605 self.assertEqual(retcode, 0, "Unable to run aktualizr --help") 438 self.assertEqual(retcode, 0, "Unable to run aktualizr --help")
606 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) 439 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
607 440
608
609def qemu_launch(efi=False, machine=None, imagename=None):
610 logger = logging.getLogger("selftest")
611 logger.info('Running bitbake to build core-image-minimal')
612 bitbake('core-image-minimal')
613 # Create empty object.
614 args = type('', (), {})()
615 if imagename:
616 args.imagename = imagename
617 else:
618 args.imagename = 'core-image-minimal'
619 args.mac = None
620 # Could use DEPLOY_DIR_IMAGE here but it's already in the machine
621 # subdirectory.
622 args.dir = 'tmp/deploy/images'
623 args.efi = efi
624 args.machine = machine
625 qemu_use_kvm = get_bb_var("QEMU_USE_KVM")
626 if qemu_use_kvm and \
627 (qemu_use_kvm == 'True' and 'x86' in machine or \
628 get_bb_var('MACHINE') in qemu_use_kvm.split()):
629 args.kvm = True
630 else:
631 args.kvm = None # Autodetect
632 args.no_gui = True
633 args.gdb = False
634 args.pcap = None
635 args.overlay = None
636 args.dry_run = False
637 args.secondary_network = False
638
639 qemu = QemuCommand(args)
640 cmdline = qemu.command_line()
641 print('Booting image with run-qemu-ota...')
642 s = subprocess.Popen(cmdline)
643 sleep(10)
644 return qemu, s
645
646
647def qemu_terminate(s):
648 try:
649 s.terminate()
650 except KeyboardInterrupt:
651 pass
652
653
654def qemu_send_command(port, command):
655 command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' +
656 str(port) + ' "' + command + '"']
657 s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
658 stdout, stderr = s2.communicate(timeout=60)
659 return stdout, stderr, s2.returncode
660
661
662def akt_native_run(testInst, cmd, **kwargs):
663 # run a command supplied by aktualizr-native and checks that:
664 # - the executable exists
665 # - the command runs without error
666 # NOTE: the base test class must have built aktualizr-native (in
667 # setUpClass, for example)
668 bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'],
669 'aktualizr-native')
670 sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix']
671 sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir']
672 libdir = bb_vars['libdir']
673
674 program, *_ = cmd.split(' ')
675 p = '{}/{}'.format(sysrootbin, program)
676 testInst.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p))
677 env = dict(os.environ)
678 env['LD_LIBRARY_PATH'] = libdir
679 result = runCmd(cmd, env=env, native_sysroot=sysroot, ignore_status=True, **kwargs)
680 testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
681
682
683def verifyProvisioned(testInst, machine):
684 # Verify that device HAS provisioned.
685 ran_ok = False
686 for delay in [5, 5, 5, 5, 10, 10, 10, 10]:
687 stdout, stderr, retcode = testInst.qemu_command('aktualizr-info')
688 if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0:
689 ran_ok = True
690 break
691 sleep(delay)
692 testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
693 testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout,
694 'Provisioning failed: ' + stderr.decode() + stdout.decode())
695 testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
696 p = re.compile(r'Device ID: ([a-z0-9-]*)\n')
697 m = p.search(stdout.decode())
698 testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
699 testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
700 logger = logging.getLogger("selftest")
701 logger.info('Device successfully provisioned with ID: ' + m.group(1))
702
703
704# vim:set ts=4 sw=4 sts=4 expandtab: 441# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater_raspberrypi.py b/lib/oeqa/selftest/cases/updater_raspberrypi.py
new file mode 100644
index 0000000..bb7cfa3
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_raspberrypi.py
@@ -0,0 +1,78 @@
1# pylint: disable=C0111,C0325
2import os
3import logging
4import re
5import unittest
6
7from oeqa.selftest.case import OESelftestTestCase
8from oeqa.utils.commands import runCmd, bitbake, get_bb_var
9
10
11class RpiTests(OESelftestTestCase):
12
13 def setUpLocal(self):
14 # Add layers before changing the machine type, otherwise the sanity
15 # checker complains loudly.
16 layer_rpi = "meta-raspberrypi"
17 layer_upd_rpi = "meta-updater-raspberrypi"
18 result = runCmd('bitbake-layers show-layers')
19 # Assume the directory layout for finding other layers. We could also
20 # make assumptions by using 'show-layers', but either way, if the
21 # layers we need aren't where we expect them, we are out of luck.
22 path = os.path.abspath(os.path.dirname(__file__))
23 metadir = path + "/../../../../../"
24 if re.search(layer_rpi, result.output) is None:
25 self.meta_rpi = metadir + layer_rpi
26 runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi)
27 else:
28 self.meta_rpi = None
29 if re.search(layer_upd_rpi, result.output) is None:
30 self.meta_upd_rpi = metadir + layer_upd_rpi
31 runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi)
32 else:
33 self.meta_upd_rpi = None
34
35 # This is trickier that I would've thought. The fundamental problem is
36 # that the qemu layer changes the u-boot file extension to .rom, but
37 # raspberrypi still expects .bin. To prevent this, the qemu layer must
38 # be temporarily removed if it is present. It has to be removed by name
39 # without the complete path, but to add it back when we are done, we
40 # need the full path.
41 p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s')
42 m = p.search(result.output)
43 if m and m.lastindex > 0:
44 self.meta_qemu = m.group(1)
45 runCmd('bitbake-layers remove-layer meta-updater-qemux86-64')
46 else:
47 self.meta_qemu = None
48
49 self.append_config('MACHINE = "raspberrypi3"')
50 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
51
52 def tearDownLocal(self):
53 if self.meta_qemu:
54 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True)
55 if self.meta_upd_rpi:
56 runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True)
57 if self.meta_rpi:
58 runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True)
59
60 def test_build(self):
61 logger = logging.getLogger("selftest")
62 logger.info('Running bitbake to build core-image-minimal')
63 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"')
64 bitbake('core-image-minimal')
65 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
66 # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set.
67 if credentials is None:
68 raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.")
69 # Check if the file exists.
70 self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials)
71 deploydir = get_bb_var('DEPLOY_DIR_IMAGE')
72 imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal')
73 # Check if the credentials are included in the output image.
74 result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' %
75 (deploydir, imagename), ignore_status=True)
76 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
77
78# vim:set ts=4 sw=4 sts=4 expandtab: