diff options
author | cajun-rat <phil@advancedtelematic.com> | 2018-03-08 13:46:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-08 13:46:15 +0100 |
commit | f1fd04ac20d778bed88727571359b4cf39e481c1 (patch) | |
tree | eae25353a26d97e9257ddca0cfdda9d3e601f4cc | |
parent | 11d0cd23f14c64f541adb640264bd80ab938c034 (diff) | |
parent | 81b2fa6bf0b5d7d68dc81c83ecc1ba15cba2ac9b (diff) | |
download | meta-updater-f1fd04ac20d778bed88727571359b4cf39e481c1.tar.gz |
Merge pull request #268 from advancedtelematic/test/better-oe-selftest
Test/better oe selftest
-rw-r--r-- | README.adoc | 10 | ||||
-rw-r--r-- | lib/oeqa/selftest/cases/updater.py | 260 |
2 files changed, 195 insertions, 75 deletions
diff --git a/README.adoc b/README.adoc index c87bd01..3562f52 100644 --- a/README.adoc +++ b/README.adoc | |||
@@ -20,7 +20,7 @@ If you already have a Yocto-based project and you want to add atomic filesystem | |||
20 | 2. Clone BSP integration layer (`meta-updater-$\{PLATFORM}`, e.g. https://github.com/advancedtelematic/meta-updater-raspberrypi[meta-updater-raspberrypi]) and add it to your `conf/bblayers.conf`. If your board isn't supported yet, you could write a BSP integration for it yourself. See the <<Adding support for your board>> section for the details. | 20 | 2. Clone BSP integration layer (`meta-updater-$\{PLATFORM}`, e.g. https://github.com/advancedtelematic/meta-updater-raspberrypi[meta-updater-raspberrypi]) and add it to your `conf/bblayers.conf`. If your board isn't supported yet, you could write a BSP integration for it yourself. See the <<Adding support for your board>> section for the details. |
21 | 3. Set up your https://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-DISTRO[distro]. If you are using "poky", the default distro in Yocto, you can change it in your `conf/local.conf` to "poky-sota". Alternatively, if you are using your own or third party distro configuration, you can add `INHERIT += " sota"` to it, thus combining capabilities of your distro with meta-updater features. | 21 | 3. Set up your https://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-DISTRO[distro]. If you are using "poky", the default distro in Yocto, you can change it in your `conf/local.conf` to "poky-sota". Alternatively, if you are using your own or third party distro configuration, you can add `INHERIT += " sota"` to it, thus combining capabilities of your distro with meta-updater features. |
22 | 22 | ||
23 | You can then build your image as usual, with bitbake. After building the root file system, bitbake will then create an https://ostree.readthedocs.io/en/latest/manual/adapting-existing/[OSTree-enabled version] of it, commit it to your local OSTree repo and (optionally) push it to a remote server. Additionally, a live disk image will be created (normally named `$\{IMAGE_NAME}.-sdimg-ota` e.g. `core-image-raspberrypi3.rpi-sdimg-ota`). You can control this behaviour through <<variables in your local.conf,OSTree-related variables in your local.conf>>. | 23 | You can then build your image as usual, with bitbake. After building the root file system, bitbake will then create an https://ostree.readthedocs.io/en/latest/manual/adapting-existing/[OSTree-enabled version] of it, commit it to your local OSTree repo and (optionally) push it to a remote server. Additionally, a live disk image will be created (normally named `$\{IMAGE_NAME}.-sdimg-ota` e.g. `core-image-raspberrypi3.rpi-sdimg-ota`). You can control this behaviour through <<sota-related-variables-in-localconf,variables in your local.conf>>. |
24 | 24 | ||
25 | === Build in AGL | 25 | === Build in AGL |
26 | 26 | ||
@@ -73,7 +73,7 @@ You may take a look into https://github.com/advancedtelematic/meta-updater-minno | |||
73 | 73 | ||
74 | Although we have used U-Boot so far, other boot loaders can be configured work with OSTree as well. | 74 | Although we have used U-Boot so far, other boot loaders can be configured work with OSTree as well. |
75 | 75 | ||
76 | == SOTA-related variables in `local.conf` | 76 | == SOTA-related variables in local.conf |
77 | 77 | ||
78 | * `OSTREE_REPO` - path to your OSTree repository. Defaults to `$\{DEPLOY_DIR_IMAGE}/ostree_repo` | 78 | * `OSTREE_REPO` - path to your OSTree repository. Defaults to `$\{DEPLOY_DIR_IMAGE}/ostree_repo` |
79 | * `OSTREE_OSNAME` - OS deployment name on your target device. For more information about deployments and osnames see the https://ostree.readthedocs.io/en/latest/manual/deployment/[OSTree documentation]. Defaults to "poky". | 79 | * `OSTREE_OSNAME` - OS deployment name on your target device. For more information about deployments and osnames see the https://ostree.readthedocs.io/en/latest/manual/deployment/[OSTree documentation]. Defaults to "poky". |
@@ -151,13 +151,15 @@ SANITY_TESTED_DISTROS = "" | |||
151 | IMAGE_INSTALL_append = " dropbear " | 151 | IMAGE_INSTALL_append = " dropbear " |
152 | ``` | 152 | ``` |
153 | 153 | ||
154 | 3. To be able to build an image for the grub tests, you will need to install https://github.com/tianocore/tianocore.github.io/wiki/OVMF[TianoCore's ovmf] package on your host system. On Debian-like systems, you can do so with this command: | 154 | 3. Some tests require that `SOTA_PACKED_CREDENTIALS` is set in your `conf/local.conf`. See the <<sota-related-variables-in-localconf,SOTA-related variables in local.conf>> section. |
155 | |||
156 | 4. To be able to build an image for the grub tests, you will need to install https://github.com/tianocore/tianocore.github.io/wiki/OVMF[TianoCore's ovmf] package on your host system. On Debian-like systems, you can do so with this command: | ||
155 | + | 157 | + |
156 | ``` | 158 | ``` |
157 | sudo apt install ovmf | 159 | sudo apt install ovmf |
158 | ``` | 160 | ``` |
159 | 161 | ||
160 | 4. Run oe-selftest: | 162 | 5. Run oe-selftest: |
161 | + | 163 | + |
162 | ``` | 164 | ``` |
163 | oe-selftest --run-tests updater | 165 | oe-selftest --run-tests updater |
diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index b544762..adb4061 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py | |||
@@ -64,7 +64,6 @@ class GeneralTests(OESelftestTestCase): | |||
64 | "Java not found. Do you have a JDK installed on your host machine?") | 64 | "Java not found. Do you have a JDK installed on your host machine?") |
65 | 65 | ||
66 | def test_add_package(self): | 66 | def test_add_package(self): |
67 | print('') | ||
68 | deploydir = get_bb_var('DEPLOY_DIR_IMAGE') | 67 | deploydir = get_bb_var('DEPLOY_DIR_IMAGE') |
69 | imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal') | 68 | imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal') |
70 | image_path = deploydir + '/' + imagename + '.otaimg' | 69 | image_path = deploydir + '/' + imagename + '.otaimg' |
@@ -134,22 +133,34 @@ class AktualizrToolsTests(OESelftestTestCase): | |||
134 | self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path) | 133 | self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path) |
135 | 134 | ||
136 | 135 | ||
137 | class QemuTests(OESelftestTestCase): | 136 | class AutoProvTests(OESelftestTestCase): |
138 | 137 | ||
139 | @classmethod | 138 | def setUpLocal(self): |
140 | def setUpClass(cls): | 139 | layer = "meta-updater-qemux86-64" |
141 | super(QemuTests, cls).setUpClass() | 140 | result = runCmd('bitbake-layers show-layers') |
142 | cls.qemu, cls.s = qemu_launch(machine='qemux86-64') | 141 | if re.search(layer, result.output) is None: |
142 | # Assume the directory layout for finding other layers. We could also | ||
143 | # make assumptions by using 'show-layers', but either way, if the | ||
144 | # layers we need aren't where we expect them, we are out of like. | ||
145 | path = os.path.abspath(os.path.dirname(__file__)) | ||
146 | metadir = path + "/../../../../../" | ||
147 | self.meta_qemu = metadir + layer | ||
148 | runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) | ||
149 | else: | ||
150 | self.meta_qemu = None | ||
151 | self.append_config('MACHINE = "qemux86-64"') | ||
152 | self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') | ||
153 | self.qemu, self.s = qemu_launch(machine='qemux86-64') | ||
143 | 154 | ||
144 | @classmethod | 155 | def tearDownLocal(self): |
145 | def tearDownClass(cls): | 156 | qemu_terminate(self.s) |
146 | qemu_terminate(cls.s) | 157 | if self.meta_qemu: |
147 | super(QemuTests, cls).tearDownClass() | 158 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) |
148 | 159 | ||
149 | def qemu_command(self, command): | 160 | def qemu_command(self, command): |
150 | return qemu_send_command(self.qemu.ssh_port, command) | 161 | return qemu_send_command(self.qemu.ssh_port, command) |
151 | 162 | ||
152 | def test_qemu(self): | 163 | def test_provisioning(self): |
153 | print('Checking machine name (hostname) of device:') | 164 | print('Checking machine name (hostname) of device:') |
154 | stdout, stderr, retcode = self.qemu_command('hostname') | 165 | stdout, stderr, retcode = self.qemu_command('hostname') |
155 | self.assertEqual(retcode, 0, "Unable to check hostname. " + | 166 | self.assertEqual(retcode, 0, "Unable to check hostname. " + |
@@ -157,10 +168,10 @@ class QemuTests(OESelftestTestCase): | |||
157 | machine = get_bb_var('MACHINE', 'core-image-minimal') | 168 | machine = get_bb_var('MACHINE', 'core-image-minimal') |
158 | self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) | 169 | self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) |
159 | # Strip off line ending. | 170 | # Strip off line ending. |
160 | value_str = stdout.decode()[:-1] | 171 | value = stdout.decode()[:-1] |
161 | self.assertEqual(value_str, machine, | 172 | self.assertEqual(value, machine, |
162 | 'MACHINE does not match hostname: ' + machine + ', ' + value_str) | 173 | 'MACHINE does not match hostname: ' + machine + ', ' + value) |
163 | print(value_str) | 174 | print(value) |
164 | print('Checking output of aktualizr-info:') | 175 | print('Checking output of aktualizr-info:') |
165 | ran_ok = False | 176 | ran_ok = False |
166 | for delay in [0, 1, 2, 5, 10, 15]: | 177 | for delay in [0, 1, 2, 5, 10, 15]: |
@@ -171,31 +182,122 @@ class QemuTests(OESelftestTestCase): | |||
171 | break | 182 | break |
172 | self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) | 183 | self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) |
173 | 184 | ||
185 | verifyProvisioned(self, machine) | ||
186 | |||
187 | |||
188 | class RpiTests(OESelftestTestCase): | ||
189 | |||
190 | def setUpLocal(self): | ||
191 | # Add layers before changing the machine type, otherwise the sanity | ||
192 | # checker complains loudly. | ||
193 | layer_python = "meta-openembedded/meta-python" | ||
194 | layer_rpi = "meta-raspberrypi" | ||
195 | layer_upd_rpi = "meta-updater-raspberrypi" | ||
196 | result = runCmd('bitbake-layers show-layers') | ||
197 | # Assume the directory layout for finding other layers. We could also | ||
198 | # make assumptions by using 'show-layers', but either way, if the | ||
199 | # layers we need aren't where we expect them, we are out of like. | ||
200 | path = os.path.abspath(os.path.dirname(__file__)) | ||
201 | metadir = path + "/../../../../../" | ||
202 | if re.search(layer_python, result.output) is None: | ||
203 | self.meta_python = metadir + layer_python | ||
204 | runCmd('bitbake-layers add-layer "%s"' % self.meta_python) | ||
205 | else: | ||
206 | self.meta_python = None | ||
207 | if re.search(layer_rpi, result.output) is None: | ||
208 | self.meta_rpi = metadir + layer_rpi | ||
209 | runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi) | ||
210 | else: | ||
211 | self.meta_rpi = None | ||
212 | if re.search(layer_upd_rpi, result.output) is None: | ||
213 | self.meta_upd_rpi = metadir + layer_upd_rpi | ||
214 | runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi) | ||
215 | else: | ||
216 | self.meta_upd_rpi = None | ||
217 | |||
218 | # This is trickier that I would've thought. The fundamental problem is | ||
219 | # that the qemu layer changes the u-boot file extension to .rom, but | ||
220 | # raspberrypi still expects .bin. To prevent this, the qemu layer must | ||
221 | # be temporarily removed if it is present. It has to be removed by name | ||
222 | # without the complete path, but to add it back when we are done, we | ||
223 | # need the full path. | ||
224 | p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s') | ||
225 | m = p.search(result.output) | ||
226 | if m and m.lastindex > 0: | ||
227 | self.meta_qemu = m.group(1) | ||
228 | runCmd('bitbake-layers remove-layer meta-updater-qemux86-64') | ||
229 | else: | ||
230 | self.meta_qemu = None | ||
231 | |||
232 | self.append_config('MACHINE = "raspberrypi3"') | ||
233 | self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') | ||
234 | |||
235 | def tearDownLocal(self): | ||
236 | if self.meta_qemu: | ||
237 | runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True) | ||
238 | if self.meta_upd_rpi: | ||
239 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True) | ||
240 | if self.meta_rpi: | ||
241 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True) | ||
242 | if self.meta_python: | ||
243 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_python, ignore_status=True) | ||
244 | |||
245 | def test_rpi(self): | ||
246 | logger = logging.getLogger("selftest") | ||
247 | logger.info('Running bitbake to build rpi-basic-image') | ||
248 | self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"') | ||
249 | bitbake('rpi-basic-image') | ||
250 | credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') | ||
251 | # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set. | ||
252 | if credentials is None: | ||
253 | raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.") | ||
254 | # Check if the file exists. | ||
255 | self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials) | ||
256 | deploydir = get_bb_var('DEPLOY_DIR_IMAGE') | ||
257 | imagename = get_bb_var('IMAGE_LINK_NAME', 'rpi-basic-image') | ||
258 | # Check if the credentials are included in the output image. | ||
259 | result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' % | ||
260 | (deploydir, imagename), ignore_status=True) | ||
261 | self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) | ||
262 | |||
174 | 263 | ||
175 | class GrubTests(OESelftestTestCase): | 264 | class GrubTests(OESelftestTestCase): |
176 | 265 | ||
177 | def setUpLocal(self): | 266 | def setUpLocal(self): |
178 | # This is a bit of a hack but I can't see a better option. | 267 | layer_intel = "meta-intel" |
268 | layer_minnow = "meta-updater-minnowboard" | ||
269 | result = runCmd('bitbake-layers show-layers') | ||
270 | # Assume the directory layout for finding other layers. We could also | ||
271 | # make assumptions by using 'show-layers', but either way, if the | ||
272 | # layers we need aren't where we expect them, we are out of like. | ||
179 | path = os.path.abspath(os.path.dirname(__file__)) | 273 | path = os.path.abspath(os.path.dirname(__file__)) |
180 | metadir = path + "/../../../../../" | 274 | metadir = path + "/../../../../../" |
181 | grub_config = 'OSTREE_BOOTLOADER = "grub"\nMACHINE = "intel-corei7-64"' | 275 | if re.search(layer_intel, result.output) is None: |
182 | self.append_config(grub_config) | 276 | self.meta_intel = metadir + layer_intel |
183 | self.meta_intel = metadir + "meta-intel" | 277 | runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) |
184 | self.meta_minnow = metadir + "meta-updater-minnowboard" | 278 | else: |
185 | runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) | 279 | self.meta_intel = None |
186 | runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) | 280 | if re.search(layer_minnow, result.output) is None: |
281 | self.meta_minnow = metadir + layer_minnow | ||
282 | runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) | ||
283 | else: | ||
284 | self.meta_minnow = None | ||
285 | self.append_config('MACHINE = "intel-corei7-64"') | ||
286 | self.append_config('OSTREE_BOOTLOADER = "grub"') | ||
287 | self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') | ||
187 | self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') | 288 | self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') |
188 | 289 | ||
189 | def tearDownLocal(self): | 290 | def tearDownLocal(self): |
190 | qemu_terminate(self.s) | 291 | qemu_terminate(self.s) |
191 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) | 292 | if self.meta_intel: |
192 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) | 293 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) |
294 | if self.meta_minnow: | ||
295 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) | ||
193 | 296 | ||
194 | def qemu_command(self, command): | 297 | def qemu_command(self, command): |
195 | return qemu_send_command(self.qemu.ssh_port, command) | 298 | return qemu_send_command(self.qemu.ssh_port, command) |
196 | 299 | ||
197 | def test_grub(self): | 300 | def test_grub(self): |
198 | print('') | ||
199 | print('Checking machine name (hostname) of device:') | 301 | print('Checking machine name (hostname) of device:') |
200 | stdout, stderr, retcode = self.qemu_command('hostname') | 302 | stdout, stderr, retcode = self.qemu_command('hostname') |
201 | self.assertEqual(retcode, 0, "Unable to check hostname. " + | 303 | self.assertEqual(retcode, 0, "Unable to check hostname. " + |
@@ -218,16 +320,32 @@ class GrubTests(OESelftestTestCase): | |||
218 | break | 320 | break |
219 | self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) | 321 | self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) |
220 | 322 | ||
323 | verifyProvisioned(self, machine) | ||
324 | |||
221 | 325 | ||
222 | class ImplProvTests(OESelftestTestCase): | 326 | class ImplProvTests(OESelftestTestCase): |
223 | 327 | ||
224 | def setUpLocal(self): | 328 | def setUpLocal(self): |
329 | layer = "meta-updater-qemux86-64" | ||
330 | result = runCmd('bitbake-layers show-layers') | ||
331 | if re.search(layer, result.output) is None: | ||
332 | # Assume the directory layout for finding other layers. We could also | ||
333 | # make assumptions by using 'show-layers', but either way, if the | ||
334 | # layers we need aren't where we expect them, we are out of like. | ||
335 | path = os.path.abspath(os.path.dirname(__file__)) | ||
336 | metadir = path + "/../../../../../" | ||
337 | self.meta_qemu = metadir + layer | ||
338 | runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) | ||
339 | else: | ||
340 | self.meta_qemu = None | ||
341 | self.append_config('MACHINE = "qemux86-64"') | ||
225 | self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') | 342 | self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') |
226 | # note: this will build aktualizr-native as a side-effect | ||
227 | self.qemu, self.s = qemu_launch(machine='qemux86-64') | 343 | self.qemu, self.s = qemu_launch(machine='qemux86-64') |
228 | 344 | ||
229 | def tearDownLocal(self): | 345 | def tearDownLocal(self): |
230 | qemu_terminate(self.s) | 346 | qemu_terminate(self.s) |
347 | if self.meta_qemu: | ||
348 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) | ||
231 | 349 | ||
232 | def qemu_command(self, command): | 350 | def qemu_command(self, command): |
233 | return qemu_send_command(self.qemu.ssh_port, command) | 351 | return qemu_send_command(self.qemu.ssh_port, command) |
@@ -240,10 +358,10 @@ class ImplProvTests(OESelftestTestCase): | |||
240 | machine = get_bb_var('MACHINE', 'core-image-minimal') | 358 | machine = get_bb_var('MACHINE', 'core-image-minimal') |
241 | self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) | 359 | self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) |
242 | # Strip off line ending. | 360 | # Strip off line ending. |
243 | value_str = stdout.decode()[:-1] | 361 | value = stdout.decode()[:-1] |
244 | self.assertEqual(value_str, machine, | 362 | self.assertEqual(value, machine, |
245 | 'MACHINE does not match hostname: ' + machine + ', ' + value_str) | 363 | 'MACHINE does not match hostname: ' + machine + ', ' + value) |
246 | print(value_str) | 364 | print(value) |
247 | print('Checking output of aktualizr-info:') | 365 | print('Checking output of aktualizr-info:') |
248 | ran_ok = False | 366 | ran_ok = False |
249 | for delay in [0, 1, 2, 5, 10, 15]: | 367 | for delay in [0, 1, 2, 5, 10, 15]: |
@@ -271,36 +389,33 @@ class ImplProvTests(OESelftestTestCase): | |||
271 | akt_native_run(self, 'aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -s -g {config}' | 389 | akt_native_run(self, 'aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -s -g {config}' |
272 | .format(creds=creds, port=self.qemu.ssh_port, config=config)) | 390 | .format(creds=creds, port=self.qemu.ssh_port, config=config)) |
273 | 391 | ||
274 | # Verify that device HAS provisioned. | 392 | verifyProvisioned(self, machine) |
275 | ran_ok = False | ||
276 | for delay in [5, 5, 5, 5, 10]: | ||
277 | sleep(delay) | ||
278 | stdout, stderr, retcode = self.qemu_command('aktualizr-info') | ||
279 | if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: | ||
280 | ran_ok = True | ||
281 | break | ||
282 | self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
283 | self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, | ||
284 | 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
285 | self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
286 | p = re.compile(r'Device ID: ([a-z0-9-]*)\n') | ||
287 | m = p.search(stdout.decode()) | ||
288 | self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) | ||
289 | self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) | ||
290 | logger = logging.getLogger("selftest") | ||
291 | logger.info('Device successfully provisioned with ID: ' + m.group(1)) | ||
292 | 393 | ||
293 | 394 | ||
294 | class HsmTests(OESelftestTestCase): | 395 | class HsmTests(OESelftestTestCase): |
295 | 396 | ||
296 | def setUpLocal(self): | 397 | def setUpLocal(self): |
398 | layer = "meta-updater-qemux86-64" | ||
399 | result = runCmd('bitbake-layers show-layers') | ||
400 | if re.search(layer, result.output) is None: | ||
401 | # Assume the directory layout for finding other layers. We could also | ||
402 | # make assumptions by using 'show-layers', but either way, if the | ||
403 | # layers we need aren't where we expect them, we are out of like. | ||
404 | path = os.path.abspath(os.path.dirname(__file__)) | ||
405 | metadir = path + "/../../../../../" | ||
406 | self.meta_qemu = metadir + layer | ||
407 | runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) | ||
408 | else: | ||
409 | self.meta_qemu = None | ||
410 | self.append_config('MACHINE = "qemux86-64"') | ||
297 | self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') | 411 | self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') |
298 | self.append_config('SOTA_CLIENT_FEATURES = "hsm"') | 412 | self.append_config('SOTA_CLIENT_FEATURES = "hsm"') |
299 | # note: this will build aktualizr-native as a side-effect | ||
300 | self.qemu, self.s = qemu_launch(machine='qemux86-64') | 413 | self.qemu, self.s = qemu_launch(machine='qemux86-64') |
301 | 414 | ||
302 | def tearDownLocal(self): | 415 | def tearDownLocal(self): |
303 | qemu_terminate(self.s) | 416 | qemu_terminate(self.s) |
417 | if self.meta_qemu: | ||
418 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) | ||
304 | 419 | ||
305 | def qemu_command(self, command): | 420 | def qemu_command(self, command): |
306 | return qemu_send_command(self.qemu.ssh_port, command) | 421 | return qemu_send_command(self.qemu.ssh_port, command) |
@@ -313,11 +428,11 @@ class HsmTests(OESelftestTestCase): | |||
313 | machine = get_bb_var('MACHINE', 'core-image-minimal') | 428 | machine = get_bb_var('MACHINE', 'core-image-minimal') |
314 | self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) | 429 | self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) |
315 | # Strip off line ending. | 430 | # Strip off line ending. |
316 | value_str = stdout.decode()[:-1] | 431 | value = stdout.decode()[:-1] |
317 | self.assertEqual(value_str, machine, | 432 | self.assertEqual(value, machine, |
318 | 'MACHINE does not match hostname: ' + machine + ', ' + value_str + | 433 | 'MACHINE does not match hostname: ' + machine + ', ' + value + |
319 | '\nIs tianocore ovmf installed?') | 434 | '\nIs tianocore ovmf installed?') |
320 | print(value_str) | 435 | print(value) |
321 | print('Checking output of aktualizr-info:') | 436 | print('Checking output of aktualizr-info:') |
322 | ran_ok = False | 437 | ran_ok = False |
323 | for delay in [0, 1, 2, 5, 10, 15]: | 438 | for delay in [0, 1, 2, 5, 10, 15]: |
@@ -387,24 +502,7 @@ class HsmTests(OESelftestTestCase): | |||
387 | self.assertEqual(p11_m.group(1), hsm_m.group(1), 'Slot number does not match: ' + | 502 | self.assertEqual(p11_m.group(1), hsm_m.group(1), 'Slot number does not match: ' + |
388 | p11_err.decode() + p11_out.decode() + hsm_err.decode() + hsm_out.decode()) | 503 | p11_err.decode() + p11_out.decode() + hsm_err.decode() + hsm_out.decode()) |
389 | 504 | ||
390 | # Verify that device HAS provisioned. | 505 | verifyProvisioned(self, machine) |
391 | ran_ok = False | ||
392 | for delay in [5, 5, 5, 5, 10]: | ||
393 | sleep(delay) | ||
394 | stdout, stderr, retcode = self.qemu_command('aktualizr-info') | ||
395 | if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: | ||
396 | ran_ok = True | ||
397 | break | ||
398 | self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
399 | self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, | ||
400 | 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
401 | self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
402 | p = re.compile(r'Device ID: ([a-z0-9-]*)\n') | ||
403 | m = p.search(stdout.decode()) | ||
404 | self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) | ||
405 | self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) | ||
406 | logger = logging.getLogger("selftest") | ||
407 | logger.info('Device successfully provisioned with ID: ' + m.group(1)) | ||
408 | 506 | ||
409 | 507 | ||
410 | def qemu_launch(efi=False, machine=None): | 508 | def qemu_launch(efi=False, machine=None): |
@@ -471,5 +569,25 @@ def akt_native_run(testInst, cmd, **kwargs): | |||
471 | testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) | 569 | testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) |
472 | 570 | ||
473 | 571 | ||
572 | def verifyProvisioned(testInst, machine): | ||
573 | # Verify that device HAS provisioned. | ||
574 | ran_ok = False | ||
575 | for delay in [5, 5, 5, 5, 10]: | ||
576 | sleep(delay) | ||
577 | stdout, stderr, retcode = testInst.qemu_command('aktualizr-info') | ||
578 | if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: | ||
579 | ran_ok = True | ||
580 | break | ||
581 | testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
582 | testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout, | ||
583 | 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
584 | testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) | ||
585 | p = re.compile(r'Device ID: ([a-z0-9-]*)\n') | ||
586 | m = p.search(stdout.decode()) | ||
587 | testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) | ||
588 | testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) | ||
589 | logger = logging.getLogger("selftest") | ||
590 | logger.info('Device successfully provisioned with ID: ' + m.group(1)) | ||
591 | |||
474 | 592 | ||
475 | # vim:set ts=4 sw=4 sts=4 expandtab: | 593 | # vim:set ts=4 sw=4 sts=4 expandtab: |