summaryrefslogtreecommitdiffstats
path: root/lib/oeqa/selftest/cases/updater_qemux86_64.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/oeqa/selftest/cases/updater_qemux86_64.py')
-rw-r--r--lib/oeqa/selftest/cases/updater_qemux86_64.py189
1 files changed, 127 insertions, 62 deletions
diff --git a/lib/oeqa/selftest/cases/updater_qemux86_64.py b/lib/oeqa/selftest/cases/updater_qemux86_64.py
index 9f32bcf..e26a022 100644
--- a/lib/oeqa/selftest/cases/updater_qemux86_64.py
+++ b/lib/oeqa/selftest/cases/updater_qemux86_64.py
@@ -4,18 +4,19 @@ import logging
4import re 4import re
5import unittest 5import unittest
6from time import sleep 6from time import sleep
7from uuid import uuid4
7 8
8from oeqa.selftest.case import OESelftestTestCase 9from oeqa.selftest.case import OESelftestTestCase
9from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars 10from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
10from testutils import qemu_launch, qemu_send_command, qemu_terminate, \ 11from testutils import qemu_launch, qemu_send_command, qemu_terminate, \
11 akt_native_run, verifyNotProvisioned, verifyProvisioned 12 akt_native_run, verifyNotProvisioned, verifyProvisioned, qemu_bake_image, qemu_boot_image
12 13
13 14
14class GeneralTests(OESelftestTestCase): 15class GeneralTests(OESelftestTestCase):
15 def test_credentials(self): 16 def test_credentials(self):
16 logger = logging.getLogger("selftest") 17 logger = logging.getLogger("selftest")
17 logger.info('Running bitbake to build core-image-minimal') 18 logger.info('Running bitbake to build core-image-minimal')
18 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"') 19 self.append_config('SOTA_CLIENT_PROV = "aktualizr-shared-prov"')
19 bitbake('core-image-minimal') 20 bitbake('core-image-minimal')
20 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') 21 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
21 # skip the test if the variable SOTA_PACKED_CREDENTIALS is not set 22 # skip the test if the variable SOTA_PACKED_CREDENTIALS is not set
@@ -45,13 +46,13 @@ class AktualizrToolsTests(OESelftestTestCase):
45 46
46 def test_cert_provider_local_output(self): 47 def test_cert_provider_local_output(self):
47 logger = logging.getLogger("selftest") 48 logger = logging.getLogger("selftest")
48 logger.info('Running bitbake to build aktualizr-ca-implicit-prov') 49 logger.info('Running bitbake to build aktualizr-device-prov')
49 bitbake('aktualizr-ca-implicit-prov') 50 bitbake('aktualizr-device-prov')
50 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native') 51 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native')
51 creds = bb_vars['SOTA_PACKED_CREDENTIALS'] 52 creds = bb_vars['SOTA_PACKED_CREDENTIALS']
52 temp_dir = bb_vars['T'] 53 temp_dir = bb_vars['T']
53 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-ca-implicit-prov') 54 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-device-prov')
54 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov_ca.toml' 55 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota-device-cred.toml'
55 56
56 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -r -l {temp} -g {config}' 57 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -r -l {temp} -g {config}'
57 .format(creds=creds, temp=temp_dir, config=config)) 58 .format(creds=creds, temp=temp_dir, config=config))
@@ -68,7 +69,7 @@ class AktualizrToolsTests(OESelftestTestCase):
68 self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path) 69 self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path)
69 70
70 71
71class AutoProvTests(OESelftestTestCase): 72class SharedCredProvTests(OESelftestTestCase):
72 73
73 def setUpLocal(self): 74 def setUpLocal(self):
74 layer = "meta-updater-qemux86-64" 75 layer = "meta-updater-qemux86-64"
@@ -84,7 +85,7 @@ class AutoProvTests(OESelftestTestCase):
84 else: 85 else:
85 self.meta_qemu = None 86 self.meta_qemu = None
86 self.append_config('MACHINE = "qemux86-64"') 87 self.append_config('MACHINE = "qemux86-64"')
87 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 88 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
88 self.qemu, self.s = qemu_launch(machine='qemux86-64') 89 self.qemu, self.s = qemu_launch(machine='qemux86-64')
89 90
90 def tearDownLocal(self): 91 def tearDownLocal(self):
@@ -126,7 +127,7 @@ class ManualControlTests(OESelftestTestCase):
126 else: 127 else:
127 self.meta_qemu = None 128 self.meta_qemu = None
128 self.append_config('MACHINE = "qemux86-64"') 129 self.append_config('MACHINE = "qemux86-64"')
129 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 130 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
130 self.append_config('SYSTEMD_AUTO_ENABLE_aktualizr = "disable"') 131 self.append_config('SYSTEMD_AUTO_ENABLE_aktualizr = "disable"')
131 self.qemu, self.s = qemu_launch(machine='qemux86-64') 132 self.qemu, self.s = qemu_launch(machine='qemux86-64')
132 133
@@ -154,7 +155,7 @@ class ManualControlTests(OESelftestTestCase):
154 'Aktualizr should have run' + stderr.decode() + stdout.decode()) 155 'Aktualizr should have run' + stderr.decode() + stdout.decode())
155 156
156 157
157class ImplProvTests(OESelftestTestCase): 158class DeviceCredProvTests(OESelftestTestCase):
158 159
159 def setUpLocal(self): 160 def setUpLocal(self):
160 layer = "meta-updater-qemux86-64" 161 layer = "meta-updater-qemux86-64"
@@ -170,9 +171,9 @@ class ImplProvTests(OESelftestTestCase):
170 else: 171 else:
171 self.meta_qemu = None 172 self.meta_qemu = None
172 self.append_config('MACHINE = "qemux86-64"') 173 self.append_config('MACHINE = "qemux86-64"')
173 self.append_config('SOTA_CLIENT_PROV = " aktualizr-ca-implicit-prov "') 174 self.append_config('SOTA_CLIENT_PROV = " aktualizr-device-prov "')
174 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"') 175 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"')
175 runCmd('bitbake -c cleanall aktualizr aktualizr-ca-implicit-prov') 176 runCmd('bitbake -c cleanall aktualizr aktualizr-device-prov')
176 self.qemu, self.s = qemu_launch(machine='qemux86-64') 177 self.qemu, self.s = qemu_launch(machine='qemux86-64')
177 178
178 def tearDownLocal(self): 179 def tearDownLocal(self):
@@ -200,8 +201,8 @@ class ImplProvTests(OESelftestTestCase):
200 # Run aktualizr-cert-provider. 201 # Run aktualizr-cert-provider.
201 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 202 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
202 creds = bb_vars['SOTA_PACKED_CREDENTIALS'] 203 creds = bb_vars['SOTA_PACKED_CREDENTIALS']
203 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-ca-implicit-prov') 204 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-device-prov')
204 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov_ca.toml' 205 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota-device-cred.toml'
205 206
206 print('Provisining at root@localhost:%d' % self.qemu.ssh_port) 207 print('Provisining at root@localhost:%d' % self.qemu.ssh_port)
207 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -s -u -r -g {config}' 208 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -s -u -r -g {config}'
@@ -210,7 +211,7 @@ class ImplProvTests(OESelftestTestCase):
210 verifyProvisioned(self, machine) 211 verifyProvisioned(self, machine)
211 212
212 213
213class HsmTests(OESelftestTestCase): 214class DeviceCredProvHsmTests(OESelftestTestCase):
214 215
215 def setUpLocal(self): 216 def setUpLocal(self):
216 layer = "meta-updater-qemux86-64" 217 layer = "meta-updater-qemux86-64"
@@ -226,11 +227,11 @@ class HsmTests(OESelftestTestCase):
226 else: 227 else:
227 self.meta_qemu = None 228 self.meta_qemu = None
228 self.append_config('MACHINE = "qemux86-64"') 229 self.append_config('MACHINE = "qemux86-64"')
229 self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') 230 self.append_config('SOTA_CLIENT_PROV = "aktualizr-device-prov-hsm"')
230 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"') 231 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"')
231 self.append_config('SOTA_CLIENT_FEATURES = "hsm"') 232 self.append_config('SOTA_CLIENT_FEATURES = "hsm"')
232 self.append_config('IMAGE_INSTALL_append = " softhsm-testtoken"') 233 self.append_config('IMAGE_INSTALL_append = " softhsm-testtoken"')
233 runCmd('bitbake -c cleanall aktualizr aktualizr-hsm-prov') 234 runCmd('bitbake -c cleanall aktualizr aktualizr-device-prov-hsm')
234 self.qemu, self.s = qemu_launch(machine='qemux86-64') 235 self.qemu, self.s = qemu_launch(machine='qemux86-64')
235 236
236 def tearDownLocal(self): 237 def tearDownLocal(self):
@@ -268,8 +269,8 @@ class HsmTests(OESelftestTestCase):
268 # Run aktualizr-cert-provider. 269 # Run aktualizr-cert-provider.
269 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 270 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
270 creds = bb_vars['SOTA_PACKED_CREDENTIALS'] 271 creds = bb_vars['SOTA_PACKED_CREDENTIALS']
271 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-hsm-prov') 272 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-device-prov-hsm')
272 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota_hsm_prov.toml' 273 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota-device-cred-hsm.toml'
273 274
274 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -r -s -u -g {config}' 275 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -r -s -u -g {config}'
275 .format(creds=creds, port=self.qemu.ssh_port, config=config)) 276 .format(creds=creds, port=self.qemu.ssh_port, config=config))
@@ -309,7 +310,91 @@ class HsmTests(OESelftestTestCase):
309 verifyProvisioned(self, machine) 310 verifyProvisioned(self, machine)
310 311
311 312
312class SecondaryTests(OESelftestTestCase): 313class IpSecondaryTests(OESelftestTestCase):
314
315 class Image:
316 def __init__(self, imagename, binaryname, machine='qemux86-64', bake=True, **kwargs):
317 self.machine = machine
318 self.imagename = imagename
319 self.boot_kwargs = kwargs
320 self.binaryname = binaryname
321 self.stdout = ''
322 self.stderr = ''
323 self.retcode = 0
324 if bake:
325 self.bake()
326
327 def bake(self):
328 self.configure()
329 qemu_bake_image(self.imagename)
330
331 def send_command(self, cmd):
332 stdout, stderr, retcode = qemu_send_command(self.qemu.ssh_port, cmd, timeout=60)
333 return str(stdout), str(stderr), retcode
334
335 def __enter__(self):
336 self.qemu, self.process = qemu_boot_image(machine=self.machine, imagename=self.imagename,
337 wait_for_boot_time=1, **self.boot_kwargs)
338 # wait until the VM is booted and is SSHable
339 self.wait_till_sshable()
340
341 def __exit__(self, exc_type, exc_val, exc_tb):
342 qemu_terminate(self.process)
343
344 def wait_till_sshable(self):
345 # qemu_send_command tries to ssh into the qemu VM and blocks until it gets there or timeout happens
346 # so it helps us to block q control flow until the VM is booted and a target binary/daemon is running there
347 self.stdout, self.stderr, self.retcode = self.send_command(self.binaryname + ' --help')
348
349 def was_successfully_booted(self):
350 return self.retcode == 0
351
352 class Secondary(Image):
353 def __init__(self, test_ctx):
354 self._test_ctx = test_ctx
355 self.sndry_serial = str(uuid4())
356 self.sndry_hw_id = 'qemux86-64-oeselftest-sndry'
357 self.id = (self.sndry_hw_id, self.sndry_serial)
358 super(IpSecondaryTests.Secondary, self).__init__('secondary-image', 'aktualizr-secondary',
359 secondary_network=True)
360
361 def configure(self):
362 self._test_ctx.append_config('SECONDARY_SERIAL_ID = "{}"'.format(self.sndry_serial))
363 self._test_ctx.append_config('SECONDARY_HARDWARE_ID = "{}"'.format(self.sndry_hw_id))
364
365 class Primary(Image):
366 def __init__(self, test_ctx):
367 self._test_ctx = test_ctx
368 super(IpSecondaryTests.Primary, self).__init__('primary-image', 'aktualizr', secondary_network=True)
369
370 def configure(self):
371 self._test_ctx.append_config('MACHINE = "qemux86-64"')
372 self._test_ctx.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
373
374 def is_ecu_registered(self, ecu_id):
375 max_number_of_tries = 20
376 try_counter = 0
377
378 # aktualizr-info is not always able to load ECU serials from DB
379 # so, let's run it a few times until it actually succeeds
380 while try_counter < max_number_of_tries:
381 device_status = self.get_info()
382 try_counter += 1
383 if device_status.find("load ECU serials") == -1:
384 break
385 sleep(1)
386
387 if not ((device_status.find(ecu_id[0]) != -1) and (device_status.find(ecu_id[1]) != -1)):
388 return False
389 not_registered_field = "Removed or not registered ecus:"
390 not_reg_start = device_status.find(not_registered_field)
391 return not_reg_start == -1 or (device_status.find(ecu_id[1], not_reg_start) == -1)
392
393 def get_info(self):
394 stdout, stderr, retcode = self.send_command('aktualizr-info')
395 self._test_ctx.assertEqual(retcode, 0, 'Unable to run aktualizr-info: {}'.format(stderr))
396 return stdout
397
313 def setUpLocal(self): 398 def setUpLocal(self):
314 layer = "meta-updater-qemux86-64" 399 layer = "meta-updater-qemux86-64"
315 result = runCmd('bitbake-layers show-layers') 400 result = runCmd('bitbake-layers show-layers')
@@ -323,57 +408,37 @@ class SecondaryTests(OESelftestTestCase):
323 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) 408 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu)
324 else: 409 else:
325 self.meta_qemu = None 410 self.meta_qemu = None
326 self.append_config('MACHINE = "qemux86-64"') 411
327 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 412 self.primary = IpSecondaryTests.Primary(self)
328 self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='secondary-image') 413 self.secondary = IpSecondaryTests.Secondary(self)
329 414
330 def tearDownLocal(self): 415 def tearDownLocal(self):
331 qemu_terminate(self.s)
332 if self.meta_qemu: 416 if self.meta_qemu:
333 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) 417 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
334 418
335 def qemu_command(self, command): 419 def test_ip_secondary_registration_if_secondary_starts_first(self):
336 return qemu_send_command(self.qemu.ssh_port, command) 420 with self.secondary:
421 self.assertTrue(self.secondary.was_successfully_booted(),
422 'The secondary failed to boot: {}'.format(self.secondary.stderr))
337 423
338 def test_secondary_present(self): 424 with self.primary:
339 print('Checking aktualizr-secondary is present') 425 self.assertTrue(self.primary.was_successfully_booted(),
340 stdout, stderr, retcode = self.qemu_command('aktualizr-secondary --help') 426 'The primary failed to boot: {}'.format(self.primary.stderr))
341 self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help")
342 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
343 427
428 self.assertTrue(self.primary.is_ecu_registered(self.secondary.id),
429 "The secondary wasn't registered at the primary: {}".format(self.primary.get_info()))
344 430
345class PrimaryTests(OESelftestTestCase): 431 def test_ip_secondary_registration_if_primary_starts_first(self):
346 def setUpLocal(self): 432 with self.primary:
347 layer = "meta-updater-qemux86-64" 433 self.assertTrue(self.primary.was_successfully_booted(),
348 result = runCmd('bitbake-layers show-layers') 434 'The primary failed to boot: {}'.format(self.primary.stderr))
349 if re.search(layer, result.output) is None:
350 # Assume the directory layout for finding other layers. We could also
351 # make assumptions by using 'show-layers', but either way, if the
352 # layers we need aren't where we expect them, we are out of luck.
353 path = os.path.abspath(os.path.dirname(__file__))
354 metadir = path + "/../../../../../"
355 self.meta_qemu = metadir + layer
356 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu)
357 else:
358 self.meta_qemu = None
359 self.append_config('MACHINE = "qemux86-64"')
360 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
361 self.append_config('SOTA_CLIENT_FEATURES = "secondary-network"')
362 self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='primary-image')
363
364 def tearDownLocal(self):
365 qemu_terminate(self.s)
366 if self.meta_qemu:
367 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
368 435
369 def qemu_command(self, command): 436 with self.secondary:
370 return qemu_send_command(self.qemu.ssh_port, command) 437 self.assertTrue(self.secondary.was_successfully_booted(),
438 'The secondary failed to boot: {}'.format(self.secondary.stderr))
371 439
372 def test_aktualizr_present(self): 440 self.assertTrue(self.primary.is_ecu_registered(self.secondary.id),
373 print('Checking aktualizr is present') 441 "The secondary wasn't registered at the primary: {}".format(self.primary.get_info()))
374 stdout, stderr, retcode = self.qemu_command('aktualizr --help')
375 self.assertEqual(retcode, 0, "Unable to run aktualizr --help")
376 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
377 442
378 443
379class ResourceControlTests(OESelftestTestCase): 444class ResourceControlTests(OESelftestTestCase):
@@ -391,7 +456,7 @@ class ResourceControlTests(OESelftestTestCase):
391 else: 456 else:
392 self.meta_qemu = None 457 self.meta_qemu = None
393 self.append_config('MACHINE = "qemux86-64"') 458 self.append_config('MACHINE = "qemux86-64"')
394 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 459 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
395 self.append_config('IMAGE_INSTALL_append += " aktualizr-resource-control "') 460 self.append_config('IMAGE_INSTALL_append += " aktualizr-resource-control "')
396 self.append_config('RESOURCE_CPU_WEIGHT_pn-aktualizr = "1000"') 461 self.append_config('RESOURCE_CPU_WEIGHT_pn-aktualizr = "1000"')
397 self.append_config('RESOURCE_MEMORY_HIGH_pn-aktualizr = "50M"') 462 self.append_config('RESOURCE_MEMORY_HIGH_pn-aktualizr = "50M"')