Merge ~jslarraz/review-tools:initial-schema-support into review-tools:master
- Git
- lp:~jslarraz/review-tools
- initial-schema-support
- Merge into master
Proposed by
Jorge Sancho Larraz
Status: | Rejected |
---|---|
Rejected by: | Jorge Sancho Larraz |
Proposed branch: | ~jslarraz/review-tools:initial-schema-support |
Merge into: | review-tools:master |
Diff against target: |
534 lines (+223/-244) 6 files modified
reviewtools/schemas/snap.json (+14/-0) reviewtools/sr_lint.py (+22/-35) reviewtools/tests/schemas/test_schema_against_store.py (+76/-0) reviewtools/tests/schemas/test_schema_base.py (+44/-0) reviewtools/tests/schemas/test_schema_snap.py (+67/-0) reviewtools/tests/test_sr_lint.py (+0/-209) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jorge Sancho Larraz | Needs Fixing | ||
Review via email:
|
Commit message
Initial schema support
Description of the change
Set up the framework to verify snap.yaml via schema. Attributes will be included in the schema iteratively to make PR reasonable to review
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jorge Sancho Larraz (jslarraz) : | # |
review:
Needs Fixing
Unmerged commits
- e23df21... by Jorge Sancho Larraz
-
Initial schema support
-
test:0 (build) coverage:0 (build) 1 → 2 of 2 results First • Previous • Next • Last
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/reviewtools/schemas/snap.json b/reviewtools/schemas/snap.json |
2 | new file mode 100644 |
3 | index 0000000..3c239c4 |
4 | --- /dev/null |
5 | +++ b/reviewtools/schemas/snap.json |
6 | @@ -0,0 +1,14 @@ |
7 | +{ |
8 | + "description": "snap.yaml", |
9 | + "type": "object", |
10 | + "properties": { |
11 | + "name": { |
12 | + "description": "The identifying name of the snap.", |
13 | + "type": "string", |
14 | + "pattern": "^(?:[a-z0-9]|(?<=[a-z0-9])-)*[a-z](?:[a-z0-9]|-(?=[a-z0-9]))*$", |
15 | + "minLength": 2, |
16 | + "maxLength": 40 |
17 | + } |
18 | + }, |
19 | + "required": ["name"] |
20 | +} |
21 | diff --git a/reviewtools/sr_lint.py b/reviewtools/sr_lint.py |
22 | index c94340a..e1175e8 100644 |
23 | --- a/reviewtools/sr_lint.py |
24 | +++ b/reviewtools/sr_lint.py |
25 | @@ -18,8 +18,6 @@ from __future__ import print_function |
26 | from reviewtools.sr_common import SnapReview |
27 | from reviewtools.common import ( |
28 | find_external_symlinks, |
29 | - STORE_PKGNAME_SNAPV2_MAXLEN, |
30 | - STORE_PKGNAME_SNAPV2_MINLEN, |
31 | ) |
32 | from reviewtools.overrides import ( |
33 | redflagged_snap_types_overrides, |
34 | @@ -33,6 +31,8 @@ import os |
35 | import re |
36 | import shlex |
37 | import unicodedata |
38 | +import jsonschema |
39 | +import json |
40 | |
41 | |
42 | class SnapReviewLint(SnapReview): |
43 | @@ -77,6 +77,26 @@ class SnapReviewLint(SnapReview): |
44 | "test-snapd-refresh-control-base", |
45 | ] |
46 | |
47 | + def check_schema(self): |
48 | + """Check snap.yaml against the schema""" |
49 | + t = "info" |
50 | + n = self._get_check_name("snap_schema") |
51 | + s = "OK" |
52 | + manual_review = False |
53 | + |
54 | + with open("reviewtools/schemas/snap.json") as fd: |
55 | + schema = json.loads(fd.read()) |
56 | + |
57 | + try: |
58 | + jsonschema.validate(self.snap_yaml, schema) |
59 | + except jsonschema.ValidationError as e: |
60 | + t = "error" |
61 | + s = "Error found in snap.yaml while validating %s: %s" % ( |
62 | + e.json_path, |
63 | + e.message, |
64 | + ) |
65 | + self._add_result(t, n, s, manual_review=manual_review) |
66 | + |
67 | def check_architectures(self): |
68 | """Check architectures in snap.yaml is valid""" |
69 | t = "info" |
70 | @@ -175,39 +195,6 @@ class SnapReviewLint(SnapReview): |
71 | # snap/validate.go |
72 | self._check_description_summary_title("title", 40) |
73 | |
74 | - def check_name(self): |
75 | - """Check package name""" |
76 | - t = "info" |
77 | - n = self._get_check_name("name_valid") |
78 | - s = "OK" |
79 | - if "name" not in self.snap_yaml: |
80 | - t = "error" |
81 | - s = "could not find 'name' in yaml" |
82 | - elif not isinstance(self.snap_yaml["name"], str): |
83 | - t = "error" |
84 | - s = "malformed 'name': %s (not a str)" % (self.snap_yaml["name"]) |
85 | - elif len(self.snap_yaml["name"]) > STORE_PKGNAME_SNAPV2_MAXLEN: |
86 | - t = "error" |
87 | - s = ( |
88 | - "malformed 'name': '%s' " % self.snap_yaml["name"] |
89 | - + "(length '%d' " % len(self.snap_yaml["name"]) |
90 | - + "exceeds store limit '%d')" % STORE_PKGNAME_SNAPV2_MAXLEN |
91 | - ) |
92 | - elif len(self.snap_yaml["name"]) < STORE_PKGNAME_SNAPV2_MINLEN: |
93 | - t = "error" |
94 | - s = ( |
95 | - "malformed 'name': '%s' " % self.snap_yaml["name"] |
96 | - + "(length '%d' " % len(self.snap_yaml["name"]) |
97 | - + "below store limit '%d')" % STORE_PKGNAME_SNAPV2_MINLEN |
98 | - ) |
99 | - elif not self._verify_pkgname(self.snap_yaml["name"]): |
100 | - t = "error" |
101 | - s = ( |
102 | - "malformed 'name': '%s' " % self.snap_yaml["name"] |
103 | - + "(may be only lower case, digits and hyphens)" |
104 | - ) |
105 | - self._add_result(t, n, s) |
106 | - |
107 | def check_type(self): |
108 | """Check type""" |
109 | t = "info" |
110 | diff --git a/reviewtools/tests/schemas/test_schema_against_store.py b/reviewtools/tests/schemas/test_schema_against_store.py |
111 | new file mode 100644 |
112 | index 0000000..16259e2 |
113 | --- /dev/null |
114 | +++ b/reviewtools/tests/schemas/test_schema_against_store.py |
115 | @@ -0,0 +1,76 @@ |
116 | +from subprocess import run |
117 | +import json |
118 | +import yaml |
119 | +import os |
120 | +import sys |
121 | +import jsonschema |
122 | +import unittest |
123 | + |
124 | +SNAP_SCHEMA = "reviewtools/schemas/snap.json" |
125 | +SNAP_YAML_CACHE = os.path.expanduser("~/.cache/review-tools") |
126 | + |
127 | + |
128 | +@unittest.skipUnless( |
129 | + "TEST_SCHEMA_AGAINST_STORE" in os.environ, "not intended to be run by lpci" |
130 | +) |
131 | +def test_store(): |
132 | + # Create cache directory if it does not exist |
133 | + try: |
134 | + os.mkdir( |
135 | + SNAP_YAML_CACHE, |
136 | + ) |
137 | + except OSError: |
138 | + pass |
139 | + |
140 | + # Load schema |
141 | + with open(SNAP_SCHEMA) as fd: |
142 | + snap_schema = json.loads(fd.read()) |
143 | + |
144 | + # Get list of snaps in the store |
145 | + with open("/var/cache/snapd/names", "r") as fd: |
146 | + snaps = fd.readlines() |
147 | + |
148 | + rc = 0 |
149 | + for snap in snaps: |
150 | + snap = snap.strip("\n ") |
151 | + |
152 | + # Load the snap.yaml if cached, otherwise download it from the store |
153 | + snap_file = os.path.join(SNAP_YAML_CACHE, snap + "_yaml.json") |
154 | + if os.path.exists(snap_file): |
155 | + with open(snap_file) as fd: |
156 | + snap_yaml = json.loads(fd.read()) |
157 | + else: |
158 | + try: |
159 | + p = run( |
160 | + ["review-tools.store-query", "--snap-yaml", snap], |
161 | + capture_output=True, |
162 | + ) |
163 | + snap_yaml = yaml.safe_load(p.stdout.decode()) |
164 | + except Exception as e: |
165 | + print( |
166 | + "Error occurred while getting snap.yaml for %s: %s" % (snap, str(e)) |
167 | + ) |
168 | + continue |
169 | + |
170 | + with open(snap_file, "w") as fd: |
171 | + fd.write(json.dumps(snap_yaml)) |
172 | + |
173 | + # There are some snaps that has no snap.yaml. Skip them for now |
174 | + if snap_yaml is None: |
175 | + continue |
176 | + |
177 | + # Validate the snap.yaml against the schema |
178 | + try: |
179 | + jsonschema.validate(snap_yaml, snap_schema) |
180 | + except jsonschema.ValidationError as e: |
181 | + print( |
182 | + "Error to validate %s for snap %s: %s" % (e.json_path, snap, e.message) |
183 | + ) |
184 | + rc = 1 |
185 | + |
186 | + sys.exit(rc) |
187 | + |
188 | + |
189 | +if __name__ == "__main__": |
190 | + if os.environ.get("TEST_SCHEMA_AGAINST_STORE"): |
191 | + test_store() |
192 | diff --git a/reviewtools/tests/schemas/test_schema_base.py b/reviewtools/tests/schemas/test_schema_base.py |
193 | new file mode 100644 |
194 | index 0000000..b41f5dd |
195 | --- /dev/null |
196 | +++ b/reviewtools/tests/schemas/test_schema_base.py |
197 | @@ -0,0 +1,44 @@ |
198 | +import json |
199 | +import jsonschema |
200 | +import copy |
201 | +import unittest |
202 | + |
203 | + |
204 | +class TestSchemaBase(unittest.TestCase): |
205 | + yaml = {} |
206 | + schema_file = "reviewtools/schemas/****.json" |
207 | + |
208 | + def setUp(self): |
209 | + # Load the relevant schema (defined in subclass) |
210 | + with open(self.schema_file) as fd: |
211 | + self.schema = json.loads(fd.read()) |
212 | + |
213 | + # Validate base yaml against the schema |
214 | + error = self._validate(self.yaml, self.schema) |
215 | + self.assertEqual(None, error) |
216 | + |
217 | + def _validate(self, yaml, schema): |
218 | + # Validate yaml against the schema |
219 | + try: |
220 | + jsonschema.validate(yaml, schema) |
221 | + return None |
222 | + except jsonschema.ValidationError as e: |
223 | + return e.message |
224 | + |
225 | + def _test_value(self, key, value, expected_error): |
226 | + # Prepare yaml, make a copy so we use the pristine yaml on each subtest |
227 | + yaml = copy.deepcopy(self.yaml) |
228 | + if value is None: |
229 | + if key in yaml: |
230 | + del yaml[key] |
231 | + else: |
232 | + yaml[key] = value |
233 | + |
234 | + # Validate the schema |
235 | + error = self._validate(yaml, self.schema) |
236 | + |
237 | + # Compare the errors against the expected ones |
238 | + if expected_error is None: |
239 | + self.assertIsNone(error) |
240 | + else: |
241 | + self.assertIn(expected_error, error) |
242 | diff --git a/reviewtools/tests/schemas/test_schema_snap.py b/reviewtools/tests/schemas/test_schema_snap.py |
243 | new file mode 100644 |
244 | index 0000000..315b278 |
245 | --- /dev/null |
246 | +++ b/reviewtools/tests/schemas/test_schema_snap.py |
247 | @@ -0,0 +1,67 @@ |
248 | +from reviewtools.tests.schemas.test_schema_base import TestSchemaBase |
249 | + |
250 | + |
251 | +class TestSchemaSnap(TestSchemaBase): |
252 | + |
253 | + schema_file = "reviewtools/schemas/snap.json" |
254 | + |
255 | + def setUp(self): |
256 | + self.yaml = { |
257 | + "name": "foo", |
258 | + "version": "0.1", |
259 | + "type": "app", |
260 | + "description": "Test description", |
261 | + "summary": "Test summary", |
262 | + } |
263 | + super(TestSchemaSnap, self).setUp() |
264 | + |
265 | + def test_name(self): |
266 | + for value, error in [ |
267 | + # test_check_name_toplevel |
268 | + ("foo", None), |
269 | + # test_check_name_toplevel_startswith_number |
270 | + ("01game", None), |
271 | + # test_check_name_toplevel_maxlen_for_store |
272 | + ("a" * 40, None), |
273 | + # test_check_name_toplevel_minlen_for_store |
274 | + ("a" * 2, None), |
275 | + # test_check_name_toplevel_too_long_for_store |
276 | + ("a" * 41, "'{value}' is too long"), |
277 | + # test_check_name_toplevel_too_short_for_store |
278 | + ("a", "'{value}' is too short"), |
279 | + # test_check_name_toplevel_efficient |
280 | + ("u-94903713687486543234157734673284536758", None), |
281 | + # test_check_name_flat |
282 | + ("foo.bar", "'{value}' does not match "), |
283 | + # test_check_name_reverse_domain |
284 | + ("com.ubuntu.develeper.baz.foo", "'{value}' does not match "), |
285 | + # test_check_name_bad - ? |
286 | + ("foo?bar", "'{value}' does not match "), |
287 | + # test_check_name_bad1 - / |
288 | + ("foo/bar", "'{value}' does not match "), |
289 | + # test_check_name_bad2 - empty |
290 | + ("", "'{value}' does not match "), |
291 | + # test_check_name_bad3 - list |
292 | + ([], "{value} is not of type 'string'"), |
293 | + # test_check_name_bad4 - dict |
294 | + ({}, "{value} is not of type 'string'"), |
295 | + # test_check_name_bad5 - -- |
296 | + ("foo--bar", "'{value}' does not match "), |
297 | + # test_check_name_bad6 - endswith - |
298 | + ("foo-bar-", "'{value}' does not match "), |
299 | + # test_check_name_bad6b - startswith - |
300 | + ("-foo-bar", "'{value}' does not match "), |
301 | + # test_check_name_bad7 |
302 | + ("foo-Bar", "'{value}' does not match "), |
303 | + # test_check_name_bad8 - cap |
304 | + ("01", "'{value}' does not match "), |
305 | + # test_check_name_bad9 - all numbers and dashes |
306 | + ("0-1", "'{value}' does not match "), |
307 | + # test_check_name_missing |
308 | + (None, "'name' is a required property"), |
309 | + # ### integer |
310 | + (2, "{value} is not of type 'string'"), |
311 | + ]: |
312 | + with self.subTest(value=value): |
313 | + error = error.replace("{value}", str(value)) if error else error |
314 | + self._test_value("name", value, error) |
315 | diff --git a/reviewtools/tests/test_sr_lint.py b/reviewtools/tests/test_sr_lint.py |
316 | index 46f141c..d720017 100644 |
317 | --- a/reviewtools/tests/test_sr_lint.py |
318 | +++ b/reviewtools/tests/test_sr_lint.py |
319 | @@ -144,215 +144,6 @@ class TestSnapReviewLint(sr_tests.TestSnapReview): |
320 | sum += len(c.review_report[i]) |
321 | self.assertTrue(sum != 0) |
322 | |
323 | - def test_check_name_toplevel(self): |
324 | - """Test check_name - toplevel""" |
325 | - self.set_test_snap_yaml("name", "foo") |
326 | - c = SnapReviewLint(self.test_name) |
327 | - c.check_name() |
328 | - r = c.review_report |
329 | - expected_counts = {"info": 1, "warn": 0, "error": 0} |
330 | - self.check_results(r, expected_counts) |
331 | - |
332 | - def test_check_name_toplevel_startswith_number(self): |
333 | - """Test check_name - toplevel starts with number""" |
334 | - self.set_test_snap_yaml("name", "01game") |
335 | - c = SnapReviewLint(self.test_name) |
336 | - c.check_name() |
337 | - r = c.review_report |
338 | - expected_counts = {"info": 1, "warn": 0, "error": 0} |
339 | - self.check_results(r, expected_counts) |
340 | - |
341 | - def test_check_name_toplevel_maxlen_for_store(self): |
342 | - """Test check_name - toplevel maxlen for store""" |
343 | - self.set_test_snap_yaml("name", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40chars") |
344 | - c = SnapReviewLint(self.test_name) |
345 | - c.check_name() |
346 | - r = c.review_report |
347 | - expected_counts = {"info": 1, "warn": 0, "error": 0} |
348 | - self.check_results(r, expected_counts) |
349 | - |
350 | - def test_check_name_toplevel_minlen_for_store(self): |
351 | - """Test check_name - toplevel minlen for store""" |
352 | - self.set_test_snap_yaml("name", "aa") |
353 | - c = SnapReviewLint(self.test_name) |
354 | - c.check_name() |
355 | - r = c.review_report |
356 | - expected_counts = {"info": 1, "warn": 0, "error": 0} |
357 | - self.check_results(r, expected_counts) |
358 | - |
359 | - def test_check_name_toplevel_too_long_for_store(self): |
360 | - """Test check_name - toplevel too long for store""" |
361 | - self.set_test_snap_yaml("name", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41chars") |
362 | - c = SnapReviewLint(self.test_name) |
363 | - c.check_name() |
364 | - r = c.review_report |
365 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
366 | - self.check_results(r, expected_counts) |
367 | - |
368 | - expected = dict() |
369 | - expected["error"] = dict() |
370 | - expected["warn"] = dict() |
371 | - expected["info"] = dict() |
372 | - name = "lint-snap-v2:name_valid" |
373 | - expected["error"][name] = { |
374 | - "text": "malformed 'name': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41chars' (length '41' exceeds store limit '40')" |
375 | - } |
376 | - self.check_results(r, expected=expected) |
377 | - |
378 | - def test_check_name_toplevel_too_short_for_store(self): |
379 | - """Test check_name - toplevel too short for store""" |
380 | - self.set_test_snap_yaml("name", "a") |
381 | - c = SnapReviewLint(self.test_name) |
382 | - c.check_name() |
383 | - r = c.review_report |
384 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
385 | - self.check_results(r, expected_counts) |
386 | - |
387 | - expected = dict() |
388 | - expected["error"] = dict() |
389 | - expected["warn"] = dict() |
390 | - expected["info"] = dict() |
391 | - name = "lint-snap-v2:name_valid" |
392 | - expected["error"][name] = { |
393 | - "text": "malformed 'name': 'a' (length '1' below store limit '2')" |
394 | - } |
395 | - self.check_results(r, expected=expected) |
396 | - |
397 | - def test_check_name_toplevel_efficient(self): |
398 | - """Test check_name - toplevel is efficient""" |
399 | - self.set_test_snap_yaml("name", "u-94903713687486543234157734673284536758") |
400 | - c = SnapReviewLint(self.test_name) |
401 | - c.check_name() |
402 | - r = c.review_report |
403 | - expected_counts = {"info": 1, "warn": 0, "error": 0} |
404 | - self.check_results(r, expected_counts) |
405 | - |
406 | - def test_check_name_flat(self): |
407 | - """Test check_name - obsoleted flat""" |
408 | - self.set_test_snap_yaml("name", "foo.bar") |
409 | - c = SnapReviewLint(self.test_name) |
410 | - c.check_name() |
411 | - r = c.review_report |
412 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
413 | - self.check_results(r, expected_counts) |
414 | - |
415 | - def test_check_name_reverse_domain(self): |
416 | - """Test check_name - obsoleted reverse domain""" |
417 | - self.set_test_snap_yaml("name", "com.ubuntu.develeper.baz.foo") |
418 | - c = SnapReviewLint(self.test_name) |
419 | - c.check_name() |
420 | - r = c.review_report |
421 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
422 | - self.check_results(r, expected_counts) |
423 | - |
424 | - def test_check_name_bad(self): |
425 | - """Test check_name - bad - ?""" |
426 | - self.set_test_snap_yaml("name", "foo?bar") |
427 | - c = SnapReviewLint(self.test_name) |
428 | - c.check_name() |
429 | - r = c.review_report |
430 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
431 | - self.check_results(r, expected_counts) |
432 | - |
433 | - def test_check_name_bad1(self): |
434 | - """Test check_name - bad - /""" |
435 | - self.set_test_snap_yaml("name", "foo/bar") |
436 | - c = SnapReviewLint(self.test_name) |
437 | - c.check_name() |
438 | - r = c.review_report |
439 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
440 | - self.check_results(r, expected_counts) |
441 | - |
442 | - def test_check_name_bad2(self): |
443 | - """Test check_name - empty""" |
444 | - self.set_test_snap_yaml("name", "") |
445 | - c = SnapReviewLint(self.test_name) |
446 | - c.check_name() |
447 | - r = c.review_report |
448 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
449 | - self.check_results(r, expected_counts) |
450 | - |
451 | - def test_check_name_bad3(self): |
452 | - """Test check_name - list""" |
453 | - self.set_test_snap_yaml("name", []) |
454 | - c = SnapReviewLint(self.test_name) |
455 | - c.check_name() |
456 | - r = c.review_report |
457 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
458 | - self.check_results(r, expected_counts) |
459 | - |
460 | - def test_check_name_bad4(self): |
461 | - """Test check_name - dict""" |
462 | - self.set_test_snap_yaml("name", {}) |
463 | - c = SnapReviewLint(self.test_name) |
464 | - c.check_name() |
465 | - r = c.review_report |
466 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
467 | - self.check_results(r, expected_counts) |
468 | - |
469 | - def test_check_name_bad5(self): |
470 | - """Test check_name - bad - --""" |
471 | - self.set_test_snap_yaml("name", "foo--bar") |
472 | - c = SnapReviewLint(self.test_name) |
473 | - c.check_name() |
474 | - r = c.review_report |
475 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
476 | - self.check_results(r, expected_counts) |
477 | - |
478 | - def test_check_name_bad6(self): |
479 | - """Test check_name - bad - endswith -""" |
480 | - self.set_test_snap_yaml("name", "foo-bar-") |
481 | - c = SnapReviewLint(self.test_name) |
482 | - c.check_name() |
483 | - r = c.review_report |
484 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
485 | - self.check_results(r, expected_counts) |
486 | - |
487 | - def test_check_name_bad6b(self): |
488 | - """Test check_name - bad - startswith -""" |
489 | - self.set_test_snap_yaml("name", "-foo-bar") |
490 | - c = SnapReviewLint(self.test_name) |
491 | - c.check_name() |
492 | - r = c.review_report |
493 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
494 | - self.check_results(r, expected_counts) |
495 | - |
496 | - def test_check_name_bad7(self): |
497 | - """Test check_name - bad - cap""" |
498 | - self.set_test_snap_yaml("name", "foo-Bar") |
499 | - c = SnapReviewLint(self.test_name) |
500 | - c.check_name() |
501 | - r = c.review_report |
502 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
503 | - self.check_results(r, expected_counts) |
504 | - |
505 | - def test_check_name_bad8(self): |
506 | - """Test check_name - bad - all numbers""" |
507 | - self.set_test_snap_yaml("name", "01") |
508 | - c = SnapReviewLint(self.test_name) |
509 | - c.check_name() |
510 | - r = c.review_report |
511 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
512 | - self.check_results(r, expected_counts) |
513 | - |
514 | - def test_check_name_bad9(self): |
515 | - """Test check_name - bad - all numbers and dashes""" |
516 | - self.set_test_snap_yaml("name", "0-1") |
517 | - c = SnapReviewLint(self.test_name) |
518 | - c.check_name() |
519 | - r = c.review_report |
520 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
521 | - self.check_results(r, expected_counts) |
522 | - |
523 | - def test_check_name_missing(self): |
524 | - """Test check_name - missing""" |
525 | - self.set_test_snap_yaml("name", None) |
526 | - c = SnapReviewLint(self.test_name) |
527 | - c.check_name() |
528 | - r = c.review_report |
529 | - expected_counts = {"info": None, "warn": 0, "error": 1} |
530 | - self.check_results(r, expected_counts) |
531 | - |
532 | def test_check_version(self): |
533 | """Test check_version""" |
534 | self.set_test_snap_yaml("version", 1) |