Merge ~jocave/plainbox-provider-checkbox:iot-image-checks into plainbox-provider-checkbox:master

Proposed by Jonathan Cave
Status: Merged
Approved by: Jonathan Cave
Approved revision: fecd5b893edb77421bc79c2b96bed4020e6342b1
Merged at revision: 6063034fb9013cbbfc3c11324a82b7fc6389fd42
Proposed branch: ~jocave/plainbox-provider-checkbox:iot-image-checks
Merge into: plainbox-provider-checkbox:master
Diff against target: 237 lines (+211/-0)
4 files modified
bin/ubuntucore_image_checks.py (+116/-0)
units/image/category.pxu (+3/-0)
units/image/jobs.pxu (+72/-0)
units/image/test-plan.pxu (+20/-0)
Reviewer Review Type Date Requested Status
Sheila Miguez (community) Approve
Review via email: mp+387048@code.launchpad.net

Description of the change

I wrote these tests to go in to the test plan I had been working on whose goal was to certify Ubuntu Core IoT images. I'm not sure how relevant these are going to be now, but since I put the time in I may as well propose them.

I test them on an amd64 machine running generic UC18.

To post a comment you must log in.
Revision history for this message
Sheila Miguez (codersquid) wrote :

I have a very minor comment about a summary. Otherwise things seem ok.

Revision history for this message
Jonathan Cave (jocave) wrote :

Good spot, thanks. Fixed and squashed

Revision history for this message
Sheila Miguez (codersquid) wrote :

lgtm

review: Approve
Revision history for this message
Chris Wayne (cwayne) wrote :

Obviously this is still relevant for the core images, so very worth writing, thanks. Given the ODM program pricing structure has core as 50% of the cost of classic, I think we can still assume the majority will be core.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bin/ubuntucore_image_checks.py b/bin/ubuntucore_image_checks.py
0new file mode 1007550new file mode 100755
index 0000000..214fc42
--- /dev/null
+++ b/bin/ubuntucore_image_checks.py
@@ -0,0 +1,116 @@
1#!/usr/bin/env python3
2# Copyright 2020 Canonical Ltd.
3# All rights reserved.
4#
5# Written by:
6# Jonathan Cave <jonathan.cave@canonical.com>
7
8import io
9import sys
10
11from checkbox_support.snap_utils.snapd import Snapd
12
13
14class SnapInfo():
15
16 def __init__(self):
17 self.kernel = None
18 self.gadget = None
19 data = Snapd().list()
20 for snap in data:
21 if snap['type'] == 'kernel':
22 self.kernel = snap
23 if snap['type'] == 'gadget':
24 self.gadget = snap
25
26 def test_kernel_publisher(self):
27 if not self.kernel:
28 raise SystemExit('ERROR: failed to get kernel snap info')
29 if self.kernel['publisher']['id'] != 'canonical':
30 raise SystemExit('ERROR: kernel snap publisher must be canonical')
31 if self.kernel['publisher']['validation'] != 'verified':
32 raise SystemExit('ERROR: kernel snap publisher must be verified')
33 print('PASS')
34
35 def test_kernel_tracking(self):
36 if not self.kernel:
37 raise SystemExit('ERROR: failed to get kernel snap info')
38 if not self.kernel.get('tracking-channel'):
39 raise SystemExit('ERROR: kernel must be tracking a store channel')
40 if 'stable' not in self.kernel['tracking-channel']:
41 raise SystemExit('ERROR: kernel must be on a stable channel')
42 print('PASS')
43
44 def test_gadget_publisher(self):
45 if not self.gadget:
46 raise SystemExit('ERROR: failed to get gadget snap info')
47 if self.gadget['publisher']['id'] != 'canonical':
48 raise SystemExit('ERROR: gadget snap publisher must be canonical')
49 if self.gadget['publisher']['validation'] != 'verified':
50 raise SystemExit('ERROR: gadget snap publisher must be verified')
51 print('PASS')
52
53 def test_gadget_tracking(self):
54 if not self.gadget:
55 raise SystemExit('ERROR: failed to get gadget snap info')
56 if not self.gadget.get('tracking-channel'):
57 raise SystemExit('ERROR: gadget must be tracking a store channel')
58 if 'stable' not in self.gadget['tracking-channel']:
59 raise SystemExit('ERROR: gadget must be on a stable channel')
60 print('PASS')
61
62
63class ModelInfo():
64
65 def __init__(self):
66 self.authority = None
67 self.brand = None
68 for line in io.StringIO(Snapd().get_assertions('model').text):
69 if ':' in line:
70 entry = line.split(':', maxsplit=1)
71 if entry[0] == 'authority-id':
72 self.authority = entry[1].strip()
73 if entry[0] == 'brand-id':
74 self.brand = entry[1].strip()
75
76 def test_model_authority(self):
77 if not self.authority:
78 raise SystemExit('ERROR: failed to get model authority info')
79 if self.authority != 'canonical':
80 raise SystemExit('ERROR: model authority must be canonical')
81 print('PASS')
82
83 def test_model_brand(self):
84 if not self.brand:
85 raise SystemExit('ERROR: failed to get model brand info')
86 if self.brand != 'canonical':
87 raise SystemExit('ERROR: model brand must be canonical')
88 print('PASS')
89
90
91def main():
92 if len(sys.argv) != 2:
93 raise SystemExit('USAGE: ubuntucore_image_checks.py [action]')
94 action = sys.argv[1]
95
96 snapinfo = SnapInfo()
97 modelinfo = ModelInfo()
98
99 if action == 'kernel-publisher':
100 snapinfo.test_kernel_publisher()
101 elif action == 'kernel-tracking':
102 snapinfo.test_kernel_tracking()
103 elif action == 'gadget-publisher':
104 snapinfo.test_gadget_publisher()
105 elif action == 'gadget-tracking':
106 snapinfo.test_gadget_tracking()
107 elif action == 'model-authority':
108 modelinfo.test_model_authority()
109 elif action == 'model-brand':
110 modelinfo.test_model_authority()
111 else:
112 raise SystemExit('ERROR: unrecognised action')
113
114
115if __name__ == '__main__':
116 main()
diff --git a/units/image/category.pxu b/units/image/category.pxu
0new file mode 100644117new file mode 100644
index 0000000..919d6cf
--- /dev/null
+++ b/units/image/category.pxu
@@ -0,0 +1,3 @@
1unit: category
2id: image
3_name: Image verification tests
0\ No newline at end of file4\ No newline at end of file
diff --git a/units/image/jobs.pxu b/units/image/jobs.pxu
1new file mode 1006445new file mode 100644
index 0000000..efe8d4e
--- /dev/null
+++ b/units/image/jobs.pxu
@@ -0,0 +1,72 @@
1
2id: image/kernel-publisher-canonical
3category_id: image
4summary: Check that the kernel snap publisher is Canonical
5description:
6 During certification testing IoT devices must be running a kernel supplied
7 by Canonical
8plugin: shell
9command:
10 ubuntucore_image_checks.py kernel-publisher
11estimated_duration: 2.0
12flags: preserve-locale
13
14id: image/kernel-tracking-stable
15category_id: image
16summary: Check that the kernel snap is tracking stable channel
17description:
18 During certification testing IoT devices must be running a kernel that is on
19 a stable channel
20plugin: shell
21command:
22 ubuntucore_image_checks.py kernel-tracking
23estimated_duration: 2.0
24flags: preserve-locale
25
26id: image/gadget-publisher-canonical
27category_id: image
28summary: Check that the gadget snap publisher is Canonical
29description:
30 During certification testing IoT devices must be running a kernel supplied
31 by Canonical
32plugin: shell
33command:
34 ubuntucore_image_checks.py gadget-publisher
35estimated_duration: 2.0
36flags: preserve-locale
37
38id: image/gadget-tracking-stable
39category_id: image
40summary: Check that the gadget snap is tracking stable channel
41description:
42 During certification testing IoT devices must be running a gadget that is on
43 a stable channel
44plugin: shell
45command:
46 ubuntucore_image_checks.py gadget-tracking
47estimated_duration: 2.0
48flags: preserve-locale
49
50id: image/model-authority-canonical
51category_id: image
52summary: Check that model authority-id is canonical
53description:
54 The authority-id declares on whose authority this assertion is made. This
55 must be Canonical for the certification of IoT devices.
56plugin: shell
57command:
58 ubuntucore_image_checks.py model-authority
59estimated_duration: 2.0
60flags: preserve-locale
61
62id: image/model-brand-canonical
63category_id: image
64summary: Check the model brand-id is canoncial
65description:
66 For the certification of IoT devices canonical provided generic images must
67 be used. Hence, the brand-id must be canonical.
68plugin: shell
69command:
70 ubuntucore_image_checks.py model-brand
71estimated_duration: 2.0
72flags: preserve-locale
0\ No newline at end of file73\ No newline at end of file
diff --git a/units/image/test-plan.pxu b/units/image/test-plan.pxu
1new file mode 10064474new file mode 100644
index 0000000..48af204
--- /dev/null
+++ b/units/image/test-plan.pxu
@@ -0,0 +1,20 @@
1
2id: iot-cert-image-full
3unit: test plan
4name: Sanity checks for images being certified on IoT devices
5include:
6nested_part:
7 iot-cert-image-manual
8 iot-cert-image-automated
9
10id: iot-cert-image-automated
11unit: test plan
12name: Automated Sanity checks for images being certified on IoT devices
13include:
14 image/.*
15
16id: iot-cert-image-manual
17unit: test plan
18name: Manual Sanity checks for images being certified on IoT devices
19include:
20

Subscribers

People subscribed via source and target branches