Merge ~jocave/checkbox-support:improved-assertion-parsing into checkbox-support:master
- Git
- lp:~jocave/checkbox-support
- improved-assertion-parsing
- Merge into master
Status: | Merged |
---|---|
Approved by: | Jonathan Cave |
Approved revision: | 58435e249f5cd325465f00417369dc226083c1a9 |
Merged at revision: | afa6910c4b69dd8d6e7d1c2ae5d2aadfe820e84c |
Proposed branch: | ~jocave/checkbox-support:improved-assertion-parsing |
Merge into: | checkbox-support:master |
Diff against target: |
442 lines (+338/-31) 7 files modified
checkbox_support/snap_utils/asserts.py (+69/-0) checkbox_support/snap_utils/system.py (+16/-31) checkbox_support/snap_utils/tests/asserts_data/MODEL_FOCAL_DESKTOP.txt (+19/-0) checkbox_support/snap_utils/tests/asserts_data/MODEL_UC18.txt (+23/-0) checkbox_support/snap_utils/tests/asserts_data/MODEL_UC20.txt (+43/-0) checkbox_support/snap_utils/tests/asserts_data/SERIAL_FOCAL_DESKTOP.txt (+30/-0) checkbox_support/snap_utils/tests/test_asserts.py (+138/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Devices Certification Bot | Needs Fixing | ||
Sylvain Pineau (community) | Approve | ||
Maciej Kisielewski | Approve | ||
Review via email: mp+391270@code.launchpad.net |
Commit message
Description of the change
Given model assertions created for UC20 have a different format to previous series there was a need to rework the previous simplistic parsing functions. They previously existed in a couple of places where tests (snapd resource, fde tests) used them to identify information about the system.
This makes the parsing somewhat less crude and located in checkbox-support for reuse.
Sheila Miguez (codersquid) wrote : | # |
Sheila Miguez (codersquid) wrote : | # |
I have a few minor questions.
Jonathan Cave (jocave) wrote : | # |
Pushed fixes for spelling mistakes
Jonathan Cave (jocave) : | # |
Sheila Miguez (codersquid) wrote : | # |
lgtm but maybe wait to see if maciej or spineau have any comments?
Maciej Kisielewski (kissiel) wrote : | # |
I like the heuristics. I like the tests. I like the code. +1 :)
Minor nitpicks inline below.
Jonathan Cave (jocave) wrote : | # |
Squashed the addition of a docstring in to the first commit
Sylvain Pineau (sylvain-pineau) wrote : | # |
Nice use of yaml here. +1 (and I also like the tests!)
Devices Certification Bot (ce-certification-qa) wrote : | # |
The merge was fine but running tests failed.
[xenial] [14:40:53] starting container
Device project added to xenial-testing
[focal] [14:40:58] starting container
Device project added to focal-testing
[xenial] [14:41:04] provisioning container
[focal] [14:41:12] provisioning container
[focal] [14:41:26] Starting tests...
[focal] Found a test script: ./requirements/
[xenial] [14:41:29] Starting tests...
[xenial] Found a test script: ./requirements/
[focal] [14:42:10] container-
[focal] [14:42:10] Fixing file permissions in source directory
[focal] [14:42:10] Destroying container
[xenial] [14:42:13] container-
[xenial] output: https:/
[xenial] [14:42:17] Fixing file permissions in source directory
[xenial] [14:42:18] Destroying container
[bionic] [14:42:26] starting container
Device project added to bionic-testing
[bionic] [14:42:39] provisioning container
[bionic] [14:42:57] Starting tests...
[bionic] Found a test script: ./requirements/
[bionic] [14:43:45] container-
[bionic] output: https:/
[bionic] [14:43:48] Fixing file permissions in source directory
[bionic] [14:43:48] Destroying container
Preview Diff
1 | diff --git a/checkbox_support/snap_utils/asserts.py b/checkbox_support/snap_utils/asserts.py | |||
2 | 0 | new file mode 100644 | 0 | new file mode 100644 |
3 | index 0000000..1569b22 | |||
4 | --- /dev/null | |||
5 | +++ b/checkbox_support/snap_utils/asserts.py | |||
6 | @@ -0,0 +1,69 @@ | |||
7 | 1 | # Copyright 2020 Canonical Ltd. | ||
8 | 2 | # All rights reserved. | ||
9 | 3 | # | ||
10 | 4 | # Written by: | ||
11 | 5 | # Jonathan Cave <jonathan.cave@canonical.com> | ||
12 | 6 | |||
13 | 7 | import yaml | ||
14 | 8 | |||
15 | 9 | |||
16 | 10 | def decode(assertion_stream): | ||
17 | 11 | """Generate individual assertions in yaml format from a stream. | ||
18 | 12 | |||
19 | 13 | Multiple assertions are identified in the stream by a double empty line as | ||
20 | 14 | per the REST API documentation. Signatures are not verified and removed | ||
21 | 15 | so any data returned should be used only for informational purposes. | ||
22 | 16 | """ | ||
23 | 17 | count = int(assertion_stream.headers['X-Ubuntu-Assertions-Count']) | ||
24 | 18 | if count > 0: | ||
25 | 19 | # split in to individual assertions | ||
26 | 20 | for assertion in assertion_stream.text.split('\n\n\n\n'): | ||
27 | 21 | # split to remove signature | ||
28 | 22 | content = assertion.split('\n\n')[0] | ||
29 | 23 | if int(yaml.__version__.split('.')[0]) < 5: | ||
30 | 24 | yield yaml.load(content) | ||
31 | 25 | else: | ||
32 | 26 | yield yaml.load(content, Loader=yaml.FullLoader) | ||
33 | 27 | |||
34 | 28 | |||
35 | 29 | def model_to_resource(model_assertion): | ||
36 | 30 | """ Convert assertion yaml to flat dict for resource output.""" | ||
37 | 31 | resource = {} | ||
38 | 32 | # list keys that can just be copied over | ||
39 | 33 | wanted_keys = ('type', 'authority-id', 'brand-id', 'model', 'architecture', | ||
40 | 34 | 'base', 'grade', 'sign-key-sha3-384') | ||
41 | 35 | for key, val in model_assertion.items(): | ||
42 | 36 | if key in wanted_keys: | ||
43 | 37 | resource[key] = val | ||
44 | 38 | # handle other more complicated keys | ||
45 | 39 | if 'grade' in model_assertion: | ||
46 | 40 | # is in UC20 format | ||
47 | 41 | resource['grade'] = model_assertion.get('grade') | ||
48 | 42 | for snap in model_assertion['snaps']: | ||
49 | 43 | if snap['type'] in ('kernel', 'gadget'): | ||
50 | 44 | resource[snap['type']] = snap['name'] | ||
51 | 45 | resource['{}_track'.format( | ||
52 | 46 | snap['type'])] = snap['default-channel'] | ||
53 | 47 | else: | ||
54 | 48 | # older formats | ||
55 | 49 | for key in ('kernel', 'gadget'): | ||
56 | 50 | val = model_assertion.get(key) | ||
57 | 51 | if '=' in val: | ||
58 | 52 | snap, track = [x.strip() for x in val.split('=')] | ||
59 | 53 | resource[key] = snap | ||
60 | 54 | resource['{}_track'.format(key)] = track | ||
61 | 55 | else: | ||
62 | 56 | resource[key] = val | ||
63 | 57 | return resource | ||
64 | 58 | |||
65 | 59 | |||
66 | 60 | def serial_to_resource(serial_assertion): | ||
67 | 61 | """ Convert assertion yaml to flat dict for resource output.""" | ||
68 | 62 | resource = {} | ||
69 | 63 | # list keys that can just be copied over | ||
70 | 64 | wanted_keys = ('type', 'authority-id', 'brand-id', 'model', 'serial', | ||
71 | 65 | 'sign-key-sha3-384') | ||
72 | 66 | for key, val in serial_assertion.items(): | ||
73 | 67 | if key in wanted_keys: | ||
74 | 68 | resource[key] = val | ||
75 | 69 | return resource | ||
76 | diff --git a/checkbox_support/snap_utils/system.py b/checkbox_support/snap_utils/system.py | |||
77 | index 8086a4b..1c029d1 100644 | |||
78 | --- a/checkbox_support/snap_utils/system.py | |||
79 | +++ b/checkbox_support/snap_utils/system.py | |||
80 | @@ -4,7 +4,6 @@ | |||
81 | 4 | # Written by: | 4 | # Written by: |
82 | 5 | # Jonathan Cave <jonathan.cave@canonical.com> | 5 | # Jonathan Cave <jonathan.cave@canonical.com> |
83 | 6 | 6 | ||
84 | 7 | import io | ||
85 | 8 | import os | 7 | import os |
86 | 9 | import re | 8 | import re |
87 | 10 | import subprocess as sp | 9 | import subprocess as sp |
88 | @@ -13,6 +12,8 @@ import yaml | |||
89 | 13 | import distro | 12 | import distro |
90 | 14 | 13 | ||
91 | 15 | from checkbox_support.parsers.kernel_cmdline import parse_kernel_cmdline | 14 | from checkbox_support.parsers.kernel_cmdline import parse_kernel_cmdline |
92 | 15 | from checkbox_support.snap_utils.asserts import decode | ||
93 | 16 | from checkbox_support.snap_utils.asserts import model_to_resource | ||
94 | 16 | from checkbox_support.snap_utils.snapd import Snapd | 17 | from checkbox_support.snap_utils.snapd import Snapd |
95 | 17 | 18 | ||
96 | 18 | 19 | ||
97 | @@ -28,44 +29,28 @@ def in_classic_snap(): | |||
98 | 28 | snap = os.getenv("SNAP") | 29 | snap = os.getenv("SNAP") |
99 | 29 | if snap: | 30 | if snap: |
100 | 30 | with open(os.path.join(snap, 'meta/snap.yaml')) as f: | 31 | with open(os.path.join(snap, 'meta/snap.yaml')) as f: |
103 | 31 | for l in f.readlines(): | 32 | for line in f.readlines(): |
104 | 32 | if l == "confinement: classic\n": | 33 | if line == "confinement: classic\n": |
105 | 33 | return True | 34 | return True |
106 | 34 | return False | 35 | return False |
107 | 35 | 36 | ||
108 | 36 | 37 | ||
109 | 37 | def get_kernel_snap(): | 38 | def get_kernel_snap(): |
124 | 38 | snap = None | 39 | model = next(decode(Snapd().get_assertions('model')), None) |
125 | 39 | assertion_stream = Snapd().get_assertions('model') | 40 | if model: |
126 | 40 | count = int(assertion_stream.headers['X-Ubuntu-Assertions-Count']) | 41 | # convert to resource to handle presence of track info |
127 | 41 | if count > 0: | 42 | resource = model_to_resource(model) |
128 | 42 | for line in io.StringIO(assertion_stream.text): | 43 | return resource.get('kernel') |
129 | 43 | if line.count(':') == 1: | 44 | return None |
116 | 44 | key, val = [x.strip() for x in line.split(':')] | ||
117 | 45 | if key == 'kernel': | ||
118 | 46 | if '=' in val: | ||
119 | 47 | snap, _ = [x.strip() for x in val.split('=')] | ||
120 | 48 | else: | ||
121 | 49 | snap = val | ||
122 | 50 | break | ||
123 | 51 | return snap | ||
130 | 52 | 45 | ||
131 | 53 | 46 | ||
132 | 54 | def get_gadget_snap(): | 47 | def get_gadget_snap(): |
147 | 55 | snap = None | 48 | model = next(decode(Snapd().get_assertions('model')), None) |
148 | 56 | assertion_stream = Snapd().get_assertions('model') | 49 | if model: |
149 | 57 | count = int(assertion_stream.headers['X-Ubuntu-Assertions-Count']) | 50 | # convert to resource to handle presence of track info |
150 | 58 | if count > 0: | 51 | resource = model_to_resource(model) |
151 | 59 | for line in io.StringIO(assertion_stream.text): | 52 | return resource.get('gadget') |
152 | 60 | if line.count(':') == 1: | 53 | return None |
139 | 61 | key, val = [x.strip() for x in line.split(':')] | ||
140 | 62 | if key == 'gadget': | ||
141 | 63 | if '=' in val: | ||
142 | 64 | snap, _ = [x.strip() for x in val.split('=')] | ||
143 | 65 | else: | ||
144 | 66 | snap = val | ||
145 | 67 | break | ||
146 | 68 | return snap | ||
153 | 69 | 54 | ||
154 | 70 | 55 | ||
155 | 71 | def get_bootloader(): | 56 | def get_bootloader(): |
156 | diff --git a/checkbox_support/snap_utils/tests/asserts_data/MODEL_FOCAL_DESKTOP.txt b/checkbox_support/snap_utils/tests/asserts_data/MODEL_FOCAL_DESKTOP.txt | |||
157 | 72 | new file mode 100644 | 57 | new file mode 100644 |
158 | index 0000000..c16f1b3 | |||
159 | --- /dev/null | |||
160 | +++ b/checkbox_support/snap_utils/tests/asserts_data/MODEL_FOCAL_DESKTOP.txt | |||
161 | @@ -0,0 +1,19 @@ | |||
162 | 1 | type: model | ||
163 | 2 | authority-id: generic | ||
164 | 3 | series: 16 | ||
165 | 4 | brand-id: generic | ||
166 | 5 | model: generic-classic | ||
167 | 6 | classic: true | ||
168 | 7 | timestamp: 2017-07-27T00:00:00.0Z | ||
169 | 8 | sign-key-sha3-384: d-JcZF9nD9eBw7bwMnH61x-bklnQOhQud1Is6o_cn2wTj8EYDi9musrIT9z2MdAa | ||
170 | 9 | |||
171 | 10 | AcLBXAQAAQoABgUCWYuXiAAKCRAdLQyY+/mCiST0D/0XGQauzV2bbTEy6DkrR1jlNbI6x8vfIdS8 | ||
172 | 11 | KvEWYvzOWNhNlVSfwNOkFjs3uMHgCO6/fCg03wGXTyV9D7ZgrMeUzWrYp6EmXk8/LQSaBnff86XO | ||
173 | 12 | 4/vYyfyvEYavhF0kQ6QGg8Cqr0EaMyw0x9/zWEO/Ll9fH/8nv9qcQq8N4AbebNvNxtGsCmJuXpSe | ||
174 | 13 | 2rxl3Dw8XarYBmqgcBQhXxRNpa6/AgaTNBpPOTqgNA8ZtmbZwYLuaFjpZP410aJSs+evSKepy/ce | ||
175 | 14 | +zTA7RB3384YQVeZDdTudX2fGtuCnBZBAJ+NYlk0t8VFXxyOhyMSXeylSpNSx4pCqmUZRyaf5SDS | ||
176 | 15 | g1XxJet4IP0stZH1SfPOwc9oE81/bJlKsb9QIQKQRewvtUCLfe9a6Vy/CYd2elvcWOmeANVrJK0m | ||
177 | 16 | nRaz6VBm09RJTuwUT6vNugXSOCeF7W3WN1RHJuex0zw+nP3eCehxFSr33YrVniaA7zGfjXvS8tKx | ||
178 | 17 | AINNQB4g2fpfet4na6lPPMYM41WHIHPCMTz/fJQ6dZBSEg6UUZ/GiQhGEfWPBteK7yd9pQ8qB3fj | ||
179 | 18 | ER4UvKnR7hcVI26e3NGNkXP5kp0SFCkV5NQs8rzXzokpB7p/V5Pnqp3Km6wu45cU6UiTZFhR2IMT | ||
180 | 19 | l+6AMtrS4gDGHktOhwfmOMWqmhvR/INF+TjaWbsB6g== | ||
181 | 0 | \ No newline at end of file | 20 | \ No newline at end of file |
182 | diff --git a/checkbox_support/snap_utils/tests/asserts_data/MODEL_UC18.txt b/checkbox_support/snap_utils/tests/asserts_data/MODEL_UC18.txt | |||
183 | 1 | new file mode 100644 | 21 | new file mode 100644 |
184 | index 0000000..b213dc4 | |||
185 | --- /dev/null | |||
186 | +++ b/checkbox_support/snap_utils/tests/asserts_data/MODEL_UC18.txt | |||
187 | @@ -0,0 +1,23 @@ | |||
188 | 1 | type: model | ||
189 | 2 | authority-id: canonical | ||
190 | 3 | series: 16 | ||
191 | 4 | brand-id: canonical | ||
192 | 5 | model: ubuntu-core-18-amd64 | ||
193 | 6 | architecture: amd64 | ||
194 | 7 | base: core18 | ||
195 | 8 | display-name: Ubuntu Core 18 (amd64) | ||
196 | 9 | gadget: pc=18 | ||
197 | 10 | kernel: pc-kernel=18 | ||
198 | 11 | timestamp: 2018-08-13T09:00:00+00:00 | ||
199 | 12 | sign-key-sha3-384: 9tydnLa6MTJ-jaQTFUXEwHl1yRx7ZS4K5cyFDhYDcPzhS7uyEkDxdUjg9g08BtNn | ||
200 | 13 | |||
201 | 14 | AcLBXAQAAQoABgUCW37NBwAKCRDgT5vottzAEut9D/4u9lD3lFWXoHx1VQT+mUCROcFHdXQBY/PJ | ||
202 | 15 | NriRiDwBaOjEo5mvHMRJ2UulWvHnwqyMJctJKBP+RCKlrJEPX8eaLP/lmihwIiFfmzm49BLaNwli | ||
203 | 16 | si0entond1sVWfiNr7azXoEuAIgYvxmJIvE+GZADDT0/OTFQRcLU69bhNEAQKBnkT0y/HTpuXwlJ | ||
204 | 17 | TuwwJtDR0vZuFtwzj6Bdx7W42+vGmuXE7M4Ni6HUySNKYByB5BsrDf3/79p8huXyBtnWp+HBsHtb | ||
205 | 18 | fgjzQoBcspj65Gi+crBrJ4jS+nfowRRVXLL1clXJOJLz12za+kN0/FC0PhussiQb5UI7USXJ+RvA | ||
206 | 19 | Y8U1vrqG7bG5GYGqe1KB9GbLEm+GBPQZcZI3jRmm9V7tm9OWQzK98/uPwTD73IW7LrDT35WQrIYM | ||
207 | 20 | fBfThJcRqpgzwZD/CBx82maLB9tmsRF5Mhcj2H1v7cn8nSkbv7+cCzh25lKv48Vqz1WTgO3HMPWW | ||
208 | 21 | 0kb6BSoC+YGpstSUslqtpLdY/MfFI0DhshH2Y+h0c9/g4mux/Zb8Gs9V55HGn9mr2KKDmHsU2k+C | ||
209 | 22 | maZWcXOxRpverZ2Pi9L4fZxhZ9H+FDcMGiHn2vJFQhI3u+LiK3aUUAov4k3vNRPGSvi1AGhuEtUa | ||
210 | 23 | NG54bznx12KgOT3+YiHtfE95WiXUcJUrEXAgfVBVoA== | ||
211 | 0 | \ No newline at end of file | 24 | \ No newline at end of file |
212 | diff --git a/checkbox_support/snap_utils/tests/asserts_data/MODEL_UC20.txt b/checkbox_support/snap_utils/tests/asserts_data/MODEL_UC20.txt | |||
213 | 1 | new file mode 100644 | 25 | new file mode 100644 |
214 | index 0000000..ee19f86 | |||
215 | --- /dev/null | |||
216 | +++ b/checkbox_support/snap_utils/tests/asserts_data/MODEL_UC20.txt | |||
217 | @@ -0,0 +1,43 @@ | |||
218 | 1 | type: model | ||
219 | 2 | authority-id: canonical | ||
220 | 3 | revision: 1 | ||
221 | 4 | series: 16 | ||
222 | 5 | brand-id: canonical | ||
223 | 6 | model: ubuntu-core-20-amd64-dangerous | ||
224 | 7 | architecture: amd64 | ||
225 | 8 | base: core20 | ||
226 | 9 | grade: dangerous | ||
227 | 10 | snaps: | ||
228 | 11 | - | ||
229 | 12 | default-channel: 20/edge | ||
230 | 13 | id: UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH | ||
231 | 14 | name: pc | ||
232 | 15 | type: gadget | ||
233 | 16 | - | ||
234 | 17 | default-channel: 20/edge | ||
235 | 18 | id: pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza | ||
236 | 19 | name: pc-kernel | ||
237 | 20 | type: kernel | ||
238 | 21 | - | ||
239 | 22 | default-channel: latest/edge | ||
240 | 23 | id: DLqre5XGLbDqg9jPtiAhRRjDuPVa5X1q | ||
241 | 24 | name: core20 | ||
242 | 25 | type: base | ||
243 | 26 | - | ||
244 | 27 | default-channel: latest/edge | ||
245 | 28 | id: PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4 | ||
246 | 29 | name: snapd | ||
247 | 30 | type: snapd | ||
248 | 31 | timestamp: 2020-04-29T11:18:00.0Z | ||
249 | 32 | sign-key-sha3-384: 9tydnLa6MTJ-jaQTFUXEwHl1yRx7ZS4K5cyFDhYDcPzhS7uyEkDxdUjg9g08BtNn | ||
250 | 33 | |||
251 | 34 | AcLBXAQAAQoABgUCWYuXiAAKCRAdLQyY+/mCiST0D/0XGQauzV2bbTEy6DkrR1jlNbI6x8vfIdS8 | ||
252 | 35 | KvEWYvzOWNhNlVSfwNOkFjs3uMHgCO6/fCg03wGXTyV9D7ZgrMeUzWrYp6EmXk8/LQSaBnff86XO | ||
253 | 36 | 4/vYyfyvEYavhF0kQ6QGg8Cqr0EaMyw0x9/zWEO/Ll9fH/8nv9qcQq8N4AbebNvNxtGsCmJuXpSe | ||
254 | 37 | 2rxl3Dw8XarYBmqgcBQhXxRNpa6/AgaTNBpPOTqgNA8ZtmbZwYLuaFjpZP410aJSs+evSKepy/ce | ||
255 | 38 | +zTA7RB3384YQVeZDdTudX2fGtuCnBZBAJ+NYlk0t8VFXxyOhyMSXeylSpNSx4pCqmUZRyaf5SDS | ||
256 | 39 | g1XxJet4IP0stZH1SfPOwc9oE81/bJlKsb9QIQKQRewvtUCLfe9a6Vy/CYd2elvcWOmeANVrJK0m | ||
257 | 40 | nRaz6VBm09RJTuwUT6vNugXSOCeF7W3WN1RHJuex0zw+nP3eCehxFSr33YrVniaA7zGfjXvS8tKx | ||
258 | 41 | AINNQB4g2fpfet4na6lPPMYM41WHIHPCMTz/fJQ6dZBSEg6UUZ/GiQhGEfWPBteK7yd9pQ8qB3fj | ||
259 | 42 | ER4UvKnR7hcVI26e3NGNkXP5kp0SFCkV5NQs8rzXzokpB7p/V5Pnqp3Km6wu45cU6UiTZFhR2IMT | ||
260 | 43 | l+6AMtrS4gDGHktOhwfmOMWqmhvR/INF+TjaWbsB6g== | ||
261 | 0 | \ No newline at end of file | 44 | \ No newline at end of file |
262 | diff --git a/checkbox_support/snap_utils/tests/asserts_data/SERIAL_FOCAL_DESKTOP.txt b/checkbox_support/snap_utils/tests/asserts_data/SERIAL_FOCAL_DESKTOP.txt | |||
263 | 1 | new file mode 100644 | 45 | new file mode 100644 |
264 | index 0000000..c42add8 | |||
265 | --- /dev/null | |||
266 | +++ b/checkbox_support/snap_utils/tests/asserts_data/SERIAL_FOCAL_DESKTOP.txt | |||
267 | @@ -0,0 +1,30 @@ | |||
268 | 1 | type: serial | ||
269 | 2 | authority-id: generic | ||
270 | 3 | brand-id: generic | ||
271 | 4 | model: generic-classic | ||
272 | 5 | serial: 12345678-1234-1234-1234-b4f4dc4a1f9a | ||
273 | 6 | device-key: | ||
274 | 7 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
275 | 8 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
276 | 9 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
277 | 10 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
278 | 11 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
279 | 12 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
280 | 13 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
281 | 14 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
282 | 15 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
283 | 16 | AAAAAAAAAAAAAAAAAAAAAAAA | ||
284 | 17 | device-key-sha3-384: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
285 | 18 | timestamp: 2020-03-03T16:27:34.048105Z | ||
286 | 19 | sign-key-sha3-384: wrfougkz3Huq2T_KklfnufCC0HzG7bJ9wP99GV0FF-D3QH3eJtuSRlQc2JhrAoh1 | ||
287 | 20 | |||
288 | 21 | AcLBUgQAAQoABgUCXl6FdgAAtGsQAHSDiPo5MmtZt/Itv0dD2BR+eZ4D66SzzGLUPJv5wa8G1Ji2 | ||
289 | 22 | SIQ1MyzthyN+1vOPF3etkrHMB4wtPnpRK84E1Yfl3P7XfiKVBI46PNxx/o7BknH2iMxckhELM9jT | ||
290 | 23 | sbUFQDfOrif9NEG2GrAzG7WTaSfxVfF3aNMC1BelCbBbB0C33nf8YaiOWATT5PNG+ynDvDLSKB2M | ||
291 | 24 | BQn2V7KWrBXQw7oZoZCG/Ct1OVifACoi3/u/ceN4qzzIpQz40hoImwnuJoMGAxwqUcnbesQYmT4b | ||
292 | 25 | s+EZ+vtLMoyh99AM6TbEif/qmGTi3Otm8RGqqBADLUSypEquAVUcxmr/P3Cn6MvfDalcCSx3VH3Q | ||
293 | 26 | NO0Fs3phnpJQszXEGwi7FnLyql6H7b/zAtUriBkEjIfwGby5gOEavyOpwQ5JPblt3PKnhZ9Quh2B | ||
294 | 27 | eZzcjdElAP6OjQlCk9mSlNOErrpWFTRdOQnn6B4ZBql773rsAQXMwm/9FZURJpzJ7oYkLIUJmcQo | ||
295 | 28 | /WACY5ht45+fG+76mToHLOWlFS0IPNGuKTAaMrrkc2LvfE+rdGMgmGD7TnqjEoUAQsVsjvbykcGe | ||
296 | 29 | Sp7zj/42BdXpmHP/MCOjM3J9DPMKpEvsw4X8DdS/4p1AdK3qFaT5l3emKzoodfHwEp1IO30FQUDB | ||
297 | 30 | QOddARNK0QkdYwo4Kj0FpMKxyTOW | ||
298 | 0 | \ No newline at end of file | 31 | \ No newline at end of file |
299 | diff --git a/checkbox_support/snap_utils/tests/test_asserts.py b/checkbox_support/snap_utils/tests/test_asserts.py | |||
300 | 1 | new file mode 100644 | 32 | new file mode 100644 |
301 | index 0000000..741a101 | |||
302 | --- /dev/null | |||
303 | +++ b/checkbox_support/snap_utils/tests/test_asserts.py | |||
304 | @@ -0,0 +1,138 @@ | |||
305 | 1 | # Copyright 2020 Canonical Ltd. | ||
306 | 2 | # All rights reserved. | ||
307 | 3 | # | ||
308 | 4 | # Written by: | ||
309 | 5 | # Jonathan Cave <jonathan.cave@canonical.com> | ||
310 | 6 | |||
311 | 7 | from requests.models import Response | ||
312 | 8 | import unittest | ||
313 | 9 | from unittest.mock import Mock | ||
314 | 10 | |||
315 | 11 | from pkg_resources import resource_filename | ||
316 | 12 | |||
317 | 13 | from checkbox_support.snap_utils.asserts import decode | ||
318 | 14 | from checkbox_support.snap_utils.asserts import model_to_resource | ||
319 | 15 | from checkbox_support.snap_utils.asserts import serial_to_resource | ||
320 | 16 | |||
321 | 17 | model_focal_desktop = 'snap_utils/tests/asserts_data/MODEL_FOCAL_DESKTOP.txt' | ||
322 | 18 | serial_focal_desktop = 'snap_utils/tests/asserts_data/SERIAL_FOCAL_DESKTOP.txt' | ||
323 | 19 | model_uc18 = 'snap_utils/tests/asserts_data/MODEL_UC18.txt' | ||
324 | 20 | model_uc20 = 'snap_utils/tests/asserts_data/MODEL_UC20.txt' | ||
325 | 21 | |||
326 | 22 | |||
327 | 23 | def create_mock_response(assert_path): | ||
328 | 24 | mock_response = Mock(spec=Response) | ||
329 | 25 | mock_response.status_code = 400 | ||
330 | 26 | mock_response.headers = {'X-Ubuntu-Assertions-Count': 1} | ||
331 | 27 | with open(resource_filename('checkbox_support', assert_path), 'r') as f: | ||
332 | 28 | mock_response.text = f.read() | ||
333 | 29 | return mock_response | ||
334 | 30 | |||
335 | 31 | |||
336 | 32 | class TestModelAsserts(unittest.TestCase): | ||
337 | 33 | |||
338 | 34 | def test_decode_focal(self): | ||
339 | 35 | assertion_stream = create_mock_response(model_focal_desktop) | ||
340 | 36 | iter = decode(assertion_stream) | ||
341 | 37 | a = next(iter) | ||
342 | 38 | self.assertIn('type', a) | ||
343 | 39 | self.assertEqual(a['type'], 'model') | ||
344 | 40 | self.assertIn('model', a) | ||
345 | 41 | self.assertEqual(a['model'], 'generic-classic') | ||
346 | 42 | with self.assertRaises(StopIteration): | ||
347 | 43 | next(iter) | ||
348 | 44 | |||
349 | 45 | def test_decode_uc18(self): | ||
350 | 46 | assertion_stream = create_mock_response(model_uc18) | ||
351 | 47 | iter = decode(assertion_stream) | ||
352 | 48 | a = next(iter) | ||
353 | 49 | self.assertIn('type', a) | ||
354 | 50 | self.assertEqual(a['type'], 'model') | ||
355 | 51 | self.assertIn('model', a) | ||
356 | 52 | self.assertEqual(a['model'], 'ubuntu-core-18-amd64') | ||
357 | 53 | with self.assertRaises(StopIteration): | ||
358 | 54 | next(iter) | ||
359 | 55 | |||
360 | 56 | def test_decode_uc20(self): | ||
361 | 57 | assertion_stream = create_mock_response(model_uc20) | ||
362 | 58 | iter = decode(assertion_stream) | ||
363 | 59 | a = next(iter) | ||
364 | 60 | self.assertIn('type', a) | ||
365 | 61 | self.assertEqual(a['type'], 'model') | ||
366 | 62 | self.assertIn('model', a) | ||
367 | 63 | self.assertEqual(a['model'], 'ubuntu-core-20-amd64-dangerous') | ||
368 | 64 | with self.assertRaises(StopIteration): | ||
369 | 65 | next(iter) | ||
370 | 66 | |||
371 | 67 | def test_model_to_resource_uc18(self): | ||
372 | 68 | assertion_stream = create_mock_response(model_uc18) | ||
373 | 69 | iter = decode(assertion_stream) | ||
374 | 70 | a = next(iter) | ||
375 | 71 | correct_resource = { | ||
376 | 72 | 'type': 'model', | ||
377 | 73 | 'authority-id': 'canonical', | ||
378 | 74 | 'brand-id': 'canonical', | ||
379 | 75 | 'model': 'ubuntu-core-18-amd64', | ||
380 | 76 | 'architecture': 'amd64', | ||
381 | 77 | 'base': 'core18', | ||
382 | 78 | 'sign-key-sha3-384': '9tydnLa6MTJ-jaQTFUXEwHl1yRx7ZS4K5cyFDhYDcPzhS7uyEkDxdUjg9g08BtNn', | ||
383 | 79 | 'kernel': 'pc-kernel', | ||
384 | 80 | 'kernel_track': '18', | ||
385 | 81 | 'gadget': 'pc', | ||
386 | 82 | 'gadget_track': '18' | ||
387 | 83 | } | ||
388 | 84 | self.assertDictEqual(correct_resource, model_to_resource(a)) | ||
389 | 85 | with self.assertRaises(StopIteration): | ||
390 | 86 | next(iter) | ||
391 | 87 | |||
392 | 88 | def test_model_to_resource_uc20(self): | ||
393 | 89 | assertion_stream = create_mock_response(model_uc20) | ||
394 | 90 | iter = decode(assertion_stream) | ||
395 | 91 | a = next(iter) | ||
396 | 92 | correct_resource = { | ||
397 | 93 | 'type': 'model', | ||
398 | 94 | 'authority-id': 'canonical', | ||
399 | 95 | 'brand-id': 'canonical', | ||
400 | 96 | 'model': 'ubuntu-core-20-amd64-dangerous', | ||
401 | 97 | 'architecture': 'amd64', | ||
402 | 98 | 'base': 'core20', | ||
403 | 99 | 'grade': 'dangerous', | ||
404 | 100 | 'sign-key-sha3-384': '9tydnLa6MTJ-jaQTFUXEwHl1yRx7ZS4K5cyFDhYDcPzhS7uyEkDxdUjg9g08BtNn', | ||
405 | 101 | 'gadget': 'pc', | ||
406 | 102 | 'gadget_track': '20/edge', | ||
407 | 103 | 'kernel': 'pc-kernel', | ||
408 | 104 | 'kernel_track': '20/edge' | ||
409 | 105 | } | ||
410 | 106 | self.assertDictEqual(correct_resource, model_to_resource(a)) | ||
411 | 107 | with self.assertRaises(StopIteration): | ||
412 | 108 | next(iter) | ||
413 | 109 | |||
414 | 110 | |||
415 | 111 | class TestSerialAsserts(unittest.TestCase): | ||
416 | 112 | |||
417 | 113 | def test_decode_focal(self): | ||
418 | 114 | assertion_stream = create_mock_response(serial_focal_desktop) | ||
419 | 115 | iter = decode(assertion_stream) | ||
420 | 116 | a = next(iter) | ||
421 | 117 | self.assertIn('type', a) | ||
422 | 118 | self.assertEqual(a['type'], 'serial') | ||
423 | 119 | self.assertIn('serial', a) | ||
424 | 120 | self.assertEqual(a['serial'], '12345678-1234-1234-1234-b4f4dc4a1f9a') | ||
425 | 121 | with self.assertRaises(StopIteration): | ||
426 | 122 | next(iter) | ||
427 | 123 | |||
428 | 124 | def test_serial_to_resource_focal(self): | ||
429 | 125 | assertion_stream = create_mock_response(serial_focal_desktop) | ||
430 | 126 | iter = decode(assertion_stream) | ||
431 | 127 | a = next(iter) | ||
432 | 128 | correct_resource = { | ||
433 | 129 | 'type': 'serial', | ||
434 | 130 | 'authority-id': 'generic', | ||
435 | 131 | 'brand-id': 'generic', | ||
436 | 132 | 'model': 'generic-classic', | ||
437 | 133 | 'serial': '12345678-1234-1234-1234-b4f4dc4a1f9a', | ||
438 | 134 | 'sign-key-sha3-384': 'wrfougkz3Huq2T_KklfnufCC0HzG7bJ9wP99GV0FF-D3QH3eJtuSRlQc2JhrAoh1' | ||
439 | 135 | } | ||
440 | 136 | self.assertDictEqual(correct_resource, serial_to_resource(a)) | ||
441 | 137 | with self.assertRaises(StopIteration): | ||
442 | 138 | next(iter) |
I noticed a typo while reading this. See inline.