From c2e9fcc8744b6c1f1af5941fd7d4546273361a91 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Fri, 19 Jan 2018 14:12:22 +0100 Subject: Add a helpful hint for the oe-selftest grub problem. Partial cherry-pick of b605cf215ff4cef35c3f62fee0ec14e3c8d5ba22 from rocko. --- lib/oeqa/selftest/updater.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index f28349f..b435d1b 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -161,7 +161,8 @@ class GrubTests(oeSelfTest): # Strip off line ending. value_str = value.decode()[:-1] self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str) + 'MACHINE does not match hostname: ' + machine + ', ' + value_str + + '\nIs tianocore ovmf installed?') print(value_str) -- cgit v1.2.3-54-g00ecf From 3a4bdbcae17b1b2f2197c61a0d188336767e1c60 Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Fri, 1 Dec 2017 11:56:51 +0100 Subject: Add tests for aktualizr-info. Cherry-pick of c64b399633975bc05856e5eded519c4f22adfe44 from rocko. --- lib/oeqa/selftest/updater.py | 56 +++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index b435d1b..0962cb7 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -1,8 +1,9 @@ -import unittest +# pylint: disable=C0111,C0325 import os import logging import subprocess -import time +import unittest +from time import sleep from oeqa.selftest.base import oeSelfTest from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars @@ -49,11 +50,11 @@ class GeneralTests(oeSelfTest): def test_feature_sota(self): result = get_bb_var('DISTRO_FEATURES').find('sota') - self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES'); + self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES') def test_feature_systemd(self): result = get_bb_var('DISTRO_FEATURES').find('systemd') - self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES'); + self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES') def test_credentials(self): bitbake('core-image-minimal') @@ -66,7 +67,8 @@ class GeneralTests(oeSelfTest): deploydir = get_bb_var('DEPLOY_DIR_IMAGE') imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal') # Check if the credentials are included in the output image - result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' % (deploydir, imagename), ignore_status=True) + result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' % + (deploydir, imagename), ignore_status=True) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) def test_java(self): @@ -99,7 +101,7 @@ class GeneralTests(oeSelfTest): self.assertEqual(result.output, 'ERROR: Unable to find any package producing path /usr/bin/man') path2 = os.path.realpath(image_path) size2 = os.path.getsize(path2) - logger.info('Second image %s has size %i' % (path2, size2)) + logger.info('Second image %s has size %i', path2, size2) self.assertNotEqual(path1, path2, "Image paths are identical; image was not rebuilt.") self.assertNotEqual(size1, size2, "Image sizes are identical; image was not rebuilt.") @@ -114,14 +116,17 @@ class QemuTests(oeSelfTest): def tearDownClass(cls): qemu_terminate(cls.s) + def run_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + def test_hostname(self): print('') print('Checking machine name (hostname) of device:') - value, err = qemu_send_command(self.qemu.ssh_port, 'hostname') + stdout, stderr, retcode = self.run_command('hostname') machine = get_bb_var('MACHINE', 'core-image-minimal') - self.assertEqual(err, b'', 'Error: ' + err.decode()) + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = value.decode()[:-1] + value_str = stdout.decode()[:-1] self.assertEqual(value_str, machine, 'MACHINE does not match hostname: ' + machine + ', ' + value_str) print(value_str) @@ -129,9 +134,26 @@ class QemuTests(oeSelfTest): def test_var_sota(self): print('') print('Checking contents of /var/sota:') - value, err = qemu_send_command(self.qemu.ssh_port, 'ls /var/sota') - self.assertEqual(err, b'', 'Error: ' + err.decode()) - print(value.decode()) + stdout, stderr, retcode = self.run_command('ls /var/sota') + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) + self.assertEqual(retcode, 0) + print(stdout.decode()) + + def test_aktualizr_info(self): + print('Checking output of aktualizr-info:') + ran_ok = False + for delay in [0, 1, 2, 5, 10, 15]: + sleep(delay) + try: + stdout, stderr, retcode = self.run_command('aktualizr-info') + if retcode == 0 and stderr == b'': + ran_ok = True + break + except IOError as e: + print(e) + if not ran_ok: + print(stdout.decode()) + print(stderr.decode()) class GrubTests(oeSelfTest): @@ -155,9 +177,10 @@ class GrubTests(oeSelfTest): def test_grub(self): print('') print('Checking machine name (hostname) of device:') - value, err = qemu_send_command(self.qemu.ssh_port, 'hostname') + value, err, retcode = qemu_send_command(self.qemu.ssh_port, 'hostname') machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(err, b'', 'Error: ' + err.decode()) + self.assertEqual(retcode, 0) # Strip off line ending. value_str = value.decode()[:-1] self.assertEqual(value_str, machine, @@ -190,7 +213,7 @@ def qemu_launch(efi=False, machine=None): cmdline = qemu.command_line() print('Booting image with run-qemu-ota...') s = subprocess.Popen(cmdline) - time.sleep(10) + sleep(10) return qemu, s def qemu_terminate(s): @@ -203,6 +226,7 @@ def qemu_send_command(port, command): command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + str(port) + ' "' + command + '"'] s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - value, err = s2.communicate() - return value, err + stdout, stderr = s2.communicate() + return stdout, stderr, s2.returncode +# vim:set ts=4 sw=4 sts=4 expandtab: -- cgit v1.2.3-54-g00ecf From 9a404b4e60c3a9166d98491fed778c64a67150bc Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Tue, 13 Feb 2018 17:23:08 +0100 Subject: Only expect credentials in the image if using autoprov. The credentials test was failing if any other provisioning recipe was specified. --- lib/oeqa/selftest/updater.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 0962cb7..7e8a615 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -57,6 +57,7 @@ class GeneralTests(oeSelfTest): self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES') def test_credentials(self): + self.write_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') bitbake('core-image-minimal') credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') # skip the test if the variable SOTA_PACKED_CREDENTIALS is not set -- cgit v1.2.3-54-g00ecf From 7bcbb8046672ff66ca7aa0bdf48460d1a11000c3 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Wed, 14 Feb 2018 17:08:52 +0100 Subject: Test that implicit_writer and cert_provider work. This required setting the LD_LIBRARY_PATH to get some dependencies that are liable to conflict with the host's normal installation. I adapted that for the sota_tools tests as well for good measure. Also, we now actually install cert_provider in the native build. --- lib/oeqa/selftest/updater.py | 42 +++++++++++++++++++++++---------- recipes-sota/aktualizr/aktualizr_git.bb | 3 ++- 2 files changed, 32 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 7e8a615..9a3efee 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -19,24 +19,27 @@ class SotaToolsTests(oeSelfTest): bitbake('aktualizr-native') def test_push_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'aktualizr-native') - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "garage-push" + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/garage-push" self.assertTrue(os.path.isfile(p), msg = "No garage-push found (%s)" % p) - result = runCmd('%s --help' % p, ignore_status=True) + result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) def test_deploy_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'aktualizr-native') - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "garage-deploy" + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/garage-deploy" self.assertTrue(os.path.isfile(p), msg = "No garage-deploy found (%s)" % p) - result = runCmd('%s --help' % p, ignore_status=True) + result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) def test_garagesign_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'aktualizr-native') - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "garage-sign" + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/garage-sign" self.assertTrue(os.path.isfile(p), msg = "No garage-sign found (%s)" % p) - result = runCmd('%s --help' % p, ignore_status=True) + result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) class HsmTests(oeSelfTest): @@ -76,6 +79,22 @@ class GeneralTests(oeSelfTest): result = runCmd('which java', ignore_status=True) self.assertEqual(result.status, 0, "Java not found.") + def test_implicit_writer_help(self): + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_implicit_writer" + self.assertTrue(os.path.isfile(p), msg = "No aktualizr_implicit_writer found (%s)" % p) + result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + def test_cert_provider_help(self): + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" + self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) + result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + def test_add_package(self): print('') deploydir = get_bb_var('DEPLOY_DIR_IMAGE') @@ -152,9 +171,8 @@ class QemuTests(oeSelfTest): break except IOError as e: print(e) - if not ran_ok: - print(stdout.decode()) - print(stderr.decode()) + self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stdout.decode() + stderr.decode()) + class GrubTests(oeSelfTest): diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index 0194dbb..bcc1438 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -37,10 +37,10 @@ EXTRA_OECMAKE_append_class-target = " -DBUILD_OSTREE=ON -DBUILD_ISOTP=ON ${@bb.u EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF " do_install_append () { - rm -f ${D}${bindir}/aktualizr_cert_provider rm -fr ${D}${libdir}/systemd } do_install_append_class-target () { + rm -f ${D}${bindir}/aktualizr_cert_provider rm -f ${D}${bindir}/aktualizr_implicit_writer rm -f ${D}${libdir}/sota/sota.toml ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', '', 'rm -f ${D}${bindir}/example-interface', d)} @@ -76,6 +76,7 @@ FILES_${PN}_class-target = " \ FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', ' ${bindir}/example-interface', '', d)} " FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-isotp-example', ' ${bindir}/isotp-test-interface', '', d)} " FILES_${PN}_class-native = " \ + ${bindir}/aktualizr_cert_provider \ ${bindir}/aktualizr_implicit_writer \ ${bindir}/garage-deploy \ ${bindir}/garage-push \ -- cgit v1.2.3-54-g00ecf From 9e4918cff53c6154b5bcee2e28deca08280aff75 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Thu, 15 Feb 2018 12:05:55 +0100 Subject: Add test_cert_provider_local_output. Improve some organization and logging. --- lib/oeqa/selftest/updater.py | 71 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 9a3efee..83febb1 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -60,6 +60,8 @@ class GeneralTests(oeSelfTest): self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES') def test_credentials(self): + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build core-image-minimal') self.write_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') bitbake('core-image-minimal') credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') @@ -79,22 +81,6 @@ class GeneralTests(oeSelfTest): result = runCmd('which java', ignore_status=True) self.assertEqual(result.status, 0, "Java not found.") - def test_implicit_writer_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_implicit_writer" - self.assertTrue(os.path.isfile(p), msg = "No aktualizr_implicit_writer found (%s)" % p) - result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) - - def test_cert_provider_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" - self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) - result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) - def test_add_package(self): print('') deploydir = get_bb_var('DEPLOY_DIR_IMAGE') @@ -126,6 +112,59 @@ class GeneralTests(oeSelfTest): self.assertNotEqual(size1, size2, "Image sizes are identical; image was not rebuilt.") +class AktualizrToolsTests(oeSelfTest): + + @classmethod + def setUpClass(cls): + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build aktualizr-native tools') + bitbake('aktualizr-native') + + def test_implicit_writer_help(self): + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_implicit_writer" + self.assertTrue(os.path.isfile(p), msg = "No aktualizr_implicit_writer found (%s)" % p) + result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + def test_cert_provider_help(self): + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" + self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) + result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + def test_cert_provider_local_output(self): + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build aktualizr-implicit-prov') + bitbake('aktualizr-implicit-prov') + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', + 'SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" + creds = bb_vars['SOTA_PACKED_CREDENTIALS'] + temp_dir = bb_vars['T'] + bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-implicit-prov') + config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' + self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) + command = 'LD_LIBRARY_PATH=' + l + ' ' + p + ' -c ' + creds + ' -r -l ' + temp_dir + ' -g ' + config + # logger.info('Checking output of: ' + command) + result = runCmd(command, ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + # Might be nice if these names weren't hardcoded. + cert_path = temp_dir + '/client.pem' + self.assertTrue(os.path.isfile(cert_path), "Client certificate not found at %s." % cert_path) + self.assertTrue(os.path.getsize(cert_path) > 0, "Client certificate at %s is empty." % cert_path) + pkey_path = temp_dir + '/pkey.pem' + self.assertTrue(os.path.isfile(pkey_path), "Private key not found at %s." % pkey_path) + self.assertTrue(os.path.getsize(pkey_path) > 0, "Private key at %s is empty." % pkey_path) + ca_path = temp_dir + '/root.crt' + self.assertTrue(os.path.isfile(ca_path), "Client certificate not found at %s." % ca_path) + self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path) + + class QemuTests(oeSelfTest): @classmethod -- cgit v1.2.3-54-g00ecf From 586394dc9f7b5e97c827ea982dd69692f3ca0c97 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Tue, 13 Feb 2018 18:08:39 +0100 Subject: Test provisioning with HSM. --- lib/oeqa/selftest/updater.py | 95 ++++++++++++++++++++++++++++++--- recipes-sota/aktualizr/aktualizr_git.bb | 2 +- 2 files changed, 89 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 83febb1..8ee8378 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -42,12 +42,6 @@ class SotaToolsTests(oeSelfTest): result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) -class HsmTests(oeSelfTest): - - def test_hsm(self): - self.write_config('SOTA_CLIENT_FEATURES="hsm"') - bitbake('core-image-minimal') - class GeneralTests(oeSelfTest): @@ -210,7 +204,7 @@ class QemuTests(oeSelfTest): break except IOError as e: print(e) - self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stdout.decode() + stderr.decode()) + self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) class GrubTests(oeSelfTest): @@ -247,6 +241,93 @@ class GrubTests(oeSelfTest): print(value_str) +class HsmTests(oeSelfTest): + + def setUpLocal(self): + self.write_config('SOTA_CLIENT_PROV = " aktualizr-hsm-prov "') + self.write_config('SOTA_CLIENT_FEATURES="hsm"') + self.qemu, self.s = qemu_launch(machine='qemux86-64') + + def tearDownLocal(self): + qemu_terminate(self.s) + + def run_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + + def test_provisioning(self): + print('') + ran_ok = False + for delay in [0, 1, 2, 5, 10, 15]: + stdout, stderr, retcode = self.run_command('aktualizr-info') + if retcode == 0 and stderr == b'': + ran_ok = True + break + self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) + # Verify that device has NOT yet provisioned. + self.assertIn(b'Couldn\'t load device ID', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Couldn\'t load ECU serials', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Provisioned on server: no', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Fetched metadata: no', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + + pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O' + stdout, stderr, retcode = self.run_command(pkcs11_command) + self.assertNotEqual(retcode, 0, 'pkcs11-tool succeeded before initialization: ' + + stdout.decode() + stderr.decode()) + softhsm2_command = 'softhsm2-util --show-slots' + stdout, stderr, retcode = self.run_command(softhsm2_command) + self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' + + stdout.decode() + stderr.decode()) + + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', + 'SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') + l = bb_vars['libdir'] + p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" + creds = bb_vars['SOTA_PACKED_CREDENTIALS'] + bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-hsm-prov') + config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' + self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) + command = ('LD_LIBRARY_PATH=' + l + ' ' + p + ' -c ' + creds + ' -t root@localhost -p ' + + str(self.qemu.ssh_port) + ' -r -s -g ' + config) + logger = logging.getLogger("selftest") + # logger.info('Checking output of: ' + command) + result = runCmd(command, ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + ran_ok = False + for delay in [5, 5, 5, 5, 10]: + sleep(delay) + p11_out, p11_err, p11_ret = self.run_command(pkcs11_command) + hsm_out, hsm_err, hsm_ret = self.run_command(softhsm2_command) + if p11_ret == 0 and hsm_ret == 0 and hsm_err == b'': + ran_ok = True + break + self.assertTrue(ran_ok, 'pkcs11-tool or softhsm2-tool failed: ' + p11_err.decode() + + p11_out.decode() + hsm_err.decode() + hsm_out.decode()) + self.assertIn(b'present token', p11_err, 'pkcs11-tool failed: ' + p11_err.decode() + p11_out.decode()) + self.assertIn(b'X.509 cert', p11_out, 'pkcs11-tool failed: ' + p11_err.decode() + p11_out.decode()) + self.assertIn(b'Initialized: yes', hsm_out, 'softhsm2-tool failed: ' + + hsm_err.decode() + hsm_out.decode()) + self.assertIn(b'User PIN init.: yes', hsm_out, 'softhsm2-tool failed: ' + + hsm_err.decode() + hsm_out.decode()) + + # Verify that device HAS provisioned. + ran_ok = False + for delay in [5, 5, 5, 5, 10]: + sleep(delay) + stdout, stderr, retcode = self.run_command('aktualizr-info') + if retcode == 0 and stderr == b'' and stdout.decode().find('Provisioned on server: yes') >= 0: + ran_ok = True + break + self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, + 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + + def qemu_launch(efi=False, machine=None): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index bcc1438..ab9a8dc 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -20,7 +20,7 @@ SRC_URI = " \ file://aktualizr.service \ file://aktualizr-serialcan.service \ " -SRCREV = "715dfc3410d46670174ee2f55613e8d953fbb1ae" +SRCREV = "abd0db4e503cbe647fbe3a6e70d28456c2ad7ea4" BRANCH ?= "master" S = "${WORKDIR}/git" -- cgit v1.2.3-54-g00ecf From 1f5d44911e608d809ac1e6987542c8909dfc464f Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Thu, 15 Feb 2018 17:20:35 +0100 Subject: Use some regex to get a little fancier. --- lib/oeqa/selftest/updater.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 8ee8378..690dae5 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -1,6 +1,7 @@ # pylint: disable=C0111,C0325 import os import logging +import re import subprocess import unittest from time import sleep @@ -273,6 +274,7 @@ class HsmTests(oeSelfTest): self.assertIn(b'Fetched metadata: no', stdout, 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + # Verify that HSM is not yet initialized. pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O' stdout, stderr, retcode = self.run_command(pkcs11_command) self.assertNotEqual(retcode, 0, 'pkcs11-tool succeeded before initialization: ' + @@ -282,6 +284,7 @@ class HsmTests(oeSelfTest): self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' + stdout.decode() + stderr.decode()) + # Run cert_provider. bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', 'SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') l = bb_vars['libdir'] @@ -297,6 +300,7 @@ class HsmTests(oeSelfTest): result = runCmd(command, ignore_status=True) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + # Verify that HSM is able to initialize. ran_ok = False for delay in [5, 5, 5, 5, 10]: sleep(delay) @@ -314,6 +318,20 @@ class HsmTests(oeSelfTest): self.assertIn(b'User PIN init.: yes', hsm_out, 'softhsm2-tool failed: ' + hsm_err.decode() + hsm_out.decode()) + # Check that pkcs11 output matches sofhsm output. + p11_p = re.compile(r'Using slot [0-9] with a present token \((0x[0-9a-f]*)\)\s') + p11_m = p11_p.search(p11_err.decode()) + self.assertTrue(p11_m, 'Slot number not found with pkcs11-tool: ' + p11_err.decode() + p11_out.decode()) + self.assertGreater(p11_m.lastindex, 0, 'Slot number not found with pkcs11-tool: ' + + p11_err.decode() + p11_out.decode()) + hsm_p = re.compile(r'Description:\s*SoftHSM slot ID (0x[0-9a-f]*)\s') + hsm_m = hsm_p.search(hsm_out.decode()) + self.assertTrue(hsm_m, 'Slot number not found with softhsm2-tool: ' + hsm_err.decode() + hsm_out.decode()) + self.assertGreater(hsm_m.lastindex, 0, 'Slot number not found with softhsm2-tool: ' + + hsm_err.decode() + hsm_out.decode()) + self.assertEqual(p11_m.group(1), hsm_m.group(1), 'Slot number does not match: ' + + p11_err.decode() + p11_out.decode() + hsm_err.decode() + hsm_out.decode()) + # Verify that device HAS provisioned. ran_ok = False for delay in [5, 5, 5, 5, 10]: @@ -326,6 +344,11 @@ class HsmTests(oeSelfTest): self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + p = re.compile(r'Device ID: ([a-z0-9-]*)\n') + m = p.search(stdout.decode()) + self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + logger.info('Device successfully provisioned with ID: ' + m.group(1)) def qemu_launch(efi=False, machine=None): -- cgit v1.2.3-54-g00ecf From c6690b907a0a4525848dfed6cde2d89d8554b5f1 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Mon, 19 Feb 2018 14:10:16 +0100 Subject: Rename run_command to qemu_command. This helps distinguish it from runCmd, which is how you run commands in the shell. --- lib/oeqa/selftest/updater.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 690dae5..c8ec711 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -170,13 +170,13 @@ class QemuTests(oeSelfTest): def tearDownClass(cls): qemu_terminate(cls.s) - def run_command(self, command): + def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) def test_hostname(self): print('') print('Checking machine name (hostname) of device:') - stdout, stderr, retcode = self.run_command('hostname') + stdout, stderr, retcode = self.qemu_command('hostname') machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. @@ -188,7 +188,7 @@ class QemuTests(oeSelfTest): def test_var_sota(self): print('') print('Checking contents of /var/sota:') - stdout, stderr, retcode = self.run_command('ls /var/sota') + stdout, stderr, retcode = self.qemu_command('ls /var/sota') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) self.assertEqual(retcode, 0) print(stdout.decode()) @@ -199,7 +199,7 @@ class QemuTests(oeSelfTest): for delay in [0, 1, 2, 5, 10, 15]: sleep(delay) try: - stdout, stderr, retcode = self.run_command('aktualizr-info') + stdout, stderr, retcode = self.qemu_command('aktualizr-info') if retcode == 0 and stderr == b'': ran_ok = True break @@ -252,14 +252,14 @@ class HsmTests(oeSelfTest): def tearDownLocal(self): qemu_terminate(self.s) - def run_command(self, command): + def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) def test_provisioning(self): print('') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: - stdout, stderr, retcode = self.run_command('aktualizr-info') + stdout, stderr, retcode = self.qemu_command('aktualizr-info') if retcode == 0 and stderr == b'': ran_ok = True break @@ -276,11 +276,11 @@ class HsmTests(oeSelfTest): # Verify that HSM is not yet initialized. pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O' - stdout, stderr, retcode = self.run_command(pkcs11_command) + stdout, stderr, retcode = self.qemu_command(pkcs11_command) self.assertNotEqual(retcode, 0, 'pkcs11-tool succeeded before initialization: ' + stdout.decode() + stderr.decode()) softhsm2_command = 'softhsm2-util --show-slots' - stdout, stderr, retcode = self.run_command(softhsm2_command) + stdout, stderr, retcode = self.qemu_command(softhsm2_command) self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' + stdout.decode() + stderr.decode()) @@ -304,8 +304,8 @@ class HsmTests(oeSelfTest): ran_ok = False for delay in [5, 5, 5, 5, 10]: sleep(delay) - p11_out, p11_err, p11_ret = self.run_command(pkcs11_command) - hsm_out, hsm_err, hsm_ret = self.run_command(softhsm2_command) + p11_out, p11_err, p11_ret = self.qemu_command(pkcs11_command) + hsm_out, hsm_err, hsm_ret = self.qemu_command(softhsm2_command) if p11_ret == 0 and hsm_ret == 0 and hsm_err == b'': ran_ok = True break @@ -336,7 +336,7 @@ class HsmTests(oeSelfTest): ran_ok = False for delay in [5, 5, 5, 5, 10]: sleep(delay) - stdout, stderr, retcode = self.run_command('aktualizr-info') + stdout, stderr, retcode = self.qemu_command('aktualizr-info') if retcode == 0 and stderr == b'' and stdout.decode().find('Provisioned on server: yes') >= 0: ran_ok = True break -- cgit v1.2.3-54-g00ecf From 5c141641e143883e06b815371dd69551dbf3d52a Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Mon, 19 Feb 2018 16:52:12 +0100 Subject: oe-selftest standardization and general improvement. --- lib/oeqa/selftest/updater.py | 72 ++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 30 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index c8ec711..0ef3e16 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -173,10 +173,11 @@ class QemuTests(oeSelfTest): def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) - def test_hostname(self): - print('') + def test_qemu(self): print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') + self.assertEqual(retcode, 0, "Unable to check hostname. " + + "Is an ssh daemon (such as dropbear or openssh) installed on the device?") machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. @@ -184,27 +185,14 @@ class QemuTests(oeSelfTest): self.assertEqual(value_str, machine, 'MACHINE does not match hostname: ' + machine + ', ' + value_str) print(value_str) - - def test_var_sota(self): - print('') - print('Checking contents of /var/sota:') - stdout, stderr, retcode = self.qemu_command('ls /var/sota') - self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) - self.assertEqual(retcode, 0) - print(stdout.decode()) - - def test_aktualizr_info(self): print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: sleep(delay) - try: - stdout, stderr, retcode = self.qemu_command('aktualizr-info') - if retcode == 0 and stderr == b'': - ran_ok = True - break - except IOError as e: - print(e) + stdout, stderr, retcode = self.qemu_command('aktualizr-info') + if retcode == 0 and stderr == b'': + ran_ok = True + break self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) @@ -227,26 +215,39 @@ class GrubTests(oeSelfTest): runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) + def qemu_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + def test_grub(self): print('') print('Checking machine name (hostname) of device:') - value, err, retcode = qemu_send_command(self.qemu.ssh_port, 'hostname') + stdout, stderr, retcode = self.qemu_command('hostname') + self.assertEqual(retcode, 0, "Unable to check hostname. " + + "Is an ssh daemon (such as dropbear or openssh) installed on the device?") machine = get_bb_var('MACHINE', 'core-image-minimal') - self.assertEqual(err, b'', 'Error: ' + err.decode()) - self.assertEqual(retcode, 0) + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = value.decode()[:-1] - self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str + - '\nIs tianocore ovmf installed?') - print(value_str) + value = stdout.decode()[:-1] + self.assertEqual(value, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value + + '\nIs TianoCore ovmf installed?') + print(value) + print('Checking output of aktualizr-info:') + ran_ok = False + for delay in [0, 1, 2, 5, 10, 15]: + sleep(delay) + stdout, stderr, retcode = self.qemu_command('aktualizr-info') + if retcode == 0 and stderr == b'': + ran_ok = True + break + self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) class HsmTests(oeSelfTest): def setUpLocal(self): - self.write_config('SOTA_CLIENT_PROV = " aktualizr-hsm-prov "') - self.write_config('SOTA_CLIENT_FEATURES="hsm"') + self.write_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') + self.write_config('SOTA_CLIENT_FEATURES = "hsm"') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): @@ -256,7 +257,18 @@ class HsmTests(oeSelfTest): return qemu_send_command(self.qemu.ssh_port, command) def test_provisioning(self): - print('') + print('Checking machine name (hostname) of device:') + stdout, stderr, retcode = self.qemu_command('hostname') + self.assertEqual(retcode, 0, "Unable to check hostname. " + + "Is an ssh daemon (such as dropbear or openssh) installed on the device?") + machine = get_bb_var('MACHINE', 'core-image-minimal') + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) + # Strip off line ending. + value_str = stdout.decode()[:-1] + self.assertEqual(value_str, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value_str) + print(value_str) + print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: stdout, stderr, retcode = self.qemu_command('aktualizr-info') -- cgit v1.2.3-54-g00ecf From e77c7c7b6121ed9ad207d7fd1603a32e59540f00 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Tue, 20 Feb 2018 11:56:55 +0100 Subject: Replace write_config with append_config. Also fix a minor provisioning check ordering problem. --- lib/oeqa/selftest/updater.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 0ef3e16..703df91 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -57,7 +57,7 @@ class GeneralTests(oeSelfTest): def test_credentials(self): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') - self.write_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"') bitbake('core-image-minimal') credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') # skip the test if the variable SOTA_PACKED_CREDENTIALS is not set @@ -74,7 +74,8 @@ class GeneralTests(oeSelfTest): def test_java(self): result = runCmd('which java', ignore_status=True) - self.assertEqual(result.status, 0, "Java not found.") + self.assertEqual(result.status, 0, + "Java not found. Do you have a JDK installed on your host machine?") def test_add_package(self): print('') @@ -84,7 +85,7 @@ class GeneralTests(oeSelfTest): logger = logging.getLogger("selftest") logger.info('Running bitbake with man in the image package list') - self.write_config('IMAGE_INSTALL_append = " man "') + self.append_config('IMAGE_INSTALL_append = " man "') bitbake('-c cleanall man') bitbake('core-image-minimal') result = runCmd('oe-pkgdata-util find-path /usr/bin/man') @@ -94,7 +95,7 @@ class GeneralTests(oeSelfTest): logger.info('First image %s has size %i' % (path1, size1)) logger.info('Running bitbake without man in the image package list') - self.write_config('IMAGE_INSTALL_remove = " man "') + self.append_config('IMAGE_INSTALL_remove = " man "') bitbake('-c cleanall man') bitbake('core-image-minimal') result = runCmd('oe-pkgdata-util find-path /usr/bin/man', ignore_status=True) @@ -230,7 +231,7 @@ class GrubTests(oeSelfTest): value = stdout.decode()[:-1] self.assertEqual(value, machine, 'MACHINE does not match hostname: ' + machine + ', ' + value + - '\nIs TianoCore ovmf installed?') + '\nIs TianoCore ovmf installed on your host machine?') print(value) print('Checking output of aktualizr-info:') ran_ok = False @@ -246,8 +247,8 @@ class GrubTests(oeSelfTest): class HsmTests(oeSelfTest): def setUpLocal(self): - self.write_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') - self.write_config('SOTA_CLIENT_FEATURES = "hsm"') + self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') + self.append_config('SOTA_CLIENT_FEATURES = "hsm"') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): @@ -349,7 +350,7 @@ class HsmTests(oeSelfTest): for delay in [5, 5, 5, 5, 10]: sleep(delay) stdout, stderr, retcode = self.qemu_command('aktualizr-info') - if retcode == 0 and stderr == b'' and stdout.decode().find('Provisioned on server: yes') >= 0: + if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: ran_ok = True break self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) -- cgit v1.2.3-54-g00ecf From fc84de73eb3f04f1e7600a1c86061af7f856e8d4 Mon Sep 17 00:00:00 2001 From: Laurent Bonnans Date: Tue, 20 Feb 2018 17:43:52 +0100 Subject: Refactor oe selftests Factorize the call of aktualizr-native commands in each testing class --- lib/oeqa/selftest/updater.py | 121 +++++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 51 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 703df91..8563e3b 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -16,32 +16,32 @@ class SotaToolsTests(oeSelfTest): @classmethod def setUpClass(cls): logger = logging.getLogger("selftest") + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], + 'aktualizr-native') + cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] + cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + cls.libdir = bb_vars['libdir'] + logger.info('Running bitbake to build aktualizr-native tools') bitbake('aktualizr-native') - def test_push_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/garage-push" - self.assertTrue(os.path.isfile(p), msg = "No garage-push found (%s)" % p) - result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) + def runNativeCmd(self, cmd, **kwargs): + program, *_ = cmd.split(' ') + p = '{}/{}'.format(self.sysrootbin, program) + self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) + env = dict(os.environ) + env['LD_LIBRARY_PATH'] = self.libdir + result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + def test_push_help(self): + self.runNativeCmd('garage-push --help') + def test_deploy_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/garage-deploy" - self.assertTrue(os.path.isfile(p), msg = "No garage-deploy found (%s)" % p) - result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + self.runNativeCmd('garage-deploy --help') def test_garagesign_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/garage-sign" - self.assertTrue(os.path.isfile(p), msg = "No garage-sign found (%s)" % p) - result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + self.runNativeCmd('garage-sign --help') class GeneralTests(oeSelfTest): @@ -113,24 +113,29 @@ class AktualizrToolsTests(oeSelfTest): @classmethod def setUpClass(cls): logger = logging.getLogger("selftest") + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], + 'aktualizr-native') + cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] + cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + cls.libdir = bb_vars['libdir'] + logger.info('Running bitbake to build aktualizr-native tools') bitbake('aktualizr-native') - def test_implicit_writer_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_implicit_writer" - self.assertTrue(os.path.isfile(p), msg = "No aktualizr_implicit_writer found (%s)" % p) - result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) + def runNativeCmd(self, cmd, **kwargs): + program, *_ = cmd.split(' ') + p = '{}/{}'.format(self.sysrootbin, program) + self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) + env = dict(os.environ) + env['LD_LIBRARY_PATH'] = self.libdir + result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + def test_implicit_writer_help(self): + self.runNativeCmd('aktualizr_implicit_writer --help') + def test_cert_provider_help(self): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" - self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) - result = runCmd('LD_LIBRARY_PATH=%s %s --help' % (l, p), ignore_status=True) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + self.runNativeCmd('aktualizr_cert_provider --help') def test_cert_provider_local_output(self): logger = logging.getLogger("selftest") @@ -138,17 +143,14 @@ class AktualizrToolsTests(oeSelfTest): bitbake('aktualizr-implicit-prov') bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', 'SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" creds = bb_vars['SOTA_PACKED_CREDENTIALS'] temp_dir = bb_vars['T'] bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-implicit-prov') config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' - self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) - command = 'LD_LIBRARY_PATH=' + l + ' ' + p + ' -c ' + creds + ' -r -l ' + temp_dir + ' -g ' + config - # logger.info('Checking output of: ' + command) - result = runCmd(command, ignore_status=True) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + self.runNativeCmd('aktualizr_cert_provider -c {creds} -r -l {temp} -g {config}' + .format(creds=creds, temp=temp_dir, config=config)) + # Might be nice if these names weren't hardcoded. cert_path = temp_dir + '/client.pem' self.assertTrue(os.path.isfile(cert_path), "Client certificate not found at %s." % cert_path) @@ -178,7 +180,7 @@ class QemuTests(oeSelfTest): print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') self.assertEqual(retcode, 0, "Unable to check hostname. " + - "Is an ssh daemon (such as dropbear or openssh) installed on the device?") + "Is an ssh daemon (such as dropbear or openssh) installed on the device?") machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. @@ -224,7 +226,7 @@ class GrubTests(oeSelfTest): print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') self.assertEqual(retcode, 0, "Unable to check hostname. " + - "Is an ssh daemon (such as dropbear or openssh) installed on the device?") + "Is an ssh daemon (such as dropbear or openssh) installed on the device?") machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. @@ -246,6 +248,18 @@ class GrubTests(oeSelfTest): class HsmTests(oeSelfTest): + @classmethod + def setUpClass(cls): + logger = logging.getLogger("selftest") + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], + 'aktualizr-native') + cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] + cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + cls.libdir = bb_vars['libdir'] + + logger.info('Running bitbake to build aktualizr-native tools') + bitbake('aktualizr-native') + def setUpLocal(self): self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') self.append_config('SOTA_CLIENT_FEATURES = "hsm"') @@ -254,6 +268,15 @@ class HsmTests(oeSelfTest): def tearDownLocal(self): qemu_terminate(self.s) + def runNativeCmd(self, cmd, **kwargs): + program, *_ = cmd.split(' ') + p = '{}/{}'.format(self.sysrootbin, program) + self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) + env = dict(os.environ) + env['LD_LIBRARY_PATH'] = self.libdir + result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -261,7 +284,7 @@ class HsmTests(oeSelfTest): print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') self.assertEqual(retcode, 0, "Unable to check hostname. " + - "Is an ssh daemon (such as dropbear or openssh) installed on the device?") + "Is an ssh daemon (such as dropbear or openssh) installed on the device?") machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. @@ -291,7 +314,7 @@ class HsmTests(oeSelfTest): pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O' stdout, stderr, retcode = self.qemu_command(pkcs11_command) self.assertNotEqual(retcode, 0, 'pkcs11-tool succeeded before initialization: ' + - stdout.decode() + stderr.decode()) + stdout.decode() + stderr.decode()) softhsm2_command = 'softhsm2-util --show-slots' stdout, stderr, retcode = self.qemu_command(softhsm2_command) self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' + @@ -300,18 +323,12 @@ class HsmTests(oeSelfTest): # Run cert_provider. bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', 'SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') - l = bb_vars['libdir'] - p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/aktualizr_cert_provider" creds = bb_vars['SOTA_PACKED_CREDENTIALS'] bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-hsm-prov') config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' - self.assertTrue(os.path.isfile(p), msg = "No aktualizr_cert_provider found (%s)" % p) - command = ('LD_LIBRARY_PATH=' + l + ' ' + p + ' -c ' + creds + ' -t root@localhost -p ' + - str(self.qemu.ssh_port) + ' -r -s -g ' + config) - logger = logging.getLogger("selftest") - # logger.info('Checking output of: ' + command) - result = runCmd(command, ignore_status=True) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + self.runNativeCmd('aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -r -s -g {config}' + .format(creds=creds, port=self.qemu.ssh_port, config=config)) # Verify that HSM is able to initialize. ran_ok = False @@ -361,7 +378,7 @@ class HsmTests(oeSelfTest): m = p.search(stdout.decode()) self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - logger.info('Device successfully provisioned with ID: ' + m.group(1)) + self.logger.info('Device successfully provisioned with ID: ' + m.group(1)) def qemu_launch(efi=False, machine=None): @@ -391,12 +408,14 @@ def qemu_launch(efi=False, machine=None): sleep(10) return qemu, s + def qemu_terminate(s): try: s.terminate() except KeyboardInterrupt: pass + def qemu_send_command(port, command): command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + str(port) + ' "' + command + '"'] -- cgit v1.2.3-54-g00ecf From 2023bfbbe31d5bb2df6da2af66ff828b2321b1e4 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Wed, 21 Feb 2018 08:56:38 +0100 Subject: Fix minor logging issue. No need for the extra bitbake of aktualizr-native. --- lib/oeqa/selftest/updater.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 8563e3b..1efbba9 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -250,16 +250,12 @@ class HsmTests(oeSelfTest): @classmethod def setUpClass(cls): - logger = logging.getLogger("selftest") bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], 'aktualizr-native') cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] cls.libdir = bb_vars['libdir'] - logger.info('Running bitbake to build aktualizr-native tools') - bitbake('aktualizr-native') - def setUpLocal(self): self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') self.append_config('SOTA_CLIENT_FEATURES = "hsm"') @@ -378,7 +374,8 @@ class HsmTests(oeSelfTest): m = p.search(stdout.decode()) self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - self.logger.info('Device successfully provisioned with ID: ' + m.group(1)) + logger = logging.getLogger("selftest") + logger.info('Device successfully provisioned with ID: ' + m.group(1)) def qemu_launch(efi=False, machine=None): -- cgit v1.2.3-54-g00ecf From 235826d067217aedf3e3e1819ee9c8f5ac0b60d3 Mon Sep 17 00:00:00 2001 From: Laurent Bonnans Date: Tue, 20 Feb 2018 12:12:43 +0100 Subject: Test implicit provisioning with oe-selftest --- lib/oeqa/selftest/updater.py | 89 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 1efbba9..cad5b2a 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -246,6 +246,95 @@ class GrubTests(oeSelfTest): self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) +class ImplProvTests(oeSelfTest): + + @classmethod + def setUpClass(cls): + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], + 'aktualizr-native') + cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] + cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + cls.libdir = bb_vars['libdir'] + + def setUpLocal(self): + self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') + self.qemu, self.s = qemu_launch(machine='qemux86-64') + + def tearDownLocal(self): + qemu_terminate(self.s) + + def runNativeCmd(self, cmd, **kwargs): + program, *_ = cmd.split(' ') + p = '{}/{}'.format(self.sysrootbin, program) + self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) + env = dict(os.environ) + env['LD_LIBRARY_PATH'] = self.libdir + result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + def qemu_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + + def test_provisioning(self): + print('Checking machine name (hostname) of device:') + stdout, stderr, retcode = self.qemu_command('hostname') + self.assertEqual(retcode, 0, "Unable to check hostname. " + + "Is an ssh daemon (such as dropbear or openssh) installed on the device?") + machine = get_bb_var('MACHINE', 'core-image-minimal') + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) + # Strip off line ending. + value_str = stdout.decode()[:-1] + self.assertEqual(value_str, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value_str) + print(value_str) + print('Checking output of aktualizr-info:') + ran_ok = False + for delay in [0, 1, 2, 5, 10, 15]: + stdout, stderr, retcode = self.qemu_command('aktualizr-info') + if retcode == 0 and stderr == b'': + ran_ok = True + break + self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) + # Verify that device has NOT yet provisioned. + self.assertIn(b'Couldn\'t load device ID', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Couldn\'t load ECU serials', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Provisioned on server: no', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Fetched metadata: no', stdout, + 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) + + # Run cert_provider. + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', + 'SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') + creds = bb_vars['SOTA_PACKED_CREDENTIALS'] + bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-implicit-prov') + config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' + + self.runNativeCmd('aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -s -g {config}' \ + .format(creds=creds, port=self.qemu.ssh_port, config=config)) + + # Verify that device HAS provisioned. + ran_ok = False + for delay in [5, 5, 5, 5, 10]: + sleep(delay) + stdout, stderr, retcode = self.qemu_command('aktualizr-info') + if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: + ran_ok = True + break + self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, + 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + p = re.compile(r'Device ID: ([a-z0-9-]*)\n') + m = p.search(stdout.decode()) + self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + logger = logging.getLogger("selftest") + logger.info('Device successfully provisioned with ID: ' + m.group(1)) + + class HsmTests(oeSelfTest): @classmethod -- cgit v1.2.3-54-g00ecf From 5c70505c127e58aa14c25599c6c7405e77e4c360 Mon Sep 17 00:00:00 2001 From: Laurent Bonnans Date: Wed, 21 Feb 2018 12:10:01 +0100 Subject: Factorize aktualizr native helper in oe-selftest --- lib/oeqa/selftest/updater.py | 118 ++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 75 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index cad5b2a..f237364 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -16,32 +16,17 @@ class SotaToolsTests(oeSelfTest): @classmethod def setUpClass(cls): logger = logging.getLogger("selftest") - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], - 'aktualizr-native') - cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] - cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] - cls.libdir = bb_vars['libdir'] - logger.info('Running bitbake to build aktualizr-native tools') bitbake('aktualizr-native') - def runNativeCmd(self, cmd, **kwargs): - program, *_ = cmd.split(' ') - p = '{}/{}'.format(self.sysrootbin, program) - self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) - env = dict(os.environ) - env['LD_LIBRARY_PATH'] = self.libdir - result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) - def test_push_help(self): - self.runNativeCmd('garage-push --help') + akt_native_run(self, 'garage-push --help') def test_deploy_help(self): - self.runNativeCmd('garage-deploy --help') + akt_native_run(self, 'garage-deploy --help') def test_garagesign_help(self): - self.runNativeCmd('garage-sign --help') + akt_native_run(self, 'garage-sign --help') class GeneralTests(oeSelfTest): @@ -113,43 +98,27 @@ class AktualizrToolsTests(oeSelfTest): @classmethod def setUpClass(cls): logger = logging.getLogger("selftest") - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], - 'aktualizr-native') - cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] - cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] - cls.libdir = bb_vars['libdir'] - logger.info('Running bitbake to build aktualizr-native tools') bitbake('aktualizr-native') - def runNativeCmd(self, cmd, **kwargs): - program, *_ = cmd.split(' ') - p = '{}/{}'.format(self.sysrootbin, program) - self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) - env = dict(os.environ) - env['LD_LIBRARY_PATH'] = self.libdir - result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) - def test_implicit_writer_help(self): - self.runNativeCmd('aktualizr_implicit_writer --help') + akt_native_run(self, 'aktualizr_implicit_writer --help') def test_cert_provider_help(self): - self.runNativeCmd('aktualizr_cert_provider --help') + akt_native_run(self, 'aktualizr_cert_provider --help') def test_cert_provider_local_output(self): logger = logging.getLogger("selftest") logger.info('Running bitbake to build aktualizr-implicit-prov') bitbake('aktualizr-implicit-prov') - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', - 'SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native') + bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native') creds = bb_vars['SOTA_PACKED_CREDENTIALS'] temp_dir = bb_vars['T'] bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-implicit-prov') config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' - self.runNativeCmd('aktualizr_cert_provider -c {creds} -r -l {temp} -g {config}' - .format(creds=creds, temp=temp_dir, config=config)) + akt_native_run(self, 'aktualizr_cert_provider -c {creds} -r -l {temp} -g {config}' + .format(creds=creds, temp=temp_dir, config=config)) # Might be nice if these names weren't hardcoded. cert_path = temp_dir + '/client.pem' @@ -250,11 +219,9 @@ class ImplProvTests(oeSelfTest): @classmethod def setUpClass(cls): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], - 'aktualizr-native') - cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] - cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] - cls.libdir = bb_vars['libdir'] + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build aktualizr-native tools') + bitbake('aktualizr-native') def setUpLocal(self): self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') @@ -263,15 +230,6 @@ class ImplProvTests(oeSelfTest): def tearDownLocal(self): qemu_terminate(self.s) - def runNativeCmd(self, cmd, **kwargs): - program, *_ = cmd.split(' ') - p = '{}/{}'.format(self.sysrootbin, program) - self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) - env = dict(os.environ) - env['LD_LIBRARY_PATH'] = self.libdir - result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) - def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -306,14 +264,13 @@ class ImplProvTests(oeSelfTest): 'Device already provisioned!? ' + stderr.decode() + stdout.decode()) # Run cert_provider. - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', - 'SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') + bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') creds = bb_vars['SOTA_PACKED_CREDENTIALS'] bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-implicit-prov') config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' - self.runNativeCmd('aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -s -g {config}' \ - .format(creds=creds, port=self.qemu.ssh_port, config=config)) + akt_native_run(self, 'aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -s -g {config}' + .format(creds=creds, port=self.qemu.ssh_port, config=config)) # Verify that device HAS provisioned. ran_ok = False @@ -339,11 +296,9 @@ class HsmTests(oeSelfTest): @classmethod def setUpClass(cls): - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], - 'aktualizr-native') - cls.sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] - cls.sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] - cls.libdir = bb_vars['libdir'] + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build aktualizr-native tools') + bitbake('aktualizr-native') def setUpLocal(self): self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') @@ -353,15 +308,6 @@ class HsmTests(oeSelfTest): def tearDownLocal(self): qemu_terminate(self.s) - def runNativeCmd(self, cmd, **kwargs): - program, *_ = cmd.split(' ') - p = '{}/{}'.format(self.sysrootbin, program) - self.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) - env = dict(os.environ) - env['LD_LIBRARY_PATH'] = self.libdir - result = runCmd(cmd, env=env, native_sysroot=self.sysroot, ignore_status=True, **kwargs) - self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) - def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -406,14 +352,13 @@ class HsmTests(oeSelfTest): stdout.decode() + stderr.decode()) # Run cert_provider. - bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir', 'libdir', - 'SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') + bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') creds = bb_vars['SOTA_PACKED_CREDENTIALS'] bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-hsm-prov') config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' - self.runNativeCmd('aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -r -s -g {config}' - .format(creds=creds, port=self.qemu.ssh_port, config=config)) + akt_native_run(self, 'aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -r -s -g {config}' + .format(creds=creds, port=self.qemu.ssh_port, config=config)) # Verify that HSM is able to initialize. ran_ok = False @@ -509,4 +454,27 @@ def qemu_send_command(port, command): stdout, stderr = s2.communicate() return stdout, stderr, s2.returncode + +def akt_native_run(testInst, cmd, **kwargs): + # run a command supplied by aktualizr-native and checks that: + # - the executable exists + # - the command runs without error + # NOTE: the base test class must have built aktualizr-native (in + # setUpClass, for example) + bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'], + 'aktualizr-native') + sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix'] + sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + libdir = bb_vars['libdir'] + + program, *_ = cmd.split(' ') + p = '{}/{}'.format(sysrootbin, program) + testInst.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p)) + env = dict(os.environ) + env['LD_LIBRARY_PATH'] = libdir + result = runCmd(cmd, env=env, native_sysroot=sysroot, ignore_status=True, **kwargs) + testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + + # vim:set ts=4 sw=4 sts=4 expandtab: -- cgit v1.2.3-54-g00ecf From 372b3f72ae6113a450f40288f884e3a5b97c6206 Mon Sep 17 00:00:00 2001 From: Laurent Bonnans Date: Wed, 21 Feb 2018 16:04:52 +0100 Subject: Less redundant bitbaking in oe-selftest --- lib/oeqa/selftest/updater.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index f237364..69d8eb7 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -217,14 +217,9 @@ class GrubTests(oeSelfTest): class ImplProvTests(oeSelfTest): - @classmethod - def setUpClass(cls): - logger = logging.getLogger("selftest") - logger.info('Running bitbake to build aktualizr-native tools') - bitbake('aktualizr-native') - def setUpLocal(self): self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') + # note: this will build aktualizr-native as a side-effect self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): @@ -294,15 +289,10 @@ class ImplProvTests(oeSelfTest): class HsmTests(oeSelfTest): - @classmethod - def setUpClass(cls): - logger = logging.getLogger("selftest") - logger.info('Running bitbake to build aktualizr-native tools') - bitbake('aktualizr-native') - def setUpLocal(self): self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') self.append_config('SOTA_CLIENT_FEATURES = "hsm"') + # note: this will build aktualizr-native as a side-effect self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): -- cgit v1.2.3-54-g00ecf From 0f55df2e10db67f33d5656c4569c8de40ca89fb5 Mon Sep 17 00:00:00 2001 From: Laurent Bonnans Date: Wed, 21 Feb 2018 17:24:35 +0100 Subject: Fix typo in oe-selftest --- lib/oeqa/selftest/updater.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index 69d8eb7..8fbc857 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py @@ -345,7 +345,7 @@ class HsmTests(oeSelfTest): bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') creds = bb_vars['SOTA_PACKED_CREDENTIALS'] bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-hsm-prov') - config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov.toml' + config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_hsm_prov.toml' akt_native_run(self, 'aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -r -s -g {config}' .format(creds=creds, port=self.qemu.ssh_port, config=config)) -- cgit v1.2.3-54-g00ecf From c0d6f4c7949ddfc01977096b985c46c28aa8ed4f Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Wed, 28 Feb 2018 10:27:01 +0100 Subject: oe-selftest improvements. * Check successful provisioning with autoprov and grub. * Refactor provisioning check into an independent function. * Rename QemuTests to AutoProvTests since that's what it is now. * Be more explicit about MACHINE. --- lib/oeqa/selftest/cases/updater.py | 111 +++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 60 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index b544762..fe18981 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -134,22 +134,20 @@ class AktualizrToolsTests(OESelftestTestCase): self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path) -class QemuTests(OESelftestTestCase): +class AutoProvTests(OESelftestTestCase): - @classmethod - def setUpClass(cls): - super(QemuTests, cls).setUpClass() - cls.qemu, cls.s = qemu_launch(machine='qemux86-64') + def setUpLocal(self): + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + self.qemu, self.s = qemu_launch(machine='qemux86-64') - @classmethod - def tearDownClass(cls): - qemu_terminate(cls.s) - super(QemuTests, cls).tearDownClass() + def tearDownLocal(self): + qemu_terminate(self.s) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) - def test_qemu(self): + def test_provisioning(self): print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') self.assertEqual(retcode, 0, "Unable to check hostname. " + @@ -157,10 +155,10 @@ class QemuTests(OESelftestTestCase): machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = stdout.decode()[:-1] - self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str) - print(value_str) + value = stdout.decode()[:-1] + self.assertEqual(value, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value) + print(value) print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: @@ -171,15 +169,18 @@ class QemuTests(OESelftestTestCase): break self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) + verifyProvisioned(self, machine) + class GrubTests(OESelftestTestCase): def setUpLocal(self): + self.append_config('MACHINE = "intel-corei7-64"') + self.append_config('OSTREE_BOOTLOADER = "grub"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') # This is a bit of a hack but I can't see a better option. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" - grub_config = 'OSTREE_BOOTLOADER = "grub"\nMACHINE = "intel-corei7-64"' - self.append_config(grub_config) self.meta_intel = metadir + "meta-intel" self.meta_minnow = metadir + "meta-updater-minnowboard" runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) @@ -218,10 +219,13 @@ class GrubTests(OESelftestTestCase): break self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) + verifyProvisioned(self, machine) + class ImplProvTests(OESelftestTestCase): def setUpLocal(self): + self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') # note: this will build aktualizr-native as a side-effect self.qemu, self.s = qemu_launch(machine='qemux86-64') @@ -240,10 +244,10 @@ class ImplProvTests(OESelftestTestCase): machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = stdout.decode()[:-1] - self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str) - print(value_str) + value = stdout.decode()[:-1] + self.assertEqual(value, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value) + print(value) print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: @@ -271,29 +275,13 @@ class ImplProvTests(OESelftestTestCase): akt_native_run(self, 'aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -s -g {config}' .format(creds=creds, port=self.qemu.ssh_port, config=config)) - # Verify that device HAS provisioned. - ran_ok = False - for delay in [5, 5, 5, 5, 10]: - sleep(delay) - stdout, stderr, retcode = self.qemu_command('aktualizr-info') - if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: - ran_ok = True - break - self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, - 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - p = re.compile(r'Device ID: ([a-z0-9-]*)\n') - m = p.search(stdout.decode()) - self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - logger = logging.getLogger("selftest") - logger.info('Device successfully provisioned with ID: ' + m.group(1)) + verifyProvisioned(self, machine) class HsmTests(OESelftestTestCase): def setUpLocal(self): + self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') self.append_config('SOTA_CLIENT_FEATURES = "hsm"') # note: this will build aktualizr-native as a side-effect @@ -313,11 +301,11 @@ class HsmTests(OESelftestTestCase): machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = stdout.decode()[:-1] - self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str + + value = stdout.decode()[:-1] + self.assertEqual(value, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value + '\nIs tianocore ovmf installed?') - print(value_str) + print(value) print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: @@ -387,24 +375,7 @@ class HsmTests(OESelftestTestCase): self.assertEqual(p11_m.group(1), hsm_m.group(1), 'Slot number does not match: ' + p11_err.decode() + p11_out.decode() + hsm_err.decode() + hsm_out.decode()) - # Verify that device HAS provisioned. - ran_ok = False - for delay in [5, 5, 5, 5, 10]: - sleep(delay) - stdout, stderr, retcode = self.qemu_command('aktualizr-info') - if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: - ran_ok = True - break - self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, - 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - p = re.compile(r'Device ID: ([a-z0-9-]*)\n') - m = p.search(stdout.decode()) - self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - logger = logging.getLogger("selftest") - logger.info('Device successfully provisioned with ID: ' + m.group(1)) + verifyProvisioned(self, machine) def qemu_launch(efi=False, machine=None): @@ -471,5 +442,25 @@ def akt_native_run(testInst, cmd, **kwargs): testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) +def verifyProvisioned(testInst, machine): + # Verify that device HAS provisioned. + ran_ok = False + for delay in [5, 5, 5, 5, 10]: + sleep(delay) + stdout, stderr, retcode = testInst.qemu_command('aktualizr-info') + if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: + ran_ok = True + break + testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout, + 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + p = re.compile(r'Device ID: ([a-z0-9-]*)\n') + m = p.search(stdout.decode()) + testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + logger = logging.getLogger("selftest") + logger.info('Device successfully provisioned with ID: ' + m.group(1)) + # vim:set ts=4 sw=4 sts=4 expandtab: -- cgit v1.2.3-54-g00ecf From 0fb122d88290a7476d694547f4d05a15d5ec38d1 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Wed, 28 Feb 2018 11:23:07 +0100 Subject: Add qemu layer for qemu tests if not present. The layers required for the grub test are now also only added if not already present. This should make the tests runnable from an environment configured for raspberry pi. --- lib/oeqa/selftest/cases/updater.py | 61 +++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index fe18981..a9c3206 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -139,10 +139,22 @@ class AutoProvTests(OESelftestTestCase): def setUpLocal(self): self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # This is a bit of a hack but I can't see a better option. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -178,19 +190,30 @@ class GrubTests(OESelftestTestCase): self.append_config('MACHINE = "intel-corei7-64"') self.append_config('OSTREE_BOOTLOADER = "grub"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + layer_intel = "meta-intel" + layer_minnow = "meta-updater-minnowboard" + result = runCmd('bitbake-layers show-layers') # This is a bit of a hack but I can't see a better option. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" - self.meta_intel = metadir + "meta-intel" - self.meta_minnow = metadir + "meta-updater-minnowboard" - runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) - runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) + if re.search(layer_intel, result.output) is None: + self.meta_intel = metadir + layer_intel + runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) + else: + self.meta_intel = None + if re.search(layer_minnow, result.output) is None: + self.meta_minnow = metadir + layer_minnow + runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) + else: + self.meta_minnow = None self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') def tearDownLocal(self): qemu_terminate(self.s) - runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) - runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) + if self.meta_intel: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) + if self.meta_minnow: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -227,11 +250,22 @@ class ImplProvTests(OESelftestTestCase): def setUpLocal(self): self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') - # note: this will build aktualizr-native as a side-effect + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # This is a bit of a hack but I can't see a better option. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -284,11 +318,22 @@ class HsmTests(OESelftestTestCase): self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') self.append_config('SOTA_CLIENT_FEATURES = "hsm"') - # note: this will build aktualizr-native as a side-effect + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # This is a bit of a hack but I can't see a better option. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) -- cgit v1.2.3-54-g00ecf From 81b2fa6bf0b5d7d68dc81c83ecc1ba15cba2ac9b Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Fri, 2 Mar 2018 09:39:39 +0100 Subject: Add a basic raspberry pi test. There's not much we can do, since booting the device via a test is not practical. Still, it's useful to make sure that we can build the image. If trying to build the image in an environment designed for qemu, this takes some trickery to set things up just right. Also consistently set up layers before setting the MACHINE, since the sanity checker sometimes complains otherwise. --- lib/oeqa/selftest/cases/updater.py | 114 +++++++++++++++++++++++++++++++------ 1 file changed, 98 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index a9c3206..adb4061 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -64,7 +64,6 @@ class GeneralTests(OESelftestTestCase): "Java not found. Do you have a JDK installed on your host machine?") def test_add_package(self): - print('') deploydir = get_bb_var('DEPLOY_DIR_IMAGE') imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal') image_path = deploydir + '/' + imagename + '.otaimg' @@ -137,18 +136,20 @@ class AktualizrToolsTests(OESelftestTestCase): class AutoProvTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "qemux86-64"') - self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') layer = "meta-updater-qemux86-64" result = runCmd('bitbake-layers show-layers') if re.search(layer, result.output) is None: - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" self.meta_qemu = metadir + layer runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) else: self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): @@ -184,16 +185,91 @@ class AutoProvTests(OESelftestTestCase): verifyProvisioned(self, machine) -class GrubTests(OESelftestTestCase): +class RpiTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "intel-corei7-64"') - self.append_config('OSTREE_BOOTLOADER = "grub"') + # Add layers before changing the machine type, otherwise the sanity + # checker complains loudly. + layer_python = "meta-openembedded/meta-python" + layer_rpi = "meta-raspberrypi" + layer_upd_rpi = "meta-updater-raspberrypi" + result = runCmd('bitbake-layers show-layers') + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + if re.search(layer_python, result.output) is None: + self.meta_python = metadir + layer_python + runCmd('bitbake-layers add-layer "%s"' % self.meta_python) + else: + self.meta_python = None + if re.search(layer_rpi, result.output) is None: + self.meta_rpi = metadir + layer_rpi + runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi) + else: + self.meta_rpi = None + if re.search(layer_upd_rpi, result.output) is None: + self.meta_upd_rpi = metadir + layer_upd_rpi + runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi) + else: + self.meta_upd_rpi = None + + # This is trickier that I would've thought. The fundamental problem is + # that the qemu layer changes the u-boot file extension to .rom, but + # raspberrypi still expects .bin. To prevent this, the qemu layer must + # be temporarily removed if it is present. It has to be removed by name + # without the complete path, but to add it back when we are done, we + # need the full path. + p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s') + m = p.search(result.output) + if m and m.lastindex > 0: + self.meta_qemu = m.group(1) + runCmd('bitbake-layers remove-layer meta-updater-qemux86-64') + else: + self.meta_qemu = None + + self.append_config('MACHINE = "raspberrypi3"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + + def tearDownLocal(self): + if self.meta_qemu: + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True) + if self.meta_upd_rpi: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True) + if self.meta_rpi: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True) + if self.meta_python: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_python, ignore_status=True) + + def test_rpi(self): + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build rpi-basic-image') + self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"') + bitbake('rpi-basic-image') + credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') + # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set. + if credentials is None: + raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.") + # Check if the file exists. + self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials) + deploydir = get_bb_var('DEPLOY_DIR_IMAGE') + imagename = get_bb_var('IMAGE_LINK_NAME', 'rpi-basic-image') + # Check if the credentials are included in the output image. + result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' % + (deploydir, imagename), ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + +class GrubTests(OESelftestTestCase): + + def setUpLocal(self): layer_intel = "meta-intel" layer_minnow = "meta-updater-minnowboard" result = runCmd('bitbake-layers show-layers') - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" if re.search(layer_intel, result.output) is None: @@ -206,6 +282,9 @@ class GrubTests(OESelftestTestCase): runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) else: self.meta_minnow = None + self.append_config('MACHINE = "intel-corei7-64"') + self.append_config('OSTREE_BOOTLOADER = "grub"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') def tearDownLocal(self): @@ -219,7 +298,6 @@ class GrubTests(OESelftestTestCase): return qemu_send_command(self.qemu.ssh_port, command) def test_grub(self): - print('') print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') self.assertEqual(retcode, 0, "Unable to check hostname. " + @@ -248,18 +326,20 @@ class GrubTests(OESelftestTestCase): class ImplProvTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "qemux86-64"') - self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') layer = "meta-updater-qemux86-64" result = runCmd('bitbake-layers show-layers') if re.search(layer, result.output) is None: - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" self.meta_qemu = metadir + layer runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) else: self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): @@ -315,19 +395,21 @@ class ImplProvTests(OESelftestTestCase): class HsmTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "qemux86-64"') - self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') - self.append_config('SOTA_CLIENT_FEATURES = "hsm"') layer = "meta-updater-qemux86-64" result = runCmd('bitbake-layers show-layers') if re.search(layer, result.output) is None: - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" self.meta_qemu = metadir + layer runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) else: self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') + self.append_config('SOTA_CLIENT_FEATURES = "hsm"') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): -- cgit v1.2.3-54-g00ecf From bbce1809a921e627678947e9585ea15223b181d9 Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Wed, 14 Mar 2018 11:44:26 +0100 Subject: Add secondary-image to meta-updater This required splitting the aktualizr package into several components, in order to be able to either install the primary 'aktualzr' or the secondary 'aktualizr-secondary'. --- README.adoc | 4 +-- lib/oeqa/selftest/cases/updater.py | 45 +++++++++++++++++++++++++++++++-- recipes-sota/aktualizr/aktualizr_git.bb | 42 +++++++++++++++++------------- recipes-test/images/secondary-image.bb | 18 +++++++++++++ 4 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 recipes-test/images/secondary-image.bb (limited to 'lib') diff --git a/README.adoc b/README.adoc index 3562f52..980fa81 100644 --- a/README.adoc +++ b/README.adoc @@ -80,8 +80,8 @@ Although we have used U-Boot so far, other boot loaders can be configured work w * `OSTREE_INITRAMFS_IMAGE` - initramfs/initrd image that is used as a proxy while booting into OSTree deployment. Do not change this setting unless you are sure that your initramfs can serve as such a proxy. * `SOTA_PACKED_CREDENTIALS` - when set, your ostree commit will be pushed to a remote repo as a bitbake step. This should be the path to a zipped credentials file in https://github.com/advancedtelematic/aktualizr/blob/master/docs/credentials.adoc[the format accepted by garage-push]. * `SOTA_CLIENT_PROV` - which provisioning method to use. Valid options are https://github.com/advancedtelematic/aktualizr/blob/master/docs/automatic-provisioning.adoc[`aktualizr-auto-prov`], https://github.com/advancedtelematic/aktualizr/blob/master/docs/implicit-provisioning.adoc[`aktualizr-implicit-prov`], and `aktualizr-hsm-prov`. The default is `aktualizr-auto-prov`. This can also be set to an empty string to avoid using a provisioning recipe. -* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. Multiple can be specified if separated by spaces. Valid options are `hsm` (to build with HSM support) and `secondary-example` (to install an example https://github.com/advancedtelematic/aktualizr/blob/master/docs/legacysecondary.adoc[legacy secondary interface] in the image). -* `SOTA_LEGACY_SECONDARY_INTERFACE` - path to a legacy secondary interface installed on the device. To use the example interface from the Aktualizr repo, use `/usr/bin/example-interface` and make sure `SOTA_CLIENT_FEATURES = "secondary-example"`. +* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. The only valid option is `hsm` (to build with HSM support) +* `SOTA_LEGACY_SECONDARY_INTERFACE` - path to a https://github.com/advancedtelematic/aktualizr/blob/master/docs/legacysecondary.adoc[legacy secondary interface] installed on the device. To use the example interface from the Aktualizr repo, use `/usr/bin/example-interface` and make sure `IMAGE_INSTALL_append` includes `aktualizr-examples`. * `SOTA_SECONDARY_ECUS` - a list of paths separated by spaces of JSON configuration files for virtual secondaries on the host. These will be installed into `/var/sota/ecus` on the device. * `SOTA_VIRTUAL_SECONDARIES` - a list of paths separated by spaces of JSON configuration files for virtual secondaries installed on the device. If `SOTA_SECONDARY_ECUS` is used to install them, then you can expect them to be installed in `/var/sota/ecus`. diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index adb4061..a5072e8 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -504,14 +504,55 @@ class HsmTests(OESelftestTestCase): verifyProvisioned(self, machine) +class SecondaryTests(OESelftestTestCase): + @classmethod + def setUpClass(cls): + super(SecondaryTests, cls).setUpClass() + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build secondary-image') + bitbake('secondary-image') + + def setUpLocal(self): + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='secondary-image') + + def tearDownLocal(self): + qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) + + def qemu_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + + def test_secondary_present(self): + print('Checking aktualizr-secondary is present') + stdout, stderr, retcode = self.qemu_command('aktualizr-secondary --help') + self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help") + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) -def qemu_launch(efi=False, machine=None): +def qemu_launch(efi=False, machine=None, imagename=None): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') bitbake('core-image-minimal') # Create empty object. args = type('', (), {})() - args.imagename = 'core-image-minimal' + if imagename: + args.imagename = imagename + else: + args.imagename = 'core-image-minimal' args.mac = None # Could use DEPLOY_DIR_IMAGE here but it's already in the machine # subdirectory. diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index 4c4e975..ad06339 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -20,7 +20,7 @@ SRC_URI = " \ file://aktualizr.service \ file://aktualizr-serialcan.service \ " -SRCREV = "1a6432175b9fb7326173e8db35d326cc1a1011a1" +SRCREV = "dca6271f4ec06eb2272cc99b4b9cf76a9805f18d" BRANCH ?= "master" S = "${WORKDIR}/git" @@ -34,27 +34,19 @@ BBCLASSEXTEND =+ "native" EXTRA_OECMAKE = "-DWARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} " EXTRA_OECMAKE_append_class-target = " -DBUILD_OSTREE=ON -DBUILD_ISOTP=ON ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', '-DBUILD_P11=ON', '', d)} " -EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF " +EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF -DBUILD_SYSTEMD=OFF " do_install_append () { rm -fr ${D}${libdir}/systemd + rm -f ${D}${libdir}/sota/sota.toml # Only needed for the Debian package } do_install_append_class-target () { - rm -f ${D}${bindir}/aktualizr_cert_provider - rm -f ${D}${bindir}/aktualizr_implicit_writer - rm -f ${D}${libdir}/sota/sota.toml - ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', '', 'rm -f ${D}${bindir}/example-interface', d)} - ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-isotp-example', '', 'rm -f ${D}${bindir}/isotp-test-interface', d)} - install -d ${D}${systemd_unitdir}/system aktualizr_service=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'serialcan', '${WORKDIR}/aktualizr-serialcan.service', '${WORKDIR}/aktualizr.service', d)} install -m 0644 ${aktualizr_service} ${D}${systemd_unitdir}/system/aktualizr.service } do_install_append_class-native () { - rm -f ${D}${bindir}/aktualizr - rm -f ${D}${bindir}/aktualizr-info - rm -f ${D}${bindir}/example-interface install -d ${D}${libdir}/sota install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml install -m 0644 ${S}/config/sota_hsm_prov.toml ${D}/${libdir}/sota/sota_hsm_prov.toml @@ -65,23 +57,37 @@ do_install_append_class-native () { install -m 0644 ${B}/src/sota_tools/garage-sign-prefix/src/garage-sign/lib/* ${D}${libdir} } -FILES_${PN}_append = " \ - ${libdir}/sota \ - " +PACKAGES =+ " ${PN}-common ${PN}-examples ${PN}-host-tools ${PN}-secondary " -FILES_${PN}_class-target = " \ +FILES_${PN} = " \ ${bindir}/aktualizr \ ${bindir}/aktualizr-info \ ${systemd_unitdir}/system/aktualizr.service \ " -FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', ' ${bindir}/example-interface', '', d)} " -FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-isotp-example', ' ${bindir}/isotp-test-interface', '', d)} " -FILES_${PN}_class-native = " \ +FILES_${PN}-common = " \ + ${libdir}/sota/schemas \ + " + +FILES_${PN}-examples = " \ + ${libdir}/sota/demo_secondary.json \ + ${bindir}/example-interface \ + ${bindir}/isotp-test-interface \ + " + +FILES_${PN}-host-tools = " \ ${bindir}/aktualizr_cert_provider \ ${bindir}/aktualizr_implicit_writer \ ${bindir}/garage-deploy \ ${bindir}/garage-push \ " +FILES_${PN}-secondary = " \ + ${bindir}/aktualizr-secondary \ + " + +# Both primary and secondary need the SQL Schemas +RDEPENDS_${PN}_class-target =+ "${PN}-common" +RDEPENDS_${PN}-secondary_class-target =+ "${PN}-common" + # vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-test/images/secondary-image.bb b/recipes-test/images/secondary-image.bb new file mode 100644 index 0000000..c7a91db --- /dev/null +++ b/recipes-test/images/secondary-image.bb @@ -0,0 +1,18 @@ +include recipes-core/images/core-image-minimal.bb + +SUMMARY = "A minimal Uptane Secondary image running aktualizr-secondary" + +LICENSE = "MIT" + + +# Remove default aktualizr primary, and the provisioning configuration (which +# RDEPENDS on aktualizr) +IMAGE_INSTALL_remove = " \ + aktualizr \ + aktualizr-auto-prov \ + aktualizr-ca-implicit-prov \ + aktualizr-hsm-prov \ + aktualizr-implicit-prov \ + " + +IMAGE_INSTALL_append = " aktualizr-secondary " \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 66a4721d0b7885a18db952d69f7ee385a95b2f2b Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Wed, 14 Mar 2018 16:00:53 +0100 Subject: Add systemd socket activation for secondary --- lib/oeqa/selftest/cases/updater.py | 5 +++++ recipes-sota/aktualizr/aktualizr_git.bb | 15 ++++++++++++++- recipes-sota/aktualizr/files/aktualizr-secondary.service | 9 +++++++++ recipes-sota/aktualizr/files/aktualizr-secondary.socket | 5 +++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 recipes-sota/aktualizr/files/aktualizr-secondary.service create mode 100644 recipes-sota/aktualizr/files/aktualizr-secondary.socket (limited to 'lib') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index a5072e8..1850d98 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -543,6 +543,11 @@ class SecondaryTests(OESelftestTestCase): self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help") self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) + def test_secondary_listening(self): + print('Checking aktualizr-secondary is present') + stdout, stderr, retcode = self.qemu_command('echo test | nc localhost 9030') + self.assertEqual(retcode, 0, "Unable to connect to secondary") + def qemu_launch(efi=False, machine=None, imagename=None): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index ad06339..5e683ac 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -18,9 +18,11 @@ PR = "7" SRC_URI = " \ gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \ file://aktualizr.service \ + file://aktualizr-secondary.service \ + file://aktualizr-secondary.socket \ file://aktualizr-serialcan.service \ " -SRCREV = "dca6271f4ec06eb2272cc99b4b9cf76a9805f18d" +SRCREV = "fbb3404824c4eb239455c7fa1a794c26e2ea954d" BRANCH ?= "master" S = "${WORKDIR}/git" @@ -28,7 +30,10 @@ S = "${WORKDIR}/git" inherit cmake inherit systemd + +SYSTEMD_PACKAGES = "${PN} ${PN}-secondary" SYSTEMD_SERVICE_${PN} = "aktualizr.service" +SYSTEMD_SERVICE_${PN}-secondary = "aktualizr-secondary.socket" BBCLASSEXTEND =+ "native" @@ -39,6 +44,11 @@ EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF - do_install_append () { rm -fr ${D}${libdir}/systemd rm -f ${D}${libdir}/sota/sota.toml # Only needed for the Debian package + install -d ${D}${libdir}/sota + install -m 0644 ${S}/config/sota_secondary.toml ${D}/${libdir}/sota/sota_secondary.toml + install -d ${D}${systemd_unitdir}/system + install -m 0644 ${WORKDIR}/aktualizr-secondary.socket ${D}${systemd_unitdir}/system/aktualizr-secondary.socket + install -m 0644 ${WORKDIR}/aktualizr-secondary.service ${D}${systemd_unitdir}/system/aktualizr-secondary.service } do_install_append_class-target () { install -d ${D}${systemd_unitdir}/system @@ -84,6 +94,9 @@ FILES_${PN}-host-tools = " \ FILES_${PN}-secondary = " \ ${bindir}/aktualizr-secondary \ + ${libdir}/sota/sota_secondary.toml \ + ${systemd_unitdir}/system/aktualizr-secondary.socket \ + ${systemd_unitdir}/system/aktualizr-secondary.service \ " # Both primary and secondary need the SQL Schemas diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.service b/recipes-sota/aktualizr/files/aktualizr-secondary.service new file mode 100644 index 0000000..a1e0e1b --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.service @@ -0,0 +1,9 @@ +[Unit] +Description=Aktualizr SOTA Client (UPTANE Secondary) + +[Service] +RestartSec=10 +Restart=always +EnvironmentFile=-/etc/sota/sota.env +ExecStart=/usr/bin/aktualizr-secondary --config /usr/lib/sota/sota_secondary.toml + diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.socket b/recipes-sota/aktualizr/files/aktualizr-secondary.socket new file mode 100644 index 0000000..1cb4269 --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.socket @@ -0,0 +1,5 @@ +[Socket] +ListenStream=9030 + +[Install] +WantedBy=sockets.target \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 046ac433f47b5a6cbacb95873e55f7d6c842a939 Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Tue, 20 Mar 2018 13:42:04 +0100 Subject: Fix up tests --- lib/oeqa/selftest/cases/updater.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index 1850d98..0e7c11b 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -570,6 +570,7 @@ def qemu_launch(efi=False, machine=None, imagename=None): args.pcap = None args.overlay = None args.dry_run = False + args.secondary_network = False qemu = QemuCommand(args) cmdline = qemu.command_line() -- cgit v1.2.3-54-g00ecf From 1804d9f6cfcae158fcf1e5c9da90fdf8cbc6fc18 Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Fri, 23 Mar 2018 11:56:15 +0100 Subject: UDP Socket activation for discovery service Also, timeout communication to the DUT after 60s. --- lib/oeqa/selftest/cases/updater.py | 4 ++-- recipes-sota/aktualizr/files/aktualizr-secondary.socket | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index 0e7c11b..06884e5 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -544,7 +544,7 @@ class SecondaryTests(OESelftestTestCase): self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) def test_secondary_listening(self): - print('Checking aktualizr-secondary is present') + print('Checking aktualizr-secondary service is listening') stdout, stderr, retcode = self.qemu_command('echo test | nc localhost 9030') self.assertEqual(retcode, 0, "Unable to connect to secondary") @@ -591,7 +591,7 @@ def qemu_send_command(port, command): command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + str(port) + ' "' + command + '"'] s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = s2.communicate() + stdout, stderr = s2.communicate(timeout=60) return stdout, stderr, s2.returncode diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.socket b/recipes-sota/aktualizr/files/aktualizr-secondary.socket index 1cb4269..bda8cdb 100644 --- a/recipes-sota/aktualizr/files/aktualizr-secondary.socket +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.socket @@ -1,5 +1,6 @@ [Socket] ListenStream=9030 +ListenDatagram=9030 [Install] WantedBy=sockets.target \ No newline at end of file -- cgit v1.2.3-54-g00ecf From de2b0f06546666aacf9dd2fce94e0134768c6a3b Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Tue, 27 Mar 2018 14:06:38 +0200 Subject: Add SOTA client feature to enable secondary network Also add a test for the 'primary-image' --- lib/oeqa/selftest/cases/updater.py | 41 ++++++++++++++++++++++ recipes-sota/aktualizr/aktualizr-auto-prov.bb | 4 ++- recipes-sota/aktualizr/aktualizr_git.bb | 3 +- .../files/27-dhcp-client-external.network | 6 ++++ .../secondary-network-config.bb | 6 +++- recipes-test/images/secondary-image.bb | 2 ++ 6 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 recipes-test/demo-network-config/files/27-dhcp-client-external.network (limited to 'lib') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index 06884e5..e459ffb 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -548,6 +548,47 @@ class SecondaryTests(OESelftestTestCase): stdout, stderr, retcode = self.qemu_command('echo test | nc localhost 9030') self.assertEqual(retcode, 0, "Unable to connect to secondary") + +class PrimaryTests(OESelftestTestCase): + @classmethod + def setUpClass(cls): + super(PrimaryTests, cls).setUpClass() + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build primary-image') + bitbake('primary-image') + + def setUpLocal(self): + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + self.append_config('SOTA_CLIENT_FEATURES = "secondary-network"') + self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='primary-image') + + def tearDownLocal(self): + qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) + + def qemu_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + + def test_aktualizr_present(self): + print('Checking aktualizr is present') + stdout, stderr, retcode = self.qemu_command('aktualizr --help') + self.assertEqual(retcode, 0, "Unable to run aktualizr --help") + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) + def qemu_launch(efi=False, machine=None, imagename=None): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov.bb b/recipes-sota/aktualizr/aktualizr-auto-prov.bb index 2190512..07e5bb8 100644 --- a/recipes-sota/aktualizr/aktualizr-auto-prov.bb +++ b/recipes-sota/aktualizr/aktualizr-auto-prov.bb @@ -35,7 +35,9 @@ do_install() { install -d ${D}${libdir}/sota install -d ${D}${localstatedir}/sota if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then - install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/sota_autoprov.toml ${D}${libdir}/sota/sota.toml + aktualizr_toml=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-network', 'sota_autoprov_primary.toml', 'sota_autoprov.toml', d)} + + install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/${aktualizr_toml} ${D}${libdir}/sota/sota.toml # deploy SOTA credentials if [ -e ${SOTA_PACKED_CREDENTIALS} ]; then diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index 79a89ef..ba0a261 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -22,7 +22,7 @@ SRC_URI = " \ file://aktualizr-secondary.socket \ file://aktualizr-serialcan.service \ " -SRCREV = "7d1d71a28a9ff0b14240b98600de3d541835b278" +SRCREV = "3fc94e7ed20a486da0067f01906250e9d4868931" BRANCH ?= "master" S = "${WORKDIR}/git" @@ -59,6 +59,7 @@ do_install_append_class-target () { do_install_append_class-native () { install -d ${D}${libdir}/sota install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml + install -m 0644 ${S}/config/sota_autoprov_primary.toml ${D}/${libdir}/sota/sota_autoprov_primary.toml install -m 0644 ${S}/config/sota_hsm_prov.toml ${D}/${libdir}/sota/sota_hsm_prov.toml install -m 0644 ${S}/config/sota_implicit_prov.toml ${D}/${libdir}/sota/sota_implicit_prov.toml install -m 0644 ${S}/config/sota_implicit_prov_ca.toml ${D}/${libdir}/sota/sota_implicit_prov_ca.toml diff --git a/recipes-test/demo-network-config/files/27-dhcp-client-external.network b/recipes-test/demo-network-config/files/27-dhcp-client-external.network new file mode 100644 index 0000000..ba49593 --- /dev/null +++ b/recipes-test/demo-network-config/files/27-dhcp-client-external.network @@ -0,0 +1,6 @@ +[Match] +Name=enp0s3 + +[Network] +Description=External network for secondary +DHCP=yes diff --git a/recipes-test/demo-network-config/secondary-network-config.bb b/recipes-test/demo-network-config/secondary-network-config.bb index 492d3ca..9091c65 100644 --- a/recipes-test/demo-network-config/secondary-network-config.bb +++ b/recipes-test/demo-network-config/secondary-network-config.bb @@ -3,7 +3,10 @@ LICENSE = "CLOSED" inherit allarch -SRC_URI = "file://26-dhcp-client.network" +SRC_URI = "\ + file://26-dhcp-client.network \ + file://27-dhcp-client-external.network \ + " FILES_${PN} = "/usr/lib/systemd/network" @@ -13,4 +16,5 @@ PR = "1" do_install() { install -d ${D}/usr/lib/systemd/network install -m 0644 ${WORKDIR}/26-dhcp-client.network ${D}/usr/lib/systemd/network/ + install -m 0644 ${WORKDIR}/27-dhcp-client-external.network ${D}/usr/lib/systemd/network/ } diff --git a/recipes-test/images/secondary-image.bb b/recipes-test/images/secondary-image.bb index c1ce57a..02153d0 100644 --- a/recipes-test/images/secondary-image.bb +++ b/recipes-test/images/secondary-image.bb @@ -13,6 +13,8 @@ IMAGE_INSTALL_remove = " \ aktualizr-ca-implicit-prov \ aktualizr-hsm-prov \ aktualizr-implicit-prov \ + connman \ + connman-client \ " IMAGE_INSTALL_append = " \ -- cgit v1.2.3-54-g00ecf