Merge lp:~jdstrand/click-reviewers-tools/click-reviewers-tools.snappy1604 into lp:click-reviewers-tools

Proposed by Jamie Strandboge
Status: Merged
Merged at revision: 555
Proposed branch: lp:~jdstrand/click-reviewers-tools/click-reviewers-tools.snappy1604
Merge into: lp:click-reviewers-tools
Diff against target: 3029 lines (+1432/-469)
23 files modified
check-names.list (+2/-6)
clickreviews/cr_common.py (+82/-30)
clickreviews/cr_content_hub.py (+4/-0)
clickreviews/cr_desktop.py (+11/-4)
clickreviews/cr_framework.py (+13/-11)
clickreviews/cr_functional.py (+9/-10)
clickreviews/cr_lint.py (+113/-109)
clickreviews/cr_online_accounts.py (+10/-0)
clickreviews/cr_push_helper.py (+7/-0)
clickreviews/cr_scope.py (+4/-0)
clickreviews/cr_security.py (+210/-104)
clickreviews/cr_tests.py (+41/-1)
clickreviews/cr_url_dispatcher.py (+4/-0)
clickreviews/tests/test_cr_content_hub.py (+25/-0)
clickreviews/tests/test_cr_desktop.py (+28/-0)
clickreviews/tests/test_cr_lint.py (+386/-112)
clickreviews/tests/test_cr_online_accounts.py (+24/-0)
clickreviews/tests/test_cr_push_helper.py (+20/-0)
clickreviews/tests/test_cr_scope.py (+24/-0)
clickreviews/tests/test_cr_security.py (+334/-62)
clickreviews/tests/test_cr_url_dispatcher.py (+24/-0)
clickreviews/tests/utils.py (+28/-20)
debian/changelog (+29/-0)
To merge this branch: bzr merge lp:~jdstrand/click-reviewers-tools/click-reviewers-tools.snappy1604
Reviewer Review Type Date Requested Status
Jamie Strandboge (community) Approve
Michael Vogt Pending
Review via email: mp+278218@code.launchpad.net

Description of the change

This is a big branch to support all snaps and squashfs. In particular:

* add kernel and os as valid snap types
* remove package filename checks. They were meaningless and hard to maintain
* several changes for squashfs snaps that won't have a click manifest, etc.
  Importantly, this means that only package.yaml is looked at and a lot of
  click specific tests can be skipped
  - cr_common.py:
    + rename a few variable to not be click specific
    + add self.pkgfmt
    + adjust __init__() to conditionally use package.yaml on squashfs,
      otherwise click manifest
    + make click data structure initialization conditional on if click
      or not (eg, don't run hooks code on squashfs images)
  - adjust clickreviews/cr_* to conditionally run certain click-only tests
    on click packages
  - adjust architecture checks to use self.pkg_arch and rename
    control_architecture_specified_needed as architecture_specified_needed
  - cr_security.py:
    + revamp to use package.yaml on non-click instead of now nonexistent
      security manifest
    + update push-helper template test to not make hooks specific
    + network-client should not be allowed with push helpers either
    + conditionally look for INSTALL_DIR on 16.04 systems in security-policy
    + adjust security-override checks on 16.04 to follow 16.04 yaml
    + make click manifest checks conditional on if click
  - cr_tests.py: mock _pkgfmt_type(), _pkgfmt_version() and _is_squashfs()

Testing consisted of:
* comparing the output of 'click-review -v' on all clicks in the store with trunk and with this branch
* comparing the output of 'click-review -v' on all non-squashfs snaps in the store with trunk and with this branch
* comparing the output of 'click-review -v' on hello-world.canonial snap (click format) and hello-world.mvo snap (squashfs format) to make sure the correct tests are being run
* testing 'click-review -v' on all squashfs snaps

I don't necessarily expect people to go through this whole branch, but I wanted people to see it before committing. I'm going on holiday next week and will address feedback and pursue a store sync after that.

For those that want to test:
$ bzr branch lp:~jdstrand/click-reviewers-tools/click-reviewers-tools.snappy1604 review-tools
$ cd ./review-tools
$ PYTHONPATH=./ ./bin/click-review -v /path/to/app

To post a comment you must log in.
576. By Jamie Strandboge

merge r551 from trunk: lp:~jamestait/click-reviewers-tools/add-askubuntu-links

577. By Jamie Strandboge

merge r552 from trunk: add changelog entry

578. By Jamie Strandboge

merge r553 from trunk: Allow "accounts" hook since the 15.04.1 framework

579. By Jamie Strandboge

Merge from trunk: Forbid the internal "DebugMode" scope.ini key from making its
way into the store (LP: #1511063)

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Ok, this has not received reviews but is well tested. It is important that this land sooner rather than later so committing. Please ping me if there are any issues and I'll sort them out immediately.

review: Approve
580. By Jamie Strandboge

clickreviews/tests/test_cr_scope.py: update for last commit

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'check-names.list'
2--- check-names.list 2015-12-01 14:44:03 +0000
3+++ check-names.list 2015-12-01 15:03:49 +0000
4@@ -44,9 +44,9 @@
5 framework:policy_metadata|
6 framework:policy_unknown|
7 framework:policy_valid_name|
8+lint:architecture_specified_needed|
9 lint:click_local_extensions|
10 lint:control_architecture_match|
11-lint:control_architecture_specified_needed|
12 lint:control_architecture_valid|
13 lint:control_architecture_valid_contents|
14 lint:control_click_version_up_to_date|http://askubuntu.com/questions/417366/what-does-lint-control-click-version-up-to-date-mean/417367
15@@ -77,10 +77,6 @@
16 lint:manifest_icon_absolute_path|
17 lint:manifest_icon_empty|
18 lint:manifest_icon_present|
19-lint:package_filename_arch_match|
20-lint:package_filename_arch_valid|http://askubuntu.com/questions/685103/what-does-lint-package-filename-arch-valid-mean/685104
21-lint:package_filename_format|http://askubuntu.com/questions/685049/what-does-lint-package-filename-format-mean/685050
22-lint:package_filename_version_match|http://askubuntu.com/questions/417384/what-does-lint-package-filename-version-match-mean/417385
23 lint:package yaml_architecture_valid|
24 lint:package_yaml_icon_absolute_path|
25 lint:package_yaml_icon_empty|
26@@ -153,7 +149,6 @@
27 security:template_account_provider|
28 security:template_account_qml_plugin|
29 security:template_exists|
30-security:template_push_helper|
31 security:template_valid|http://askubuntu.com/q/671403
32 security:template_with_policy_version|
33 security:yaml_and_click|
34@@ -163,6 +158,7 @@
35 security:yaml_combinations|
36 security:yaml_override_click|
37 security:yaml_override_format|
38+security:yaml_override_present|https://developer.ubuntu.com/en/snappy/guides/security-policy/
39 security:yaml_policy_format|
40 security:yaml_policy_present|https://developer.ubuntu.com/en/snappy/guides/security-policy/
41 security:yaml_security-template|
42
43=== modified file 'clickreviews/cr_common.py'
44--- clickreviews/cr_common.py 2015-11-11 16:05:23 +0000
45+++ clickreviews/cr_common.py 2015-12-01 15:03:49 +0000
46@@ -96,9 +96,13 @@
47 "binaries",
48 "caps",
49 "config",
50+ "firmware",
51 "frameworks",
52 "icon",
53 "immutable-config",
54+ "initrd",
55+ "kernel",
56+ "modules",
57 "oem",
58 "services",
59 "source",
60@@ -112,11 +116,11 @@
61
62 def __init__(self, fn, review_type, peer_hooks=None, overrides=None,
63 peer_hooks_link=None):
64- self.click_package = fn
65+ self.pkg_filename = fn
66 self._check_path_exists()
67- if not self.click_package.endswith(".click") and \
68- not self.click_package.endswith(".snap"):
69- if self.click_package.endswith(".deb"):
70+ if not self.pkg_filename.endswith(".click") and \
71+ not self.pkg_filename.endswith(".snap"):
72+ if self.pkg_filename.endswith(".deb"):
73 error("filename does not end with '.click', but '.deb' "
74 "instead. See http://askubuntu.com/a/485544/94326 for "
75 "how click packages are different.")
76@@ -141,28 +145,29 @@
77 RAW_UNPACK_DIR = raw_unpack_pkg(fn)
78 self.raw_unpack_dir = RAW_UNPACK_DIR
79
80- # Get some basic information from the control file
81- control_file = self._extract_control_file()
82- tmp = list(Deb822.iter_paragraphs(control_file))
83- if len(tmp) != 1:
84- error("malformed control file: too many paragraphs")
85- control = tmp[0]
86- self.click_pkgname = control['Package']
87- self.click_version = control['Version']
88- self.click_arch = control['Architecture']
89-
90- # Parse and store the manifest
91- manifest_json = self._extract_manifest_file()
92- try:
93- self.manifest = json.load(manifest_json)
94- except Exception:
95- error("Could not load manifest file. Is it properly formatted?")
96- self._verify_manifest_structure()
97-
98- # Parse and store the package.yaml
99+ self.pkgfmt = {"type": "", "version": ""}
100+ self.manifest = None
101+ self.click_pkgname = None
102+ self.click_version = None
103+ self.pkg_arch = []
104+
105+ # Parse and store the package.yaml, if it exists
106 pkg_yaml = self._extract_package_yaml()
107 self.is_snap = False
108- if pkg_yaml is not None:
109+ if pkg_yaml is None:
110+ self.pkgfmt["type"] = "click"
111+ else:
112+ self.pkgfmt["type"] = "snap"
113+ # Some day we will be able to introspect the version, but not
114+ # today.... For now, decide on if it is a squashfs and if so,
115+ # assume it is 16.04
116+ if is_squashfs(fn):
117+ self.pkgfmt["version"] = "16.04"
118+ self.peer_hooks = None
119+ self.peer_hooks_link = None
120+ else:
121+ self.pkgfmt["version"] = "15.04"
122+
123 try:
124 self.pkg_yaml = yaml.safe_load(pkg_yaml)
125 except Exception:
126@@ -174,6 +179,45 @@
127 if 'type' not in self.pkg_yaml:
128 self.pkg_yaml['type'] = 'app'
129
130+ if 'architectures' in self.pkg_yaml:
131+ self.pkg_arch = self.pkg_yaml['architectures']
132+ elif 'architecture' in self.pkg_yaml:
133+ if isinstance(self.pkg_yaml['architecture'], str):
134+ self.pkg_arch = [self.pkg_yaml['architecture']]
135+ elif isinstance(self.pkg_yaml['architecture'], list):
136+ self.pkg_arch = self.pkg_yaml['architecture']
137+ else:
138+ error("Could not load package.yaml: invalid 'architecture'")
139+ else:
140+ self.pkg_arch = ['all']
141+
142+ if self._pkgfmt_type() == "click" or self._pkgfmt_version() == "15.04":
143+ # Get some basic information from the control file
144+ control_file = self._extract_control_file()
145+ tmp = list(Deb822.iter_paragraphs(control_file))
146+ if len(tmp) != 1:
147+ error("malformed control file: too many paragraphs")
148+ control = tmp[0]
149+ self.click_pkgname = control['Package']
150+ self.click_version = control['Version']
151+ if self._pkgfmt_type() == "click":
152+ if control['Architecture'] not in self.pkg_arch:
153+ self.pkg_arch.append(control['Architecture'])
154+ self.pkgfmt["version"] = str(control['Click-Version'])
155+
156+ # Parse and store the manifest
157+ manifest_json = self._extract_manifest_file()
158+ try:
159+ self.manifest = json.load(manifest_json)
160+ except Exception:
161+ error("Could not load manifest file. Is it properly formatted?")
162+ self._verify_manifest_structure()
163+
164+ self.valid_frameworks = self._extract_click_frameworks()
165+
166+ self.peer_hooks = peer_hooks
167+ self.peer_hooks_link = peer_hooks_link
168+
169 self.is_snap_oem = False
170 if self.is_snap and 'type' in self.pkg_yaml and \
171 self.pkg_yaml['type'] == 'oem':
172@@ -191,11 +235,7 @@
173 # it now
174 # self._list_all_compiled_binaries()
175
176- self.valid_frameworks = self._extract_click_frameworks()
177-
178- self.peer_hooks = peer_hooks
179 self.overrides = overrides if overrides is not None else {}
180- self.peer_hooks_link = peer_hooks_link
181
182 def _extract_click_frameworks(self):
183 '''Extract installed click frameworks'''
184@@ -248,10 +288,22 @@
185 return None
186 return out.split()[0]
187
188+ def _pkgfmt_type(self):
189+ '''Return the package format type'''
190+ if "type" not in self.pkgfmt:
191+ return ""
192+ return self.pkgfmt["type"]
193+
194+ def _pkgfmt_version(self):
195+ '''Return the package format version'''
196+ if "version" not in self.pkgfmt:
197+ return ""
198+ return self.pkgfmt["version"]
199+
200 def _check_path_exists(self):
201 '''Check that the provided path exists'''
202- if not os.path.exists(self.click_package):
203- error("Could not find '%s'" % self.click_package)
204+ if not os.path.exists(self.pkg_filename):
205+ error("Could not find '%s'" % self.pkg_filename)
206
207 def _extract_control_file(self):
208 '''Extract '''
209
210=== modified file 'clickreviews/cr_content_hub.py'
211--- clickreviews/cr_content_hub.py 2015-08-13 21:07:13 +0000
212+++ clickreviews/cr_content_hub.py 2015-12-01 15:03:49 +0000
213@@ -37,6 +37,10 @@
214
215 self.content_hub_files = dict() # click-show-files and tests
216 self.content_hub = dict()
217+
218+ if self.manifest is None:
219+ return
220+
221 for app in self.manifest['hooks']:
222 if 'content-hub' not in self.manifest['hooks'][app]:
223 # msg("Skipped missing content-hub hook for '%s'" % app)
224
225=== modified file 'clickreviews/cr_desktop.py'
226--- clickreviews/cr_desktop.py 2015-08-18 16:04:05 +0000
227+++ clickreviews/cr_desktop.py 2015-12-01 15:03:49 +0000
228@@ -41,6 +41,10 @@
229 self.desktop_files = dict() # click-show-files and a couple tests
230 self.desktop_entries = dict()
231 self.desktop_hook_entries = 0
232+
233+ if self.manifest is None:
234+ return
235+
236 for app in self.manifest['hooks']:
237 if 'desktop' not in self.manifest['hooks'][app]:
238 # msg("Skipped missing desktop hook for '%s'" % app)
239@@ -196,24 +200,27 @@
240 de.getExec()
241 l = 'http://askubuntu.com/questions/417381/what-does-desktop-exec-mean/417382'
242 elif de.getExec().split()[0] not in self.expected_execs:
243- if self.click_arch == "all": # interpreted file
244+ if self.pkg_arch[0] == "all": # interpreted file
245 if de.getExec().split()[0] not in self.deprecated_execs:
246 s = "found unexpected Exec with architecture '%s': %s" % \
247- (self.click_arch, de.getExec().split()[0])
248+ (self.pkg_arch[0], de.getExec().split()[0])
249 else:
250 s = "found deprecated Exec with architecture '%s': %s" % \
251- (self.click_arch, de.getExec().split()[0])
252+ (self.pkg_arch[0], de.getExec().split()[0])
253 t = 'warn'
254 else: # compiled
255 # TODO: this can be a lot smarter
256 s = "Non-standard Exec with architecture " + \
257 "'%s': %s (ok for compiled code)" % \
258- (self.click_arch, de.getExec().split()[0])
259+ (self.pkg_arch[0], de.getExec().split()[0])
260 t = 'info'
261 self._add_result(t, n, s, l)
262
263 def check_desktop_exec_webapp_container(self):
264 '''Check Exec=webapp-container entry'''
265+ if self.manifest is None:
266+ return
267+
268 fwk = self.manifest['framework']
269
270 for app in sorted(self.desktop_entries):
271
272=== modified file 'clickreviews/cr_framework.py'
273--- clickreviews/cr_framework.py 2015-08-20 20:52:17 +0000
274+++ clickreviews/cr_framework.py 2015-12-01 15:03:49 +0000
275@@ -23,22 +23,24 @@
276
277
278 class ClickReviewFramework(ClickReview):
279- '''This class represents click lint reviews'''
280+ '''This class represents click framework reviews'''
281 def __init__(self, fn, overrides=None):
282 ClickReview.__init__(self, fn, "framework", overrides=overrides)
283
284 self.frameworks_file = dict()
285 self.frameworks = dict()
286- for app in self.manifest['hooks']:
287- if 'framework' not in self.manifest['hooks'][app]:
288- # msg("Skipped missing framework hook for '%s'" % app)
289- continue
290- if not isinstance(self.manifest['hooks'][app]['framework'], str):
291- error("manifest malformed: hooks/%s/framework is not str" %
292- app)
293- (full_fn, data) = self._extract_framework(app)
294- self.frameworks_file[app] = full_fn
295- self.frameworks[app] = data
296+
297+ if self.manifest is not None:
298+ for app in self.manifest['hooks']:
299+ if 'framework' not in self.manifest['hooks'][app]:
300+ # msg("Skipped missing framework hook for '%s'" % app)
301+ continue
302+ if not isinstance(self.manifest['hooks'][app]['framework'], str):
303+ error("manifest malformed: hooks/%s/framework is not str" %
304+ app)
305+ (full_fn, data) = self._extract_framework(app)
306+ self.frameworks_file[app] = full_fn
307+ self.frameworks[app] = data
308
309 self.framework_policy_dirs = ['apparmor', 'seccomp']
310 self.framework_policy_subdirs = ['templates', 'policygroups']
311
312=== modified file 'clickreviews/cr_functional.py'
313--- clickreviews/cr_functional.py 2015-08-13 21:07:13 +0000
314+++ clickreviews/cr_functional.py 2015-12-01 15:03:49 +0000
315@@ -39,6 +39,9 @@
316
317 def check_applicationName(self):
318 '''Check applicationName matches click manifest'''
319+ if self.manifest is None:
320+ return
321+
322 t = 'info'
323 n = self._get_check_name('qml_applicationName_matches_manifest')
324 s = "OK"
325@@ -100,18 +103,13 @@
326
327 if len(appnames) == 0:
328 s = "could not find applicationName in: %s" % \
329- ", ".join(list(map(
330- lambda x: os.path.relpath(x,
331- self.unpack_dir),
332- qmls)
333- ))
334+ ", ".join(sorted(list(map(
335+ lambda x: os.path.relpath(x, self.unpack_dir), qmls))))
336 else: # not ok
337 s = "click manifest name '%s' not found in: " % \
338 self.click_pkgname + "%s" % \
339- ", ".join(list(map(
340- lambda x: "%s ('%s')" % (x, appnames[x]),
341- appnames)
342- ))
343+ ", ".join(sorted(list(map(
344+ lambda x: "%s ('%s')" % (x, appnames[x]), appnames))))
345
346 if len(self.pkg_bin_files) == 0:
347 s += ". Application may not work properly when confined."
348@@ -148,7 +146,8 @@
349 s = "OK"
350 l = None
351
352- if self.manifest['framework'] == "ubuntu-sdk-13.10":
353+ if self.manifest is not None and \
354+ self.manifest['framework'] == "ubuntu-sdk-13.10":
355 s = "SKIPPED (Oxide not available in ubuntu-sdk-13.10)"
356 else:
357 qmls = []
358
359=== modified file 'clickreviews/cr_lint.py'
360--- clickreviews/cr_lint.py 2015-11-24 12:13:36 +0000
361+++ clickreviews/cr_lint.py 2015-12-01 15:03:49 +0000
362@@ -76,7 +76,7 @@
363 'RCS*'
364 ]
365
366- if 'maintainer' in self.manifest:
367+ if self.manifest is not None and 'maintainer' in self.manifest:
368 maintainer = self.manifest['maintainer']
369 self.email = maintainer.partition('<')[2].rstrip('>')
370 self.is_core_app = \
371@@ -125,13 +125,19 @@
372 # Valid values for 'type' in packaging yaml
373 # - app
374 # - framework
375+ # - kernel
376 # - oem
377+ # - os
378 self.snappy_valid_types = ['app',
379 'framework',
380+ 'kernel',
381 'oem',
382+ 'os',
383 ]
384 self.snappy_redflagged_types = ['framework',
385- 'oem', # TBD
386+ 'kernel',
387+ 'oem',
388+ 'os',
389 ]
390
391 def _list_control_files(self):
392@@ -142,6 +148,10 @@
393
394 def check_control_files(self):
395 '''Check DEBIAN/* files'''
396+ if self._pkgfmt_type() == "snap" and \
397+ float(self._pkgfmt_version()) > 15.04:
398+ return
399+
400 for f in self.control_files:
401 t = 'info'
402 n = self._get_check_name(
403@@ -169,6 +179,10 @@
404
405 def check_control(self):
406 '''Check control()'''
407+ if self._pkgfmt_type() == "snap" and \
408+ float(self._pkgfmt_version()) > 15.04:
409+ return
410+
411 fh = self._extract_control_file()
412 tmp = list(Deb822.iter_paragraphs(fh))
413 t = 'info'
414@@ -340,6 +354,10 @@
415
416 def check_preinst(self):
417 '''Check preinst()'''
418+ if self._pkgfmt_type() == "snap" and \
419+ float(self._pkgfmt_version()) > 15.04:
420+ return
421+
422 expected = '''#! /bin/sh
423 echo "Click packages may not be installed directly using dpkg."
424 echo "Use 'click install' instead."
425@@ -361,6 +379,10 @@
426
427 def check_hooks(self):
428 '''Check click manifest hooks'''
429+ if self._pkgfmt_type() == "snap" and \
430+ float(self._pkgfmt_version()) > 15.04:
431+ return
432+
433 # oem snaps don't have a hooks entry
434 if self.is_snap_oem:
435 return
436@@ -457,6 +479,10 @@
437
438 def check_hooks_unknown(self):
439 '''Check if have any unknown hooks'''
440+ if self._pkgfmt_type() == "snap" and \
441+ float(self._pkgfmt_version()) > 15.04:
442+ return
443+
444 # oem snaps don't have a hooks entry
445 if self.is_snap_oem:
446 return
447@@ -478,6 +504,10 @@
448
449 def check_hooks_redflagged(self):
450 '''Check if have any redflagged hooks'''
451+ if self._pkgfmt_type() == "snap" and \
452+ float(self._pkgfmt_version()) > 15.04:
453+ return
454+
455 t = 'info'
456 n = self._get_check_name('redflagged_hooks')
457 s = 'OK'
458@@ -502,6 +532,9 @@
459
460 def check_external_symlinks(self):
461 '''Check if symlinks in the click package go out to the system.'''
462+ if self.is_snap and self.pkg_yaml['type'] not in ['app', 'framework']:
463+ return
464+
465 t = 'info'
466 n = self._get_check_name('external_symlinks')
467 s = 'OK'
468@@ -571,7 +604,11 @@
469 self._add_result(t, n, s)
470
471 def check_version(self):
472- '''Check package version is valid'''
473+ '''Check click package version is valid'''
474+ if self._pkgfmt_type() == "snap" and \
475+ float(self._pkgfmt_version()) > 15.04:
476+ return
477+
478 # deb-version(5)
479 t = 'info'
480 n = self._get_check_name('version_valid')
481@@ -586,13 +623,17 @@
482 self._add_result(t, n, s)
483
484 def check_architecture(self):
485- '''Check package architecture in DEBIAN/control is valid'''
486+ '''Check click package architecture in DEBIAN/control is valid'''
487+ if self._pkgfmt_type() == "snap" and \
488+ float(self._pkgfmt_version()) > 15.04:
489+ return
490+
491 t = 'info'
492 n = self._get_check_name('control_architecture_valid')
493 s = 'OK'
494- if self.click_arch not in self.valid_control_architectures:
495+ if self.pkg_arch[0] not in self.valid_control_architectures:
496 t = 'error'
497- s = "not a valid architecture: %s" % self.click_arch
498+ s = "not a valid architecture: %s" % self.pkg_arch[0]
499 self._add_result(t, n, s)
500
501 def check_architecture_all(self):
502@@ -600,7 +641,7 @@
503 t = 'info'
504 n = self._get_check_name('control_architecture_valid_contents')
505 s = 'OK'
506- if self.click_arch != "all":
507+ if self.pkg_arch[0] != "all":
508 self._add_result(t, n, s)
509 return
510
511@@ -616,22 +657,27 @@
512
513 def check_architecture_specified_needed(self):
514 '''Check if the specified architecture is actually needed'''
515- t = 'info'
516- n = self._get_check_name('control_architecture_specified_needed')
517- s = 'OK'
518- if self.click_arch == "all":
519- s = "SKIPPED: architecture is 'all'"
520+ for arch in self.pkg_arch:
521+ t = 'info'
522+ n = self._get_check_name('architecture_specified_needed')
523+ s = 'OK'
524+ if arch == "all":
525+ s = "SKIPPED: architecture is 'all'"
526+ self._add_result(t, n, s)
527+ return
528+
529+ if len(self.pkg_bin_files) == 0:
530+ t = 'warn'
531+ s = "Could not find compiled binaries for architecture '%s'" % \
532+ arch
533 self._add_result(t, n, s)
534- return
535-
536- if len(self.pkg_bin_files) == 0:
537- t = 'warn'
538- s = "Could not find compiled binaries for architecture '%s'" % \
539- self.click_arch
540- self._add_result(t, n, s)
541
542 def check_maintainer(self):
543- '''Check maintainer()'''
544+ '''Check manifest maintainer()'''
545+ if self._pkgfmt_type() == "snap" and \
546+ float(self._pkgfmt_version()) > 15.04:
547+ return
548+
549 t = 'info'
550 n = self._get_check_name('maintainer_present')
551 s = 'OK'
552@@ -671,7 +717,11 @@
553 self._add_result(t, n, s)
554
555 def check_title(self):
556- '''Check title()'''
557+ '''Check manifest title()'''
558+ if self._pkgfmt_type() == "snap" and \
559+ float(self._pkgfmt_version()) > 15.04:
560+ return
561+
562 t = 'info'
563 n = self._get_check_name('title_present')
564 s = 'OK'
565@@ -691,7 +741,11 @@
566 self._add_result(t, n, s)
567
568 def check_description(self):
569- '''Check description()'''
570+ '''Check manifest description()'''
571+ if self._pkgfmt_type() == "snap" and \
572+ float(self._pkgfmt_version()) > 15.04:
573+ return
574+
575 t = 'info'
576 n = self._get_check_name('description_present')
577 s = 'OK'
578@@ -717,7 +771,11 @@
579 self._add_result(t, n, s)
580
581 def check_framework(self):
582- '''Check framework()'''
583+ '''Check manifest framework()'''
584+ if self._pkgfmt_type() == "snap" and \
585+ float(self._pkgfmt_version()) > 15.04:
586+ return
587+
588 n = self._get_check_name('framework')
589 l = "http://askubuntu.com/questions/460512/what-framework-should-i-use-in-my-manifest-file"
590 framework_overrides = self.overrides.get('framework', {})
591@@ -759,6 +817,10 @@
592
593 def check_click_local_extensions(self):
594 '''Report any click local extensions'''
595+ if self._pkgfmt_type() == "snap" and \
596+ float(self._pkgfmt_version()) > 15.04:
597+ return
598+
599 t = 'info'
600 n = self._get_check_name('click_local_extensions')
601 s = 'OK'
602@@ -781,90 +843,8 @@
603 s = 'found unofficial extension%s: %s' % (plural, ', '.join(found))
604 self._add_result(t, n, s)
605
606- def check_package_filename(self):
607- '''Check filename of package'''
608- tmp = os.path.basename(self.click_package).split('_')
609- click_package_bn = os.path.basename(self.click_package)
610- t = 'info'
611- n = self._get_check_name('package_filename_format')
612- s = 'OK'
613- l = 'http://askubuntu.com/questions/685049/what-does-lint-package-filename-format-mean/685050'
614- if len(tmp) != 3:
615- t = 'warn'
616- s = "'%s' not of form $pkgname_$version_$arch.[click|snap]" % \
617- click_package_bn
618- self._add_result(t, n, s, l)
619-
620- t = 'info'
621- n = self._get_check_name('package_filename_version_match')
622- s = 'OK'
623- l = None
624- if len(tmp) >= 2:
625- # handle $pkgname_$version.click or $pkgname_$version.snap
626- if self.click_package.endswith('.snap'):
627- version = tmp[1].partition('.snap')[0]
628- else:
629- version = tmp[1].partition('.click')[0]
630- if version != self.click_version:
631- t = 'error'
632- s = "'%s' != '%s' from DEBIAN/control" % (version,
633- self.click_version)
634- l = 'http://askubuntu.com/questions/417384/what-does-lint-package-filename-version-match-mean/417385'
635- else:
636- t = 'warn'
637- s = "could not determine version from '%s'" % \
638- os.path.basename(self.click_package)
639- self._add_result(t, n, s, l)
640-
641- t = 'info'
642- n = self._get_check_name('package_filename_arch_valid')
643- s = 'OK'
644- l = 'http://askubuntu.com/questions/685103/what-does-lint-package-filename-arch-valid-mean/685104'
645- if len(tmp) >= 3:
646- if self.click_package.endswith('.snap'):
647- arch = tmp[2].partition('.snap')[0]
648- else:
649- arch = tmp[2].partition('.click')[0]
650- if arch == "unknown":
651- # short-circuit here since the appstore doesn't determine
652- # the version yet
653- t = 'info'
654- s = "SKIP: architecture 'unknown'"
655- self._add_result(t, n, s)
656- return
657- if arch not in self.valid_control_architectures:
658- t = 'warn'
659- s = "not a valid architecture: %s" % arch
660- else:
661- t = 'warn'
662- s = "could not determine architecture from '%s'" % \
663- os.path.basename(self.click_package)
664- self._add_result(t, n, s, l)
665-
666- t = 'info'
667- n = self._get_check_name('package_filename_arch_match')
668- s = 'OK'
669- if len(tmp) >= 3:
670- if self.click_package.endswith('.snap'):
671- arch = tmp[2].partition('.snap')[0]
672- else:
673- arch = tmp[2].partition('.click')[0]
674- if arch != self.click_arch:
675- if arch == 'all' and self.click_arch == 'multi':
676- # The store creates filenames for fat packages with _all
677- pass
678- else:
679- t = 'error'
680- s = "'%s' != '%s' from DEBIAN/control" % (arch,
681- self.click_arch)
682- else:
683- t = 'warn'
684- s = "could not determine architecture from '%s'" % \
685- os.path.basename(self.click_package)
686- self._add_result(t, n, s)
687-
688 def check_vcs(self):
689- '''Check for VCS files in the click package'''
690+ '''Check for VCS files in the package'''
691 t = 'info'
692 n = self._get_check_name('vcs_files')
693 s = 'OK'
694@@ -881,6 +861,9 @@
695
696 def check_click_in_package(self):
697 '''Check for *.click files in the toplevel click package'''
698+ if self._pkgfmt_type() == "snap":
699+ return
700+
701 t = 'info'
702 n = self._get_check_name('click_files')
703 s = 'OK'
704@@ -896,6 +879,10 @@
705
706 def check_dot_click(self):
707 '''Check for .click directory in the toplevel click package'''
708+ if self._pkgfmt_type() == "snap" and \
709+ float(self._pkgfmt_version()) > 15.04:
710+ return
711+
712 t = 'info'
713 n = self._get_check_name('dot_click')
714 s = 'OK'
715@@ -971,6 +958,10 @@
716
717 def check_manifest_architecture(self):
718 '''Check package architecture in manifest is valid'''
719+ if self._pkgfmt_type() == "snap" and \
720+ float(self._pkgfmt_version()) > 15.04:
721+ return
722+
723 self._verify_architecture(self.manifest, "manifest")
724
725 def _verify_icon(self, my_dict, test_str):
726@@ -1003,6 +994,10 @@
727
728 def check_icon(self):
729 '''Check icon()'''
730+ if self._pkgfmt_type() == "snap" and \
731+ float(self._pkgfmt_version()) > 15.04:
732+ return
733+
734 self._verify_icon(self.manifest, "manifest")
735
736 def check_snappy_name(self):
737@@ -1111,7 +1106,8 @@
738 unknown.append(f)
739 if len(unknown) > 0:
740 t = 'warn'
741- s = "unknown entries in package.yaml: '%s'" % (",".join(unknown))
742+ s = "unknown entries in package.yaml: '%s'" % \
743+ (",".join(sorted(unknown)))
744 obsoleted = ['maintainer', 'ports']
745 tmp = list(set(unknown) & set(obsoleted))
746 if len(tmp) > 0:
747@@ -1210,7 +1206,7 @@
748
749 def check_is_squashfs(self):
750 '''Check snapfs'''
751- if is_squashfs(self.click_package):
752+ if is_squashfs(self.pkg_filename):
753 t = 'error'
754 n = self._get_check_name('is_squashfs')
755 s = "(MANUAL REVIEW) squashfs pkg"
756@@ -1219,10 +1215,14 @@
757
758 def check_snappy_hashes(self):
759 '''Check snappy hashes.yaml'''
760+ if self._pkgfmt_type() == "snap" and \
761+ float(self._pkgfmt_version()) > 15.04:
762+ return
763+
764 if not self.is_snap:
765 return
766 # no hashes.yaml for squashfs images
767- if is_squashfs(self.click_package):
768+ if is_squashfs(self.pkg_filename):
769 return
770
771 def _check_allowed_perms(mode, allowed):
772@@ -1387,3 +1387,7 @@
773 s = 'found extra files not listed in hashes.yaml: %s' % \
774 ", ".join(extra)
775 self._add_result(t, n, s)
776+
777+ def check_snappy_frameworks(self):
778+ '''TODO'''
779+ return False
780
781=== modified file 'clickreviews/cr_online_accounts.py'
782--- clickreviews/cr_online_accounts.py 2015-11-27 09:04:43 +0000
783+++ clickreviews/cr_online_accounts.py 2015-12-01 15:03:49 +0000
784@@ -78,6 +78,10 @@
785 'account-provider',
786 'account-qml-plugin',
787 'account-service']
788+
789+ if self.manifest is None:
790+ return
791+
792 for app in self.manifest['hooks']:
793 for h in self.account_hooks:
794 if h not in self.manifest['hooks'][app]:
795@@ -120,6 +124,9 @@
796
797 def _extract_account(self, app, account_type):
798 '''Extract accounts'''
799+ if self.manifest is None:
800+ return
801+
802 a = self.manifest['hooks'][app][account_type]
803 fn = os.path.join(self.unpack_dir, a)
804
805@@ -158,6 +165,9 @@
806
807 def check_hooks_versions(self):
808 '''Check hooks versions'''
809+ if self.manifest is None:
810+ return
811+
812 framework = self.manifest['framework']
813 if not framework.startswith("ubuntu-sdk"):
814 return
815
816=== modified file 'clickreviews/cr_push_helper.py'
817--- clickreviews/cr_push_helper.py 2015-08-13 21:07:13 +0000
818+++ clickreviews/cr_push_helper.py 2015-12-01 15:03:49 +0000
819@@ -38,6 +38,10 @@
820
821 self.push_helper_files = dict() # click-show-files and tests
822 self.push_helper = dict()
823+
824+ if self.manifest is None:
825+ return
826+
827 for app in self.manifest['hooks']:
828 if 'push-helper' not in self.manifest['hooks'][app]:
829 # msg("Skipped missing push-helper hook for '%s'" % app)
830@@ -121,6 +125,9 @@
831
832 def check_hooks(self):
833 '''Verify combinations of click hooks with the push-helper hook'''
834+ if self.manifest is None:
835+ return
836+
837 for app in sorted(self.manifest['hooks']):
838 if app not in self.push_helper:
839 continue
840
841=== modified file 'clickreviews/cr_scope.py'
842--- clickreviews/cr_scope.py 2015-12-01 07:45:05 +0000
843+++ clickreviews/cr_scope.py 2015-12-01 15:03:49 +0000
844@@ -41,6 +41,10 @@
845 overrides=overrides)
846
847 self.scopes = dict()
848+
849+ if self.manifest is None:
850+ return
851+
852 for app in self.manifest['hooks']:
853 if 'scope' not in self.manifest['hooks'][app]:
854 # msg("Skipped missing scope hook for '%s'" % app)
855
856=== modified file 'clickreviews/cr_security.py'
857--- clickreviews/cr_security.py 2015-11-24 12:13:36 +0000
858+++ clickreviews/cr_security.py 2015-12-01 15:03:49 +0000
859@@ -131,36 +131,79 @@
860 framework_overrides = self.overrides.get('framework', {})
861 self._override_framework_policies(framework_overrides)
862
863+ # snappy
864+ self.sec_skipped_types = ['oem',
865+ 'os',
866+ 'kernel'] # these don't need security items
867+
868 self.security_manifests = dict()
869 self.security_apps = []
870- for app in self.manifest['hooks']:
871- if 'apparmor' not in self.manifest['hooks'][app]:
872- # msg("Skipped missing apparmor hook for '%s'" % app)
873- continue
874- if not isinstance(self.manifest['hooks'][app]['apparmor'], str):
875- error("manifest malformed: hooks/%s/apparmor is not str" % app)
876- rel_fn = self.manifest['hooks'][app]['apparmor']
877- self.security_manifests[rel_fn] = \
878- self._extract_security_manifest(app)
879- self.security_apps.append(app)
880-
881 self.security_profiles = dict()
882 self.security_apps_profiles = []
883- for app in self.manifest['hooks']:
884- if 'apparmor-profile' not in self.manifest['hooks'][app]:
885- # msg("Skipped missing apparmor hook for '%s'" % app)
886- continue
887- if not isinstance(self.manifest['hooks'][app]['apparmor-profile'],
888- str):
889- error("manifest malformed: hooks/%s/apparmor-profile is not "
890- "str" % app)
891- rel_fn = self.manifest['hooks'][app]['apparmor-profile']
892- self.security_profiles[rel_fn] = \
893- self._extract_security_profile(app)
894- self.security_apps_profiles.append(app)
895-
896- # snappy
897- self.sec_skipped_types = ['oem'] # these don't need security items
898+
899+ if self.manifest is None and self.is_snap:
900+ for exe_t in ['services', 'binaries']:
901+ if exe_t not in self.pkg_yaml:
902+ continue
903+ for item in self.pkg_yaml[exe_t]:
904+ if 'name' not in item:
905+ continue
906+ app = "%s/%s" % (exe_t, item['name'])
907+
908+ if 'security-policy' in item:
909+ if 'apparmor' not in item['security-policy']:
910+ continue
911+ rel_fn = item['security-policy']['apparmor']
912+ self.security_profiles[rel_fn] = \
913+ self._extract_security_profile(app)
914+ self.security_apps_profiles.append(app)
915+ continue
916+
917+ # Fake a security manifest for code reuse
918+ # FIXME: this needs to be updated when we have 'target'
919+ m = dict()
920+ m['policy_vendor'] = "ubuntu-core"
921+ m['policy_version'] = self._pkgfmt_version()
922+ if 'security-template' in item:
923+ m['template'] = item['security-template']
924+ else:
925+ m['template'] = 'default'
926+
927+ if 'caps' in item:
928+ m['policy_groups'] = item['caps']
929+ elif self._pkgfmt_version() == "15.04":
930+ m['policy_groups'] = ['networking']
931+ else:
932+ m['policy_groups'] = ['network-client']
933+
934+ self.security_manifests[app] = m
935+ self.security_apps.append(app)
936+ else:
937+ self.security_manifests = dict()
938+ self.security_apps = []
939+ for app in self.manifest['hooks']:
940+ if 'apparmor' not in self.manifest['hooks'][app]:
941+ # msg("Skipped missing apparmor hook for '%s'" % app)
942+ continue
943+ if not isinstance(self.manifest['hooks'][app]['apparmor'], str):
944+ error("manifest malformed: hooks/%s/apparmor is not str" % app)
945+ rel_fn = self.manifest['hooks'][app]['apparmor']
946+ self.security_manifests[rel_fn] = \
947+ self._extract_security_manifest(app)
948+ self.security_apps.append(app)
949+
950+ for app in self.manifest['hooks']:
951+ if 'apparmor-profile' not in self.manifest['hooks'][app]:
952+ # msg("Skipped missing apparmor hook for '%s'" % app)
953+ continue
954+ if not isinstance(self.manifest['hooks'][app]['apparmor-profile'],
955+ str):
956+ error("manifest malformed: hooks/%s/apparmor-profile is not "
957+ "str" % app)
958+ rel_fn = self.manifest['hooks'][app]['apparmor-profile']
959+ self.security_profiles[rel_fn] = \
960+ self._extract_security_profile(app)
961+ self.security_apps_profiles.append(app)
962
963 def _override_framework_policies(self, overrides):
964 # override major framework policies
965@@ -222,21 +265,32 @@
966
967 def _get_security_manifest(self, app):
968 '''Get the security manifest for app'''
969- if app not in self.manifest['hooks']:
970- error("Could not find '%s' in click manifest" % app)
971- elif 'apparmor' not in self.manifest['hooks'][app]:
972- error("Could not find apparmor hook for '%s' in click manifest" %
973- app)
974- f = self.manifest['hooks'][app]['apparmor']
975- m = self.security_manifests[f]
976+ if self._pkgfmt_type() == "click" or self._pkgfmt_version() == "15.04":
977+ if app not in self.manifest['hooks']:
978+ error("Could not find '%s' in click manifest" % app)
979+ elif 'apparmor' not in self.manifest['hooks'][app]:
980+ error("Could not find apparmor hook for '%s' in click manifest" %
981+ app)
982+ f = self.manifest['hooks'][app]['apparmor']
983+ m = self.security_manifests[f]
984+ else:
985+ f = app
986+ m = self.security_manifests[app]
987+
988 return (f, m)
989
990 def _extract_security_profile(self, app):
991 '''Extract security profile'''
992- d = self.manifest['hooks'][app]['apparmor-profile']
993- fn = os.path.join(self.unpack_dir, d)
994- rel_fn = self.manifest['hooks'][app]['apparmor-profile']
995+ if self._pkgfmt_type() == "click" or self._pkgfmt_version() == "15.04":
996+ rel_fn = self.manifest['hooks'][app]['apparmor-profile']
997+ else:
998+ exe_t, name = app.split('/')
999+ for item in self.pkg_yaml[exe_t]:
1000+ if 'name' in item and item['name'] == name:
1001+ rel_fn = item['security-policy']['apparmor']
1002+ break
1003
1004+ fn = os.path.join(self.unpack_dir, rel_fn)
1005 if not os.path.exists(fn):
1006 error("Could not find '%s'" % rel_fn)
1007
1008@@ -254,12 +308,20 @@
1009
1010 def _get_security_profile(self, app):
1011 '''Get the security profile for app'''
1012- if app not in self.manifest['hooks']:
1013- error("Could not find '%s' in click manifest" % app)
1014- elif 'apparmor-profile' not in self.manifest['hooks'][app]:
1015- error("Could not find apparmor-profile hook for '%s' in click "
1016- "manifest" % app)
1017- f = self.manifest['hooks'][app]['apparmor-profile']
1018+ if self._pkgfmt_type() == "click" or self._pkgfmt_version() == "15.04":
1019+ if app not in self.manifest['hooks']:
1020+ error("Could not find '%s' in click manifest" % app)
1021+ elif 'apparmor-profile' not in self.manifest['hooks'][app]:
1022+ error("Could not find apparmor-profile hook for '%s' in click "
1023+ "manifest" % app)
1024+ f = self.manifest['hooks'][app]['apparmor-profile']
1025+ else:
1026+ exe_t, name = app.split('/')
1027+ for item in self.pkg_yaml[exe_t]:
1028+ if 'name' in item and item['name'] == name:
1029+ f = item['security-policy']['apparmor']
1030+ break
1031+
1032 p = self.security_profiles[f]
1033 return (f, p)
1034
1035@@ -343,6 +405,10 @@
1036 s = "policy_vendor '%s' not found" % m['policy_vendor']
1037 self._add_result(t, n, s)
1038
1039+ if self._pkgfmt_type() == "snap" and \
1040+ float(self._pkgfmt_version()) >= 16.04:
1041+ continue
1042+
1043 t = 'info'
1044 n = self._get_check_name('policy_vendor_matches_framework', extra=f)
1045 s = "OK"
1046@@ -408,6 +474,10 @@
1047 s = '%s != %s' % (str(m['policy_version']), str(highest))
1048 self._add_result(t, n, s, l)
1049
1050+ if self._pkgfmt_type() == "snap" and \
1051+ float(self._pkgfmt_version()) >= 16.04:
1052+ continue
1053+
1054 t = 'info'
1055 n = self._get_check_name('policy_version_matches_framework', extra=f)
1056 s = "OK"
1057@@ -545,29 +615,17 @@
1058
1059 self._add_result(t, n, s)
1060
1061- def check_template_push_helpers(self):
1062- '''Check template for push-helpers'''
1063- for app in sorted(self.security_apps):
1064- (f, m) = self._get_security_manifest(app)
1065- t = 'info'
1066- n = self._get_check_name('template_push_helper', extra=f)
1067- s = "OK"
1068- if 'push-helper' not in self.manifest['hooks'][app]:
1069- continue
1070- if 'template' not in m or m['template'] != "ubuntu-push-helper":
1071- t = 'error'
1072- s = "template is not 'ubuntu-push-helper'"
1073- self._add_result(t, n, s)
1074-
1075 def check_policy_groups_push_helpers(self):
1076- '''Check policy_groups for push-helpers'''
1077+ '''Check policy groups for push-helpers'''
1078 for app in sorted(self.security_apps):
1079 (f, m) = self._get_security_manifest(app)
1080 t = 'info'
1081 n = self._get_check_name('policy_groups_push_helper', extra=f)
1082 s = "OK"
1083- if 'push-helper' not in self.manifest['hooks'][app]:
1084+
1085+ if 'template' not in m or m['template'] != 'ubuntu-push-helper':
1086 continue
1087+
1088 if 'policy_groups' not in m or \
1089 'push-notification-client' not in m['policy_groups']:
1090 self._add_result('error', n,
1091@@ -578,7 +636,7 @@
1092 for p in m['policy_groups']:
1093 if p not in self.allowed_push_helper_policy_groups:
1094 bad.append(p)
1095- elif p == "networking":
1096+ elif p == "networking" or p == "network-client":
1097 # The above covers this, but let's be very explicit and
1098 # never allow networking with push-helpers
1099 bad.append(p)
1100@@ -624,7 +682,8 @@
1101 '''Check policy_groups for ubuntu-account-plugin template'''
1102 for app in sorted(self.security_apps):
1103 (f, m) = self._get_security_manifest(app)
1104- if 'account-qml-plugin' not in self.manifest['hooks'][app]:
1105+
1106+ if 'template' not in m or m['template'] != 'ubuntu-account-plugin':
1107 continue
1108
1109 t = 'info'
1110@@ -843,12 +902,17 @@
1111 for app in sorted(self.security_apps_profiles):
1112 (f, p) = self._get_security_profile(app)
1113
1114- for v in ['###VAR###',
1115- '###PROFILEATTACH###',
1116- '@{CLICK_DIR}',
1117- '@{APP_PKGNAME}',
1118- '@{APP_VERSION}',
1119- ]:
1120+ searches = ['###VAR###',
1121+ '###PROFILEATTACH###',
1122+ '@{CLICK_DIR}',
1123+ '@{APP_PKGNAME}',
1124+ '@{APP_VERSION}',
1125+ ]
1126+ if self._pkgfmt_type() == 'snap' and \
1127+ float(self._pkgfmt_version()) > 15.04:
1128+ searches.append("@{INSTALL_DIR}")
1129+
1130+ for v in searches:
1131 t = 'info'
1132 n = self._get_check_name(
1133 'apparmor_profile', extra='%s (%s)' % (v, f))
1134@@ -1081,7 +1145,9 @@
1135 '''Verify click and security yaml are in sync (not including
1136 override)
1137 '''
1138- if not self.is_snap or self.pkg_yaml['type'] in self.sec_skipped_types:
1139+ if not self.is_snap or \
1140+ self.pkg_yaml['type'] in self.sec_skipped_types or \
1141+ float(self._pkgfmt_version()) > 15.04:
1142 return
1143
1144 # setup a small dict that is a subset of self.pkg_yaml
1145@@ -1121,7 +1187,9 @@
1146
1147 def check_security_yaml_override_and_click(self):
1148 '''Verify click and security yaml override are in sync'''
1149- if not self.is_snap or self.pkg_yaml['type'] in self.sec_skipped_types:
1150+ if not self.is_snap or \
1151+ self.pkg_yaml['type'] in self.sec_skipped_types or \
1152+ float(self._pkgfmt_version()) > 15.04:
1153 return
1154
1155 for exe_t in ['services', 'binaries']:
1156@@ -1180,16 +1248,44 @@
1157 s = "OK"
1158 if 'security-override' not in item:
1159 s = "OK (skipping unspecified override)"
1160- elif 'apparmor' not in item['security-override']:
1161- t = 'error'
1162- s = "'apparmor' not specified in 'security-override' " + \
1163- "for '%s'" % app
1164- elif 'seccomp' not in item['security-override']:
1165- t = 'error'
1166- s = "'seccomp' not specified in 'security-override' " + \
1167- "for '%s'" % app
1168+ elif float(self._pkgfmt_version()) < 16.04:
1169+ if 'apparmor' not in item['security-override']:
1170+ t = 'error'
1171+ s = "'apparmor' not specified in 'security-override' " + \
1172+ "for '%s'" % app
1173+ elif 'seccomp' not in item['security-override']:
1174+ t = 'error'
1175+ s = "'seccomp' not specified in 'security-override' " + \
1176+ "for '%s'" % app
1177+ else:
1178+ allowed_fields = ['read-paths',
1179+ 'write-paths',
1180+ 'abstractions',
1181+ 'syscalls']
1182+ if len(item['security-override'].keys()) == 0:
1183+ t = 'error'
1184+ s = "nothing specified in 'security-override' " + \
1185+ "for '%s'" % app
1186+ else:
1187+ for f in item['security-override'].keys():
1188+ if f not in allowed_fields:
1189+ t = 'error'
1190+ s = "unknown field '%s' in " % f + \
1191+ "'security-override' for '%s'" % app
1192+
1193 self._add_result(t, n, s)
1194
1195+ # security-override on 16.04 gives direct access to syscalls,
1196+ # read-paths, etc so it always needs a manual override
1197+ if 'security-override' in item and \
1198+ float(self._pkgfmt_version()) > 15.04:
1199+ t = 'error'
1200+ n = self._get_check_name('yaml_override_present')
1201+ s = "(MANUAL REVIEW) 'security-override' not allowed"
1202+ l = 'https://developer.ubuntu.com/en/snappy/guides/security-policy/'
1203+ m = True
1204+ self._add_result(t, n, s, link=l, manual_review=m)
1205+
1206 def check_security_yaml_policy(self):
1207 '''Verify security yaml policy'''
1208 if not self.is_snap:
1209@@ -1305,20 +1401,21 @@
1210 continue
1211 self._add_result(t, n, s)
1212
1213- t = 'info'
1214- n = self._get_check_name('yaml_security-template_in_manifest', app=app)
1215- s = "OK"
1216- if app not in self.manifest['hooks']:
1217- t = 'error'
1218- s = "'%s' not found in click manifest" % app
1219- self._add_result(t, n, s)
1220- continue
1221- elif 'apparmor' not in self.manifest['hooks'][app] and \
1222- 'apparmor-profile' not in self.manifest['hooks'][app]:
1223- t = 'error'
1224- s = "'apparmor' not found in click manifest for '%s'" % app
1225- self._add_result(t, n, s)
1226- continue
1227+ if self._pkgfmt_version() == "15.04":
1228+ t = 'info'
1229+ n = self._get_check_name('yaml_security-template_in_manifest', app=app)
1230+ s = "OK"
1231+ if app not in self.manifest['hooks']:
1232+ t = 'error'
1233+ s = "'%s' not found in click manifest" % app
1234+ self._add_result(t, n, s)
1235+ continue
1236+ elif 'apparmor' not in self.manifest['hooks'][app] and \
1237+ 'apparmor-profile' not in self.manifest['hooks'][app]:
1238+ t = 'error'
1239+ s = "'apparmor' not found in click manifest for '%s'" % app
1240+ self._add_result(t, n, s)
1241+ continue
1242
1243 # TODO: error if not 'common' or is 'unconfined'
1244
1245@@ -1358,25 +1455,30 @@
1246 continue
1247 self._add_result(t, n, s)
1248
1249- t = 'info'
1250- n = self._get_check_name('yaml_caps_in_manifest', app=app)
1251- s = "OK"
1252- if app not in self.manifest['hooks']:
1253- t = 'error'
1254- s = "'%s' not found in click manifest" % app
1255- self._add_result(t, n, s)
1256- continue
1257- elif 'apparmor' not in self.manifest['hooks'][app] and \
1258- 'apparmor-profile' not in self.manifest['hooks'][app]:
1259- t = 'error'
1260- s = "'apparmor' not found in click manifest for '%s'" % app
1261- self._add_result(t, n, s)
1262- continue
1263+ if self._pkgfmt_version() == "15.04":
1264+ t = 'info'
1265+ n = self._get_check_name('yaml_caps_in_manifest', app=app)
1266+ s = "OK"
1267+ if app not in self.manifest['hooks']:
1268+ t = 'error'
1269+ s = "'%s' not found in click manifest" % app
1270+ self._add_result(t, n, s)
1271+ continue
1272+ elif 'apparmor' not in self.manifest['hooks'][app] and \
1273+ 'apparmor-profile' not in self.manifest['hooks'][app]:
1274+ t = 'error'
1275+ s = "'apparmor' not found in click manifest for '%s'" % app
1276+ self._add_result(t, n, s)
1277+ continue
1278
1279 # TODO: error if not 'common'
1280
1281 def check_template_online_accounts_provider(self):
1282 '''Check template for online accounts account-provider'''
1283+ if self._pkgfmt_type() == "snap" and \
1284+ float(self._pkgfmt_version()) > 15.04:
1285+ return
1286+
1287 for app in sorted(self.security_apps):
1288 (f, m) = self._get_security_manifest(app)
1289 t = 'info'
1290@@ -1391,6 +1493,10 @@
1291
1292 def check_template_online_accounts_qml_plugin(self):
1293 '''Check template for online accounts account-qml-plugin'''
1294+ if self._pkgfmt_type() == "snap" and \
1295+ float(self._pkgfmt_version()) > 15.04:
1296+ return
1297+
1298 for app in sorted(self.security_apps):
1299 (f, m) = self._get_security_manifest(app)
1300 t = 'info'
1301
1302=== modified file 'clickreviews/cr_tests.py'
1303--- clickreviews/cr_tests.py 2015-11-12 13:37:12 +0000
1304+++ clickreviews/cr_tests.py 2015-12-01 15:03:49 +0000
1305@@ -50,6 +50,8 @@
1306 TEST_FRAMEWORK = dict()
1307 TEST_FRAMEWORK_POLICY = dict()
1308 TEST_FRAMEWORK_POLICY_UNKNOWN = []
1309+TEST_PKGFMT_TYPE = "click"
1310+TEST_PKGFMT_VERSION = "0.4"
1311
1312
1313 #
1314@@ -139,6 +141,9 @@
1315
1316 def _get_security_manifest(self, app):
1317 '''Pretend we read the security manifest file'''
1318+ if TEST_PKGFMT_VERSION == "16.04":
1319+ return (app, json.loads(TEST_SECURITY[app]))
1320+
1321 return ("%s.apparmor" % app, json.loads(TEST_SECURITY[app]))
1322
1323
1324@@ -244,6 +249,21 @@
1325 return True
1326
1327
1328+def _pkgfmt_type(self):
1329+ '''Pretend we found the pkgfmt type'''
1330+ return TEST_PKGFMT_TYPE
1331+
1332+
1333+def _pkgfmt_version(self):
1334+ '''Pretend we found the pkgfmt version'''
1335+ return TEST_PKGFMT_VERSION
1336+
1337+
1338+def _is_squashfs(self):
1339+ '''Pretend we discovered if it is a squashfs or not'''
1340+ return (TEST_PKGFMT_TYPE == "snap" and float(TEST_PKGFMT_VERSION) > 15.04)
1341+
1342+
1343 def create_patches():
1344 # http://docs.python.org/3.4/library/unittest.mock-examples.html
1345 # Mock patching. Don't use decorators but instead patch in setUp() of the
1346@@ -367,7 +387,14 @@
1347 patches.append(patch(
1348 'clickreviews.cr_framework.ClickReviewFramework._has_framework_in_metadir',
1349 _has_framework_in_metadir))
1350- patches.append(patch("clickreviews.cr_lint.is_squashfs", lambda x: False))
1351+
1352+ # pkgfmt
1353+ patches.append(patch("clickreviews.cr_common.ClickReview._pkgfmt_type",
1354+ _pkgfmt_type))
1355+ patches.append(patch("clickreviews.cr_common.ClickReview._pkgfmt_version",
1356+ _pkgfmt_version))
1357+ patches.append(patch("clickreviews.cr_common.is_squashfs", _is_squashfs))
1358+ patches.append(patch("clickreviews.cr_lint.is_squashfs", _is_squashfs))
1359
1360 return patches
1361
1362@@ -427,6 +454,8 @@
1363 self.test_readme_md = self.test_control['Description']
1364 self._update_test_readme_md()
1365
1366+ self.set_test_pkgfmt("click", "0.4")
1367+
1368 # hooks
1369 self.test_security_manifests = dict()
1370 self.test_security_profiles = dict()
1371@@ -444,6 +473,7 @@
1372 self.test_framework = dict()
1373 self.test_framework_policy = dict()
1374 self.test_framework_policy_unknown = []
1375+
1376 for app in self.test_manifest["hooks"].keys():
1377 # setup security manifest for each app
1378 self.set_test_security_manifest(app, 'policy_groups',
1379@@ -846,6 +876,12 @@
1380 self.test_security_profiles[app] = policy
1381 self._update_test_security_profiles()
1382
1383+ def set_test_pkgfmt(self, t, v):
1384+ global TEST_PKGFMT_TYPE
1385+ global TEST_PKGFMT_VERSION
1386+ TEST_PKGFMT_TYPE = t
1387+ TEST_PKGFMT_VERSION = v
1388+
1389 def set_test_desktop(self, app, key, value, no_update=False):
1390 '''Set key in desktop file to value. If value is None, remove key'''
1391 if app not in self.test_desktop_files:
1392@@ -1137,6 +1173,10 @@
1393 TEST_FRAMEWORK_POLICY = dict()
1394 global TEST_FRAMEWORK_POLICY_UNKNOWN
1395 TEST_FRAMEWORK_POLICY_UNKNOWN = []
1396+ global TEST_PKGFMT_TYPE
1397+ TEST_PKGFMT_TYPE = "click"
1398+ global TEST_PKGFMT_VERSION
1399+ TEST_PKGFMT_VERSION = "0.4"
1400
1401 self._reset_test_data()
1402 cr_common.recursive_rm(self.desktop_tmpdir)
1403
1404=== modified file 'clickreviews/cr_url_dispatcher.py'
1405--- clickreviews/cr_url_dispatcher.py 2015-08-13 21:07:13 +0000
1406+++ clickreviews/cr_url_dispatcher.py 2015-12-01 15:03:49 +0000
1407@@ -40,6 +40,10 @@
1408
1409 self.url_dispatcher_files = dict() # click-show-files and tests
1410 self.url_dispatcher = dict()
1411+
1412+ if self.manifest is None:
1413+ return
1414+
1415 for app in self.manifest['hooks']:
1416 if 'urls' not in self.manifest['hooks'][app]:
1417 # msg("Skipped missing urls hook for '%s'" % app)
1418
1419=== modified file 'clickreviews/tests/test_cr_content_hub.py'
1420--- clickreviews/tests/test_cr_content_hub.py 2015-10-16 02:54:07 +0000
1421+++ clickreviews/tests/test_cr_content_hub.py 2015-12-01 15:03:49 +0000
1422@@ -155,3 +155,28 @@
1423 r = c.click_report
1424 expected_counts = {'info': None, 'warn': 0, 'error': 1}
1425 self.check_results(r, expected_counts)
1426+
1427+ def test_check_valid_snappy_1504(self):
1428+ '''Test check_valid() - snappy 15.04'''
1429+ self.set_test_pkgfmt("snap", "15.04")
1430+ self.set_test_content_hub(self.default_appname, "destination", "pictures")
1431+ self.set_test_content_hub(self.default_appname, "share", "pictures")
1432+ self.set_test_content_hub(self.default_appname, "source", "pictures")
1433+ c = ClickReviewContentHub(self.test_name)
1434+ c.check_valid()
1435+ r = c.click_report
1436+ expected_counts = {'info': 6, 'warn': 0, 'error': 0}
1437+ self.check_results(r, expected_counts)
1438+
1439+ def test_check_valid_snappy_1604(self):
1440+ '''Test check_valid() - snappy 16.04'''
1441+ self.set_test_pkgfmt("snap", "16.04")
1442+ self.set_test_content_hub(self.default_appname, "destination", "pictures")
1443+ self.set_test_content_hub(self.default_appname, "share", "pictures")
1444+ self.set_test_content_hub(self.default_appname, "source", "pictures")
1445+ c = ClickReviewContentHub(self.test_name)
1446+ c.check_valid()
1447+ r = c.click_report
1448+ # should be empty with this pkgfmt
1449+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1450+ self.check_results(r, expected_counts)
1451
1452=== modified file 'clickreviews/tests/test_cr_desktop.py'
1453--- clickreviews/tests/test_cr_desktop.py 2015-10-16 02:54:07 +0000
1454+++ clickreviews/tests/test_cr_desktop.py 2015-12-01 15:03:49 +0000
1455@@ -896,3 +896,31 @@
1456 r = c.click_report
1457 expected_counts = {'info': None, 'warn': 0, 'error': 1}
1458 self.check_results(r, expected_counts)
1459+
1460+ def test_check_desktop_file_snappy_1504(self):
1461+ '''Test check_desktop_file() - snappy 15.04'''
1462+ self.set_test_pkgfmt("snap", "15.04")
1463+ c = ClickReviewDesktop(self.test_name)
1464+ c.check_desktop_file()
1465+ r = c.click_report
1466+ expected = dict()
1467+ expected['info'] = dict()
1468+ expected['warn'] = dict()
1469+ expected['error'] = dict()
1470+ name = c._get_check_name('files_usable')
1471+ expected['info'][name] = {"text": "OK"}
1472+ self.check_results(r, expected=expected)
1473+
1474+ def test_check_desktop_file_snappy_1604(self):
1475+ '''Test check_desktop_file() - snappy 16.04'''
1476+ self.set_test_pkgfmt("snap", "16.04")
1477+ c = ClickReviewDesktop(self.test_name)
1478+ c.check_desktop_file()
1479+ r = c.click_report
1480+ expected = dict()
1481+ expected['info'] = dict()
1482+ expected['warn'] = dict()
1483+ expected['error'] = dict()
1484+ name = c._get_check_name('files_usable')
1485+ expected['info'][name] = {"text": "Skipped: could not find any desktop files"}
1486+ self.check_results(r, expected=expected)
1487
1488=== modified file 'clickreviews/tests/test_cr_lint.py'
1489--- clickreviews/tests/test_cr_lint.py 2015-11-12 14:27:00 +0000
1490+++ clickreviews/tests/test_cr_lint.py 2015-12-01 15:03:49 +0000
1491@@ -143,7 +143,9 @@
1492 def test_check_architecture_nonexistent(self):
1493 '''Test check_architecture() - nonexistent'''
1494 self.set_test_control("Architecture", "nonexistent")
1495+ self.set_test_pkgfmt("click", "0.4")
1496 c = ClickReviewLint(self.test_name)
1497+ c.pkg_arch = ["nonexistent"]
1498 c.check_architecture()
1499 r = c.click_report
1500 expected_counts = {'info': 0, 'warn': 0, 'error': 1}
1501@@ -157,6 +159,25 @@
1502 expected_counts = {'info': None, 'warn': 0, 'error': 0}
1503 self.check_results(r, expected_counts)
1504
1505+ def test_check_control_architecture_snappy_1504(self):
1506+ '''Test check_control() (architecture) - snappy 15.04'''
1507+ self.set_test_pkgfmt("snap", "15.04")
1508+ c = ClickReviewLint(self.test_name)
1509+ c.check_control()
1510+ r = c.click_report
1511+ expected_counts = {'info': 15, 'warn': 0, 'error': 0}
1512+ self.check_results(r, expected_counts)
1513+
1514+ def test_check_control_architecture_snappy_1604(self):
1515+ '''Test check_control() (architecture) - snappy 16.04'''
1516+ self.set_test_pkgfmt("snap", "16.04")
1517+ c = ClickReviewLint(self.test_name)
1518+ c.check_control()
1519+ r = c.click_report
1520+ # should be empty with this pkgfmt
1521+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1522+ self.check_results(r, expected_counts)
1523+
1524 def test_check_control_architecture_missing(self):
1525 '''Test check_control() (architecture missing)'''
1526 self.set_test_control("Architecture", None)
1527@@ -220,6 +241,7 @@
1528 self.set_test_control("Architecture", "armhf")
1529 self.set_test_manifest("architecture", "armhf")
1530 c = ClickReviewLint(self.test_name)
1531+ c.pkg_arch = ['armhf']
1532 c.pkg_bin_files = []
1533 c.check_architecture_specified_needed()
1534 r = c.click_report
1535@@ -237,90 +259,6 @@
1536 expected_counts = {'info': None, 'warn': 0, 'error': 0}
1537 self.check_results(r, expected_counts)
1538
1539- def test_check_package_filename(self):
1540- '''Test check_package_filename()'''
1541- c = ClickReviewLint(self.test_name)
1542- c.check_package_filename()
1543- r = c.click_report
1544- expected_counts = {'info': None, 'warn': 0, 'error': 0}
1545- self.check_results(r, expected_counts)
1546-
1547- def test_check_package_filename_missing_version(self):
1548- '''Test check_package_filename() - missing version'''
1549- test_name = "%s_%s.click" % (self.test_control['Package'],
1550- self.test_control['Architecture'])
1551- c = ClickReviewLint(test_name)
1552- c.check_package_filename()
1553- r = c.click_report
1554- expected_counts = {'info': None, 'warn': 3, 'error': 1}
1555- self.check_results(r, expected_counts)
1556-
1557- def test_check_package_filename_missing_arch(self):
1558- '''Test check_package_filename() - missing arch'''
1559- test_name = "%s_%s.click" % (self.test_control['Package'],
1560- self.test_control['Version'])
1561- c = ClickReviewLint(test_name)
1562- c.check_package_filename()
1563- r = c.click_report
1564- expected_counts = {'info': None, 'warn': 3, 'error': 0}
1565- self.check_results(r, expected_counts)
1566-
1567- def test_check_package_filename_missing_package(self):
1568- '''Test check_package_filename() - missing package'''
1569- test_name = "%s_%s.click" % (self.test_control['Version'],
1570- self.test_control['Architecture'])
1571- c = ClickReviewLint(test_name)
1572- c.check_package_filename()
1573- r = c.click_report
1574- expected_counts = {'info': None, 'warn': 3, 'error': 1}
1575- self.check_results(r, expected_counts)
1576-
1577- def test_check_package_filename_extra_underscore(self):
1578- '''Test check_package_filename() - extra underscore'''
1579- test_name = "_%s_%s_%s.click" % (self.test_control['Package'],
1580- self.test_control['Version'],
1581- self.test_control['Architecture'])
1582- c = ClickReviewLint(test_name)
1583- c.check_package_filename()
1584- r = c.click_report
1585- expected_counts = {'info': None, 'warn': 2, 'error': 2}
1586- self.check_results(r, expected_counts)
1587-
1588- def test_check_package_filename_version_mismatches(self):
1589- '''Test check_package_filename() (version mismatches filename)'''
1590- self.set_test_control("Version", "100.1.1")
1591- c = ClickReviewLint(self.test_name)
1592- c.check_package_filename()
1593- r = c.click_report
1594- expected_counts = {'info': None, 'warn': 0, 'error': 1}
1595- self.check_results(r, expected_counts)
1596-
1597- def test_check_package_filename_valid_arch(self):
1598- '''Test check_package_filename() (valid arch)'''
1599- arch = "armhf"
1600- self.set_test_control("Architecture", arch)
1601- test_name = "%s_%s_%s.click" % (self.test_control['Package'],
1602- self.test_control['Version'],
1603- self.test_control['Architecture'])
1604- c = ClickReviewLint(test_name)
1605- c.check_package_filename()
1606- r = c.click_report
1607- expected_counts = {'info': None, 'warn': 0, 'error': 0}
1608- self.check_results(r, expected_counts)
1609-
1610- def test_check_package_filename_valid_arch_multi(self):
1611- '''Test check_package_filename() (valid multi arch)'''
1612- arch = "multi"
1613- self.set_test_control("Architecture", arch)
1614- test_name = "%s_%s_%s.click" % (self.test_control['Package'],
1615- self.test_control['Version'],
1616- arch)
1617- c = ClickReviewLint(test_name)
1618- c.check_package_filename()
1619- r = c.click_report
1620- expected_counts = {'info': None, 'warn': 0, 'error': 0}
1621- self.check_results(r, expected_counts)
1622-
1623 def test_check_manifest_missing_arch(self):
1624 '''Test check_manifest_architecture() (missing)'''
1625 self.set_test_manifest("architecture", None)
1626@@ -330,6 +268,26 @@
1627 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1628 self.check_results(r, expected_counts)
1629
1630+ def test_check_manifest_missing_arch_snappy_1504(self):
1631+ '''Test check_manifest_architecture() - snappy 15.04'''
1632+ self.set_test_pkgfmt("snap", "15.04")
1633+ self.set_test_manifest("architecture", None)
1634+ c = ClickReviewLint(self.test_name)
1635+ c.check_manifest_architecture()
1636+ r = c.click_report
1637+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1638+ self.check_results(r, expected_counts)
1639+
1640+ def test_check_manifest_missing_arch_snappy_1604(self):
1641+ '''Test check_manifest_architecture() - snappy 16.04'''
1642+ self.set_test_pkgfmt("snap", "16.04")
1643+ self.set_test_manifest("architecture", None)
1644+ c = ClickReviewLint(self.test_name)
1645+ c.check_manifest_architecture()
1646+ r = c.click_report
1647+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1648+ self.check_results(r, expected_counts)
1649+
1650 def test_check_manifest_arch_all(self):
1651 '''Test check_manifest_architecture() (all)'''
1652 self.set_test_manifest("architecture", "all")
1653@@ -455,27 +413,6 @@
1654 expected_counts = {'info': 0, 'warn': 0, 'error': 1}
1655 self.check_results(r, expected_counts)
1656
1657- def test_check_package_filename_mismatch_arch(self):
1658- '''Test check_package_filename() (control mismatches arch)'''
1659- arch = "armhf"
1660- self.set_test_control("Architecture", "all")
1661- test_name = "%s_%s_%s.click" % (self.test_control['Package'],
1662- self.test_control['Version'],
1663- arch)
1664- c = ClickReviewLint(test_name)
1665- c.check_package_filename()
1666- r = c.click_report
1667- expected_counts = {'info': None, 'warn': 0, 'error': 1}
1668- self.check_results(r, expected_counts)
1669-
1670- def test_check_package_filename_with_extra_click(self):
1671- """Test namespaces with the word "click" in them."""
1672- c = ClickReviewLint(self.test_name)
1673- c.check_package_filename()
1674- r = c.click_report
1675- expected_counts = {'info': None, 'warn': 0, 'error': 0}
1676- self.check_results(r, expected_counts)
1677-
1678 def test_check_control(self):
1679 """A very basic test to make sure check_control can be tested."""
1680 c = ClickReviewLint(self.test_name)
1681@@ -638,6 +575,26 @@
1682 expected_counts = {'info': None, 'warn': 0, 'error': 0}
1683 self.check_results(r, expected_counts)
1684
1685+ def test_check_icon_snappy_1504(self):
1686+ '''Test check_icon() - snappy 15.04'''
1687+ self.set_test_pkgfmt("snap", "15.04")
1688+ self.set_test_manifest("icon", "someicon")
1689+ c = ClickReviewLint(self.test_name)
1690+ c.check_icon()
1691+ r = c.click_report
1692+ expected_counts = {'info': 3, 'warn': 0, 'error': 0}
1693+ self.check_results(r, expected_counts)
1694+
1695+ def test_check_icon_snappy_1604(self):
1696+ '''Test check_icon() - snappy 16.04'''
1697+ self.set_test_pkgfmt("snap", "16.04")
1698+ self.set_test_manifest("icon", "someicon")
1699+ c = ClickReviewLint(self.test_name)
1700+ c.check_icon()
1701+ r = c.click_report
1702+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1703+ self.check_results(r, expected_counts)
1704+
1705 def test_check_icon_unspecified(self):
1706 '''Test check_icon()'''
1707 self.set_test_manifest("icon", None)
1708@@ -714,6 +671,34 @@
1709 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1710 self.check_results(r, expected_counts)
1711
1712+ def test_check_click_local_extensions_snappy_1504(self):
1713+ '''Testeck_click_local_extensions() - snappy 15.04'''
1714+ self.set_test_pkgfmt("snap", "15.04")
1715+ for k in self.test_manifest.keys():
1716+ if k.startswith("x-"):
1717+ self.set_test_manifest(k, None)
1718+ self.set_test_manifest("x-source", {"vcs-bzr": "lp:notes-app",
1719+ "vcs-bzr-revno": "209"})
1720+ c = ClickReviewLint(self.test_name)
1721+ c.check_click_local_extensions()
1722+ r = c.click_report
1723+ expected_counts = {'info': 0, 'warn': 1, 'error': 0}
1724+ self.check_results(r, expected_counts)
1725+
1726+ def test_check_click_local_extensions_snappy_1604(self):
1727+ '''Testeck_click_local_extensions() - snappy 16.04'''
1728+ self.set_test_pkgfmt("snap", "16.04")
1729+ for k in self.test_manifest.keys():
1730+ if k.startswith("x-"):
1731+ self.set_test_manifest(k, None)
1732+ self.set_test_manifest("x-source", {"vcs-bzr": "lp:notes-app",
1733+ "vcs-bzr-revno": "209"})
1734+ c = ClickReviewLint(self.test_name)
1735+ c.check_click_local_extensions()
1736+ r = c.click_report
1737+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1738+ self.check_results(r, expected_counts)
1739+
1740 def test_check_framework(self):
1741 '''Test check_framework()'''
1742 self.patch_frameworks()
1743@@ -748,6 +733,19 @@
1744 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1745 self.check_results(r, expected_counts)
1746
1747+ def test_check_framework_multiple_snappy_1604(self):
1748+ '''Test check_framework() - snappy 16.04'''
1749+ self.patch_frameworks()
1750+ self.set_test_pkgfmt("snap", "16.04")
1751+ self.set_test_manifest("framework",
1752+ "ubuntu-sdk-14.10-qml-dev2,ubuntu-core-15.04")
1753+ c = ClickReviewLint(self.test_name)
1754+ c.is_snap = True
1755+ c.check_framework()
1756+ r = c.click_report
1757+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1758+ self.check_results(r, expected_counts)
1759+
1760 @patch('clickreviews.remote.read_cr_file')
1761 def test_check_framework_fetches_remote_data(self, mock_read_cr_file):
1762 '''Test check_framework()'''
1763@@ -831,6 +829,27 @@
1764 expected_counts = {'info': None, 'warn': 0, 'error': 0}
1765 self.check_results(r, expected_counts)
1766
1767+ def test_check_hooks_snappy_1504(self):
1768+ '''Test check_hooks() - snappy 15.04'''
1769+ self.set_test_pkgfmt("snap", "15.04")
1770+ self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1771+ c = ClickReviewLint(self.test_name)
1772+ c.check_hooks()
1773+ r = c.click_report
1774+ expected_counts = {'info': 5, 'warn': 0, 'error': 0}
1775+ self.check_results(r, expected_counts)
1776+
1777+ def test_check_hooks_snappy_1604(self):
1778+ '''Test check_hooks() - snappy 16.04'''
1779+ self.set_test_pkgfmt("snap", "16.04")
1780+ self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1781+ c = ClickReviewLint(self.test_name)
1782+ c.check_hooks()
1783+ r = c.click_report
1784+ # this should be 0 with this pkgfmt
1785+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1786+ self.check_results(r, expected_counts)
1787+
1788 def test_check_hooks_multiple_desktop_apps(self):
1789 '''Test check_hooks() - multiple desktop apps'''
1790 self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1791@@ -950,6 +969,26 @@
1792 expected_counts = {'info': None, 'warn': 1, 'error': 0}
1793 self.check_results(r, expected_counts)
1794
1795+ def test_check_hooks_unknown_nonexistent_snappy_1504(self):
1796+ '''Test check_hooks_unknown() - nonexistent - snappy 15.04'''
1797+ self.set_test_pkgfmt("snap", "15.04")
1798+ self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1799+ c = ClickReviewLint(self.test_name)
1800+ c.check_hooks_unknown()
1801+ r = c.click_report
1802+ expected_counts = {'info': 3, 'warn': 0, 'error': 0}
1803+ self.check_results(r, expected_counts)
1804+
1805+ def test_check_hooks_unknown_nonexistent_snappy_1604(self):
1806+ '''Test check_hooks_unknown() - nonexistent - snappy 16.04'''
1807+ self.set_test_pkgfmt("snap", "16.04")
1808+ self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1809+ c = ClickReviewLint(self.test_name)
1810+ c.check_hooks_unknown()
1811+ r = c.click_report
1812+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1813+ self.check_results(r, expected_counts)
1814+
1815 def test_check_hooks_unknown_good(self):
1816 '''Test check_hooks_unknown()'''
1817 self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1818@@ -982,6 +1021,26 @@
1819 name = c._get_check_name('hooks_redflag', app='test-app')
1820 self.check_manual_review(r, name)
1821
1822+ def test_check_hooks_redflagged_payui_snappy_1504(self):
1823+ '''Test check_hooks_redflagged() - pay-ui - snappy 15.04'''
1824+ self.set_test_pkgfmt("snap", "15.04")
1825+ self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1826+ c = ClickReviewLint(self.test_name)
1827+ c.check_hooks_redflagged()
1828+ r = c.click_report
1829+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1830+ self.check_results(r, expected_counts)
1831+
1832+ def test_check_hooks_redflagged_payui_snappy_1604(self):
1833+ '''Test check_hooks_redflagged() - pay-ui - snappy 16.04'''
1834+ self.set_test_pkgfmt("snap", "16.04")
1835+ self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1836+ c = ClickReviewLint(self.test_name)
1837+ c.check_hooks_redflagged()
1838+ r = c.click_report
1839+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
1840+ self.check_results(r, expected_counts)
1841+
1842 def test_check_hooks_redflagged_apparmor_profile(self):
1843 '''Test check_hooks_redflagged() - apparmor-profile'''
1844 self.set_test_manifest("framework", "ubuntu-sdk-13.10")
1845@@ -1036,6 +1095,28 @@
1846 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1847 self.check_results(r, expected_counts)
1848
1849+ def test_snappy_name_toplevel_1504(self):
1850+ '''Test check_snappy_name - toplevel - 15.04'''
1851+ self.set_test_pkgfmt("snap", "15.04")
1852+ self.set_test_pkg_yaml("name", "foo")
1853+ c = ClickReviewLint(self.test_name)
1854+ c.is_snap = True
1855+ c.check_snappy_name()
1856+ r = c.click_report
1857+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1858+ self.check_results(r, expected_counts)
1859+
1860+ def test_snappy_name_toplevel_1604(self):
1861+ '''Test check_snappy_name - toplevel - 16.04'''
1862+ self.set_test_pkgfmt("snap", "16.04")
1863+ self.set_test_pkg_yaml("name", "foo")
1864+ c = ClickReviewLint(self.test_name)
1865+ c.is_snap = True
1866+ c.check_snappy_name()
1867+ r = c.click_report
1868+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1869+ self.check_results(r, expected_counts)
1870+
1871 def test_snappy_name_flat(self):
1872 '''Test check_snappy_name - obsoleted flat'''
1873 self.set_test_pkg_yaml("name", "foo.bar")
1874@@ -1092,6 +1173,26 @@
1875 expected_counts = {'info': None, 'warn': 0, 'error': 1}
1876 self.check_results(r, expected_counts)
1877
1878+ def test_snappy_version_1504(self):
1879+ '''Test check_snappy_version - 15.04'''
1880+ self.set_test_pkgfmt("snap", "15.04")
1881+ self.set_test_pkg_yaml("version", 1)
1882+ c = ClickReviewLint(self.test_name)
1883+ c.check_snappy_version()
1884+ r = c.click_report
1885+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1886+ self.check_results(r, expected_counts)
1887+
1888+ def test_snappy_version_1604(self):
1889+ '''Test check_snappy_version - 16.04'''
1890+ self.set_test_pkgfmt("snap", "16.04")
1891+ self.set_test_pkg_yaml("version", 1)
1892+ c = ClickReviewLint(self.test_name)
1893+ c.check_snappy_version()
1894+ r = c.click_report
1895+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1896+ self.check_results(r, expected_counts)
1897+
1898 def test_snappy_version1(self):
1899 '''Test check_snappy_version - integer'''
1900 self.set_test_pkg_yaml("version", 1)
1901@@ -1191,6 +1292,26 @@
1902 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1903 self.check_results(r, expected_counts)
1904
1905+ def test_snappy_type_app_1504(self):
1906+ '''Test check_snappy_type - app - 15.04'''
1907+ self.set_test_pkgfmt("snap", "15.04")
1908+ self.set_test_pkg_yaml("type", "app")
1909+ c = ClickReviewLint(self.test_name)
1910+ c.check_snappy_type()
1911+ r = c.click_report
1912+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1913+ self.check_results(r, expected_counts)
1914+
1915+ def test_snappy_type_app_1604(self):
1916+ '''Test check_snappy_type - app - 16.04'''
1917+ self.set_test_pkgfmt("snap", "16.04")
1918+ self.set_test_pkg_yaml("type", "app")
1919+ c = ClickReviewLint(self.test_name)
1920+ c.check_snappy_type()
1921+ r = c.click_report
1922+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1923+ self.check_results(r, expected_counts)
1924+
1925 def test_snappy_type_framework(self):
1926 '''Test check_snappy_type - framework'''
1927 self.set_test_pkg_yaml("type", "framework")
1928@@ -1209,6 +1330,24 @@
1929 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1930 self.check_results(r, expected_counts)
1931
1932+ def test_snappy_type_os(self):
1933+ '''Test check_snappy_type - os'''
1934+ self.set_test_pkg_yaml("type", "os")
1935+ c = ClickReviewLint(self.test_name)
1936+ c.check_snappy_type()
1937+ r = c.click_report
1938+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1939+ self.check_results(r, expected_counts)
1940+
1941+ def test_snappy_type_kernel(self):
1942+ '''Test check_snappy_type - kernel'''
1943+ self.set_test_pkg_yaml("type", "kernel")
1944+ c = ClickReviewLint(self.test_name)
1945+ c.check_snappy_type()
1946+ r = c.click_report
1947+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1948+ self.check_results(r, expected_counts)
1949+
1950 def test_snappy_type_redflagged(self):
1951 '''Test check_snappy_type_redflagged - unspecified'''
1952 self.set_test_pkg_yaml("type", None)
1953@@ -1218,6 +1357,26 @@
1954 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1955 self.check_results(r, expected_counts)
1956
1957+ def test_snappy_type_redflagged_1504(self):
1958+ '''Test check_snappy_type_redflagged - unspecified - 15.04'''
1959+ self.set_test_pkgfmt("snap", "15.04")
1960+ self.set_test_pkg_yaml("type", None)
1961+ c = ClickReviewLint(self.test_name)
1962+ c.check_snappy_type_redflagged()
1963+ r = c.click_report
1964+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1965+ self.check_results(r, expected_counts)
1966+
1967+ def test_snappy_type_redflagged_1604(self):
1968+ '''Test check_snappy_type_redflagged - unspecified - 16.04'''
1969+ self.set_test_pkgfmt("snap", "16.04")
1970+ self.set_test_pkg_yaml("type", None)
1971+ c = ClickReviewLint(self.test_name)
1972+ c.check_snappy_type_redflagged()
1973+ r = c.click_report
1974+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
1975+ self.check_results(r, expected_counts)
1976+
1977 def test_snappy_type_redflagged_app(self):
1978 '''Test check_snappy_type_redflagged - app'''
1979 self.set_test_pkg_yaml("type", "app")
1980@@ -1236,6 +1395,33 @@
1981 expected_counts = {'info': None, 'warn': 0, 'error': 1}
1982 self.check_results(r, expected_counts)
1983
1984+ def test_snappy_type_redflagged_oem(self):
1985+ '''Test check_snappy_type_redflagged - oem'''
1986+ self.set_test_pkg_yaml("type", "oem")
1987+ c = ClickReviewLint(self.test_name)
1988+ c.check_snappy_type_redflagged()
1989+ r = c.click_report
1990+ expected_counts = {'info': None, 'warn': 0, 'error': 1}
1991+ self.check_results(r, expected_counts)
1992+
1993+ def test_snappy_type_redflagged_os(self):
1994+ '''Test check_snappy_type_redflagged - os'''
1995+ self.set_test_pkg_yaml("type", "os")
1996+ c = ClickReviewLint(self.test_name)
1997+ c.check_snappy_type_redflagged()
1998+ r = c.click_report
1999+ expected_counts = {'info': None, 'warn': 0, 'error': 1}
2000+ self.check_results(r, expected_counts)
2001+
2002+ def test_snappy_type_redflagged_kernel(self):
2003+ '''Test check_snappy_type_redflagged - kernel'''
2004+ self.set_test_pkg_yaml("type", "kernel")
2005+ c = ClickReviewLint(self.test_name)
2006+ c.check_snappy_type_redflagged()
2007+ r = c.click_report
2008+ expected_counts = {'info': None, 'warn': 0, 'error': 1}
2009+ self.check_results(r, expected_counts)
2010+
2011 def test_check_snappy_icon(self):
2012 '''Test check_snappy_icon()'''
2013 self.set_test_pkg_yaml("icon", "someicon")
2014@@ -1245,6 +1431,26 @@
2015 expected_counts = {'info': 3, 'warn': 0, 'error': 0}
2016 self.check_results(r, expected_counts)
2017
2018+ def test_check_snappy_icon_1504(self):
2019+ '''Test check_snappy_icon() - 15.04'''
2020+ self.set_test_pkgfmt("snap", "15.04")
2021+ self.set_test_pkg_yaml("icon", "someicon")
2022+ c = ClickReviewLint(self.test_name)
2023+ c.check_snappy_icon()
2024+ r = c.click_report
2025+ expected_counts = {'info': 3, 'warn': 0, 'error': 0}
2026+ self.check_results(r, expected_counts)
2027+
2028+ def test_check_snappy_icon_1604(self):
2029+ '''Test check_snappy_icon() - 16.04'''
2030+ self.set_test_pkgfmt("snap", "16.04")
2031+ self.set_test_pkg_yaml("icon", "someicon")
2032+ c = ClickReviewLint(self.test_name)
2033+ c.check_snappy_icon()
2034+ r = c.click_report
2035+ expected_counts = {'info': 3, 'warn': 0, 'error': 0}
2036+ self.check_results(r, expected_counts)
2037+
2038 def test_check_snappy_icon_unspecified(self):
2039 '''Test check_snappy_icon() - unspecified'''
2040 self.set_test_pkg_yaml("icon", None)
2041@@ -1274,6 +1480,18 @@
2042
2043 def test_check_snappy_missing_arch(self):
2044 '''Test check_snappy_architecture() (missing)'''
2045+ self.set_test_pkgfmt("snap", "15.04")
2046+ self.set_test_pkg_yaml("architectures", None)
2047+ c = ClickReviewLint(self.test_name)
2048+ c.is_snap = True
2049+ c.check_snappy_architecture()
2050+ r = c.click_report
2051+ expected_counts = {'info': 2, 'warn': 0, 'error': 0}
2052+ self.check_results(r, expected_counts)
2053+
2054+ def test_check_snappy_missing_arch_1604(self):
2055+ '''Test check_snappy_architecture() (missing)'''
2056+ self.set_test_pkgfmt("snap", "16.04")
2057 self.set_test_pkg_yaml("architectures", None)
2058 c = ClickReviewLint(self.test_name)
2059 c.is_snap = True
2060@@ -1284,6 +1502,7 @@
2061
2062 def test_check_snappy_arch_all_deprecated(self):
2063 '''Test check_snappy_architecture() (deprecated, all)'''
2064+ self.set_test_pkgfmt("snap", "15.04")
2065 self.set_test_pkg_yaml("architecture", "all")
2066 c = ClickReviewLint(self.test_name)
2067 c.is_snap = True
2068@@ -1294,6 +1513,7 @@
2069
2070 def test_check_snappy_arch_amd64_deprecated(self):
2071 '''Test check_snappy_architecture() (deprecated, all)'''
2072+ self.set_test_pkgfmt("snap", "15.04")
2073 self.set_test_pkg_yaml("architecture", "amd64")
2074 c = ClickReviewLint(self.test_name)
2075 c.is_snap = True
2076@@ -1304,6 +1524,7 @@
2077
2078 def test_check_snappy_arch_all(self):
2079 '''Test check_snappy_architecture() (all)'''
2080+ self.set_test_pkgfmt("snap", "15.04")
2081 self.set_test_pkg_yaml("architectures", ["all"])
2082 c = ClickReviewLint(self.test_name)
2083 c.is_snap = True
2084@@ -1314,6 +1535,7 @@
2085
2086 def test_check_snappy_arch_single_armhf(self):
2087 '''Test check_snappy_architecture() (single arch, armhf)'''
2088+ self.set_test_pkgfmt("snap", "15.04")
2089 self.set_test_pkg_yaml("architectures", ["armhf"])
2090 c = ClickReviewLint(self.test_name)
2091 c.is_snap = True
2092@@ -1324,6 +1546,7 @@
2093
2094 def test_check_snappy_arch_single_arm64(self):
2095 '''Test check_snappy_architecture() (single arch, arm64)'''
2096+ self.set_test_pkgfmt("snap", "15.04")
2097 self.set_test_pkg_yaml("architectures", ["arm64"])
2098 c = ClickReviewLint(self.test_name)
2099 c.is_snap = True
2100@@ -1334,6 +1557,7 @@
2101
2102 def test_check_snappy_arch_single_i386(self):
2103 '''Test check_snappy_architecture() (single arch, i386)'''
2104+ self.set_test_pkgfmt("snap", "15.04")
2105 self.set_test_pkg_yaml("architectures", ["i386"])
2106 c = ClickReviewLint(self.test_name)
2107 c.is_snap = True
2108@@ -1344,6 +1568,7 @@
2109
2110 def test_check_snappy_arch_single_amd64(self):
2111 '''Test check_snappy_architecture() (single arch, amd64)'''
2112+ self.set_test_pkgfmt("snap", "15.04")
2113 self.set_test_pkg_yaml("architectures", ["amd64"])
2114 c = ClickReviewLint(self.test_name)
2115 c.is_snap = True
2116@@ -1354,6 +1579,7 @@
2117
2118 def test_check_snappy_arch_single_nonexistent(self):
2119 '''Test check_snappy_architecture() (single nonexistent arch)'''
2120+ self.set_test_pkgfmt("snap", "15.04")
2121 self.set_test_pkg_yaml("architectures", ["nonexistent"])
2122 c = ClickReviewLint(self.test_name)
2123 c.is_snap = True
2124@@ -1364,6 +1590,7 @@
2125
2126 def test_check_snappy_arch_single_multi(self):
2127 '''Test check_snappy_architecture() (single arch: invalid multi)'''
2128+ self.set_test_pkgfmt("snap", "15.04")
2129 self.set_test_pkg_yaml("architectures", "multi")
2130 c = ClickReviewLint(self.test_name)
2131 c.is_snap = True
2132@@ -1374,12 +1601,11 @@
2133
2134 def test_check_snappy_valid_arch_multi(self):
2135 '''Test check_snappy_architecture() (valid multi)'''
2136- arch = "multi"
2137+ self.set_test_pkgfmt("snap", "15.04")
2138 self.set_test_pkg_yaml("architectures", ["armhf"])
2139- self.set_test_control("Architecture", arch)
2140 test_name = "%s_%s_%s.snap" % (self.test_control['Package'],
2141 self.test_control['Version'],
2142- arch)
2143+ "armhf")
2144 c = ClickReviewLint(test_name)
2145 c.is_snap = True
2146 c.check_snappy_architecture()
2147@@ -1389,9 +1615,9 @@
2148
2149 def test_check_snappy_valid_arch_multi2(self):
2150 '''Test check_snappy_architecture() (valid multi2)'''
2151+ self.set_test_pkgfmt("snap", "15.04")
2152 arch = "multi"
2153 self.set_test_pkg_yaml("architectures", ["armhf", "i386"])
2154- self.set_test_control("Architecture", arch)
2155 test_name = "%s_%s_%s.snap" % (self.test_control['Package'],
2156 self.test_control['Version'],
2157 arch)
2158@@ -1404,9 +1630,9 @@
2159
2160 def test_check_snappy_invalid_arch_multi_nonexistent(self):
2161 '''Test check_snappy_architecture() (invalid multi)'''
2162+ self.set_test_pkgfmt("snap", "15.04")
2163 arch = "multi"
2164 self.set_test_pkg_yaml("architectures", ["armhf", "nonexistent"])
2165- self.set_test_control("Architecture", arch)
2166 test_name = "%s_%s_%s.snap" % (self.test_control['Package'],
2167 self.test_control['Version'],
2168 arch)
2169@@ -1419,9 +1645,9 @@
2170
2171 def test_check_snappy_invalid_arch_multi_all(self):
2172 '''Test check_snappy_architecture() (invalid all)'''
2173+ self.set_test_pkgfmt("snap", "15.04")
2174 arch = "multi"
2175 self.set_test_pkg_yaml("architectures", ["armhf", "all"])
2176- self.set_test_control("Architecture", arch)
2177 test_name = "%s_%s_%s.snap" % (self.test_control['Package'],
2178 self.test_control['Version'],
2179 arch)
2180@@ -1434,13 +1660,14 @@
2181
2182 def test_check_snappy_invalid_arch_multi_multi(self):
2183 '''Test check_snappy_architecture() (invalid multi)'''
2184+ self.set_test_pkgfmt("snap", "15.04")
2185 arch = "multi"
2186 self.set_test_pkg_yaml("architectures", ["multi", "armhf"])
2187- self.set_test_control("Architecture", arch)
2188 test_name = "%s_%s_%s.snap" % (self.test_control['Package'],
2189 self.test_control['Version'],
2190 arch)
2191 c = ClickReviewLint(test_name)
2192+ c.is_snap = True
2193 c.check_snappy_architecture()
2194 r = c.click_report
2195 expected_counts = {'info': None, 'warn': 0, 'error': 1}
2196@@ -1455,6 +1682,26 @@
2197 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2198 self.check_results(r, expected_counts)
2199
2200+ def test_check_snappy_unknown_entries_1504(self):
2201+ '''Test check_snappy_unknown_entries - none - 15.04'''
2202+ self.set_test_pkgfmt("snap", "15.04")
2203+ self.set_test_pkg_yaml("name", "foo")
2204+ c = ClickReviewLint(self.test_name)
2205+ c.check_snappy_unknown_entries()
2206+ r = c.click_report
2207+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2208+ self.check_results(r, expected_counts)
2209+
2210+ def test_check_snappy_unknown_entries_1604(self):
2211+ '''Test check_snappy_unknown_entries - none - 16.04'''
2212+ self.set_test_pkgfmt("snap", "16.04")
2213+ self.set_test_pkg_yaml("name", "foo")
2214+ c = ClickReviewLint(self.test_name)
2215+ c.check_snappy_unknown_entries()
2216+ r = c.click_report
2217+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2218+ self.check_results(r, expected_counts)
2219+
2220 def test_check_snappy_unknown_entries2(self):
2221 '''Test check_snappy_unknown_entries - one'''
2222 self.set_test_pkg_yaml("nonexistent", "bar")
2223@@ -1653,6 +1900,33 @@
2224 expected_counts = {'info': 4, 'warn': 0, 'error': 0}
2225 self.check_results(r, expected_counts)
2226
2227+ def test_check_snappy_hashes_1504(self):
2228+ '''Test check_snappy_hashes() - 15.04'''
2229+ self.set_test_pkgfmt("snap", "15.04")
2230+ c = ClickReviewLint(self.test_name)
2231+ c.is_snap = True
2232+ yaml = self._create_hashes_yaml()
2233+ c.pkg_files = self._test_pkg_files
2234+ self.set_test_hashes_yaml(yaml)
2235+ c.check_snappy_hashes()
2236+ r = c.click_report
2237+ expected_counts = {'info': 4, 'warn': 0, 'error': 0}
2238+ self.check_results(r, expected_counts)
2239+
2240+ def test_check_snappy_hashes_1604(self):
2241+ '''Test check_snappy_hashes() - 16.04'''
2242+ self.set_test_pkgfmt("snap", "16.04")
2243+ c = ClickReviewLint(self.test_name)
2244+ c.is_snap = True
2245+ yaml = self._create_hashes_yaml()
2246+ c.pkg_files = self._test_pkg_files
2247+ self.set_test_hashes_yaml(yaml)
2248+ c.check_snappy_hashes()
2249+ r = c.click_report
2250+ # this should be empty with this package format
2251+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2252+ self.check_results(r, expected_counts)
2253+
2254 def test_check_snappy_hashes_archive_files_missing_name(self):
2255 '''Test check_snappy_hashes() - missing name'''
2256 c = ClickReviewLint(self.test_name)
2257
2258=== modified file 'clickreviews/tests/test_cr_online_accounts.py'
2259--- clickreviews/tests/test_cr_online_accounts.py 2015-11-27 09:04:43 +0000
2260+++ clickreviews/tests/test_cr_online_accounts.py 2015-12-01 15:03:49 +0000
2261@@ -270,6 +270,30 @@
2262 expected_counts = {'info': 4, 'warn': 0, 'error': 0}
2263 self.check_results(r, expected_counts)
2264
2265+ def test_check_application_snappy_1504(self):
2266+ '''Test check_application() - snappy 15.04'''
2267+ self.set_test_pkgfmt("snap", "15.04")
2268+ xml = self._stub_application()
2269+ # print(etree.tostring(xml))
2270+ self.set_test_account(self.default_appname, "account-application", xml)
2271+ c = ClickReviewAccounts(self.test_name)
2272+ c.check_application()
2273+ r = c.click_report
2274+ expected_counts = {'info': 4, 'warn': 0, 'error': 0}
2275+ self.check_results(r, expected_counts)
2276+
2277+ def test_check_application_snappy_1604(self):
2278+ '''Test check_application() - snappy 16.04'''
2279+ self.set_test_pkgfmt("snap", "16.04")
2280+ xml = self._stub_application()
2281+ # print(etree.tostring(xml))
2282+ self.set_test_account(self.default_appname, "account-application", xml)
2283+ c = ClickReviewAccounts(self.test_name)
2284+ c.check_application()
2285+ r = c.click_report
2286+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2287+ self.check_results(r, expected_counts)
2288+
2289 def test_check_application_not_specified(self):
2290 '''Test check_application() - not specified'''
2291 c = ClickReviewAccounts(self.test_name)
2292
2293=== modified file 'clickreviews/tests/test_cr_push_helper.py'
2294--- clickreviews/tests/test_cr_push_helper.py 2015-10-16 02:54:07 +0000
2295+++ clickreviews/tests/test_cr_push_helper.py 2015-12-01 15:03:49 +0000
2296@@ -201,3 +201,23 @@
2297 r = c.click_report
2298 expected_counts = {'info': None, 'warn': 0, 'error': 1}
2299 self.check_results(r, expected_counts)
2300+
2301+ def test_check_valid_exec_snappy_1504(self):
2302+ '''Test check_valid() - exec - snappy 15.04'''
2303+ self.set_test_pkgfmt("snap", "15.04")
2304+ self.set_test_push_helper(self.default_appname, "exec", "foo")
2305+ c = ClickReviewPushHelper(self.test_name)
2306+ c.check_valid()
2307+ r = c.click_report
2308+ expected_counts = {'info': 2, 'warn': 0, 'error': 0}
2309+ self.check_results(r, expected_counts)
2310+
2311+ def test_check_valid_exec_snappy_1604(self):
2312+ '''Test check_valid() - exec - snappy 16.04'''
2313+ self.set_test_pkgfmt("snap", "16.04")
2314+ self.set_test_push_helper(self.default_appname, "exec", "foo")
2315+ c = ClickReviewPushHelper(self.test_name)
2316+ c.check_valid()
2317+ r = c.click_report
2318+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2319+ self.check_results(r, expected_counts)
2320
2321=== modified file 'clickreviews/tests/test_cr_scope.py'
2322--- clickreviews/tests/test_cr_scope.py 2015-12-01 07:45:05 +0000
2323+++ clickreviews/tests/test_cr_scope.py 2015-12-01 15:03:49 +0000
2324@@ -281,3 +281,27 @@
2325 r = c.click_report
2326 expected_counts = {'info': None, 'warn': 0, 'error': 1}
2327 self.check_results(r, expected_counts)
2328+
2329+ def test_check_scope_ini_snappy_1504(self):
2330+ '''Test check_scope_ini() - snappy 15.04'''
2331+ self.set_test_pkgfmt("snap", "15.04")
2332+ scope = self._create_scope(self._stub_config())
2333+
2334+ self.set_test_scope(self.default_appname, scope)
2335+ c = ClickReviewScope(self.test_name)
2336+ c.check_scope_ini()
2337+ r = c.click_report
2338+ expected_counts = {'info': 4, 'warn': 0, 'error': 0}
2339+ self.check_results(r, expected_counts)
2340+
2341+ def test_check_scope_ini_snappy_1604(self):
2342+ '''Test check_scope_ini() - snappy 16.04'''
2343+ self.set_test_pkgfmt("snap", "16.04")
2344+ scope = self._create_scope(self._stub_config())
2345+
2346+ self.set_test_scope(self.default_appname, scope)
2347+ c = ClickReviewScope(self.test_name)
2348+ c.check_scope_ini()
2349+ r = c.click_report
2350+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2351+ self.check_results(r, expected_counts)
2352
2353=== modified file 'clickreviews/tests/test_cr_security.py'
2354--- clickreviews/tests/test_cr_security.py 2015-11-11 15:40:49 +0000
2355+++ clickreviews/tests/test_cr_security.py 2015-12-01 15:03:49 +0000
2356@@ -41,14 +41,41 @@
2357
2358 def test_check_policy_version_vendor(self):
2359 '''Test check_policy_version() - valid'''
2360- for v in [1.0]: # update when have more vendor policy
2361- c = ClickReviewSecurity(self.test_name)
2362- self.set_test_security_manifest(self.default_appname,
2363- "policy_version", v)
2364- c.check_policy_version()
2365- report = c.click_report
2366- expected_counts = {'info': 3, 'warn': 0, 'error': 0}
2367- self.check_results(report, expected_counts)
2368+ c = ClickReviewSecurity(self.test_name)
2369+ self.set_test_security_manifest(self.default_appname,
2370+ "policy_version", 1.0)
2371+ c.check_policy_version()
2372+ report = c.click_report
2373+ expected_counts = {'info': 3, 'warn': 0, 'error': 0}
2374+ self.check_results(report, expected_counts)
2375+
2376+ def test_check_policy_version_vendor_snappy_1504(self):
2377+ '''Test check_policy_version() - valid - snappy 15.04'''
2378+ self.set_test_pkgfmt("snap", "15.04")
2379+ n = "bin/%s" % self.default_appname
2380+ self._set_yaml_binary([('caps', ['network-client'])], name=n)
2381+ c = ClickReviewSecurity(self.test_name)
2382+ self.set_test_security_manifest("binaries/%s" % n,
2383+ "policy_version", 1.0)
2384+ c.check_policy_version()
2385+ report = c.click_report
2386+ expected_counts = {'info': 3, 'warn': 0, 'error': 0}
2387+ self.check_results(report, expected_counts)
2388+
2389+ def test_check_policy_version_vendor_snappy_1604(self):
2390+ '''Test check_policy_version() - valid - snappy 16.04'''
2391+ self.set_test_pkgfmt("snap", "16.04")
2392+ n = "bin/%s" % self.default_appname
2393+ self._set_yaml_binary([('caps', ['network-client'])], name=n)
2394+ c = ClickReviewSecurity(self.test_name)
2395+ self.set_test_security_manifest("binaries/%s" % n,
2396+ "policy_vendor", "ubuntu-core")
2397+ self.set_test_security_manifest("binaries/%s" % n,
2398+ "policy_version", 15.04)
2399+ c.check_policy_version()
2400+ report = c.click_report
2401+ expected_counts = {'info': 2, 'warn': 0, 'error': 0}
2402+ self.check_results(report, expected_counts)
2403
2404 def test_check_policy_version_highest(self):
2405 '''Test check_policy_version() - highest'''
2406@@ -273,6 +300,32 @@
2407 expected_counts = {'info': 2, 'warn': 0, 'error': 0}
2408 self.check_results(report, expected_counts)
2409
2410+ def test_check_policy_vendor_ubuntu_1504(self):
2411+ '''Test check_policy_vendor() - ubuntu - 15.04'''
2412+ self.set_test_pkgfmt("snap", "15.04")
2413+ n = "bin/%s" % self.default_appname
2414+ self._set_yaml_binary([('caps', ['network-client'])], name=n)
2415+ c = ClickReviewSecurity(self.test_name)
2416+ self.set_test_security_manifest("binaries/%s" % n,
2417+ "policy_vendor", "ubuntu")
2418+ c.check_policy_vendor()
2419+ report = c.click_report
2420+ expected_counts = {'info': 2, 'warn': 0, 'error': 0}
2421+ self.check_results(report, expected_counts)
2422+
2423+ def test_check_policy_vendor_ubuntu_1604(self):
2424+ '''Test check_policy_vendor() - ubuntu - 16.04'''
2425+ self.set_test_pkgfmt("snap", "16.04")
2426+ n = "bin/%s" % self.default_appname
2427+ self._set_yaml_binary([('caps', ['network-client'])], name=n)
2428+ c = ClickReviewSecurity(self.test_name)
2429+ self.set_test_security_manifest("binaries/%s" % n,
2430+ "policy_vendor", "ubuntu")
2431+ c.check_policy_vendor()
2432+ report = c.click_report
2433+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2434+ self.check_results(report, expected_counts)
2435+
2436 def test_check_policy_vendor_ubuntu(self):
2437 '''Test check_policy_vendor() - ubuntu'''
2438 c = ClickReviewSecurity(self.test_name)
2439@@ -975,18 +1028,36 @@
2440 self.set_test_security_manifest(self.default_appname,
2441 "policy_groups",
2442 ["push-notification-client"])
2443+ self.set_test_security_manifest(self.default_appname,
2444+ "template", "ubuntu-push-helper")
2445 c = ClickReviewSecurity(self.test_name)
2446 c.check_policy_groups_push_helpers()
2447 report = c.click_report
2448 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2449 self.check_results(report, expected_counts)
2450
2451+ def test_check_policy_groups_pushhelper_wrong_template(self):
2452+ '''Test check_policy_groups_pushhelper()'''
2453+ self.set_test_push_helper(self.default_appname, "exec", "foo")
2454+ self.set_test_security_manifest(self.default_appname,
2455+ "policy_groups",
2456+ ["push-notification-client"])
2457+ self.set_test_security_manifest(self.default_appname,
2458+ "template", "ubuntu-sdk")
2459+ c = ClickReviewSecurity(self.test_name)
2460+ c.check_policy_groups_push_helpers()
2461+ report = c.click_report
2462+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2463+ self.check_results(report, expected_counts)
2464+
2465 def test_check_policy_groups_pushhelper_missing(self):
2466 '''Test check_policy_groups_pushhelper - missing'''
2467 self.set_test_push_helper(self.default_appname, "exec", "foo")
2468 self.set_test_security_manifest(self.default_appname,
2469 "policy_groups",
2470 None)
2471+ self.set_test_security_manifest(self.default_appname,
2472+ "template", "ubuntu-push-helper")
2473 c = ClickReviewSecurity(self.test_name)
2474 c.check_policy_groups_push_helpers()
2475 report = c.click_report
2476@@ -1001,6 +1072,8 @@
2477 ["video_files",
2478 "networking",
2479 "push-notification-client"])
2480+ self.set_test_security_manifest(self.default_appname,
2481+ "template", "ubuntu-push-helper")
2482 c = ClickReviewSecurity(self.test_name)
2483 c.check_policy_groups_push_helpers()
2484 report = c.click_report
2485@@ -1014,64 +1087,14 @@
2486 "policy_groups",
2487 ["networking",
2488 "push-notification-client"])
2489+ self.set_test_security_manifest(self.default_appname,
2490+ "template", "ubuntu-push-helper")
2491 c = ClickReviewSecurity(self.test_name)
2492 c.check_policy_groups_push_helpers()
2493 report = c.click_report
2494 expected_counts = {'info': None, 'warn': 0, 'error': 1}
2495 self.check_results(report, expected_counts)
2496
2497- def test_check_template_pushhelper(self):
2498- '''Test check_template_pushhelper'''
2499- self.set_test_push_helper(self.default_appname, "exec", "foo")
2500- self.set_test_security_manifest(self.default_appname,
2501- "template", "ubuntu-push-helper")
2502- self.set_test_security_manifest(self.default_appname,
2503- "policy_groups",
2504- ["push-notification-client"])
2505- c = ClickReviewSecurity(self.test_name)
2506- c.check_template_push_helpers()
2507- report = c.click_report
2508- expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2509- self.check_results(report, expected_counts)
2510-
2511- def test_check_template_pushhelper_no_hook(self):
2512- '''Test check_template_pushhelper'''
2513- self.set_test_security_manifest(self.default_appname,
2514- "template", "ubuntu-sdk")
2515- c = ClickReviewSecurity(self.test_name)
2516- c.check_template_push_helpers()
2517- report = c.click_report
2518- expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2519- self.check_results(report, expected_counts)
2520-
2521- def test_check_template_pushhelper_wrong_template(self):
2522- '''Test check_template_pushhelper - wrong template'''
2523- self.set_test_push_helper(self.default_appname, "exec", "foo")
2524- self.set_test_security_manifest(self.default_appname,
2525- "template", "ubuntu-webapp")
2526- self.set_test_security_manifest(self.default_appname,
2527- "policy_groups",
2528- ["push-notification-client"])
2529- c = ClickReviewSecurity(self.test_name)
2530- c.check_template_push_helpers()
2531- report = c.click_report
2532- expected_counts = {'info': None, 'warn': 0, 'error': 1}
2533- self.check_results(report, expected_counts)
2534-
2535- def test_check_template_pushhelper_wrong_template2(self):
2536- '''Test check_template_pushhelper - default template'''
2537- self.set_test_push_helper(self.default_appname, "exec", "foo")
2538- self.set_test_security_manifest(self.default_appname,
2539- "template", None)
2540- self.set_test_security_manifest(self.default_appname,
2541- "policy_groups",
2542- ["push-notification-client"])
2543- c = ClickReviewSecurity(self.test_name)
2544- c.check_template_push_helpers()
2545- report = c.click_report
2546- expected_counts = {'info': None, 'warn': 0, 'error': 1}
2547- self.check_results(report, expected_counts)
2548-
2549 def test_check_peer_hooks(self):
2550 '''Test check_peer_hooks()'''
2551 c = ClickReviewSecurity(self.test_name)
2552@@ -1267,6 +1290,25 @@
2553 expected_counts = {'info': 5, 'warn': 0, 'error': 0}
2554 self.check_results(report, expected_counts)
2555
2556+ def test_check_apparmor_profile_1604(self):
2557+ '''Test check_apparmor_profile() - snappy 16.04'''
2558+ policy = '''
2559+###VAR###
2560+###PROFILEATTACH### {
2561+ #include <abstractions/base>
2562+ # Read-only for the install directory
2563+ @{CLICK_DIR}/@{APP_PKGNAME}/@{APP_VERSION}/** mrklix,
2564+ @{INSTALL_DIR}/@{APP_PKGNAME}/@{APP_VERSION}/** mrklix,
2565+}
2566+'''
2567+ self.set_test_security_profile(self.default_appname, policy)
2568+ c = ClickReviewSecurity(self.test_name)
2569+ self.set_test_pkgfmt("snap", "16.04")
2570+ c.check_apparmor_profile()
2571+ report = c.click_report
2572+ expected_counts = {'info': 6, 'warn': 0, 'error': 0}
2573+ self.check_results(report, expected_counts)
2574+
2575 def test_check_apparmor_profile_missing_var(self):
2576 '''Test check_apparmor_profile() - missing ###VAR###'''
2577 policy = '''
2578@@ -1366,6 +1408,30 @@
2579 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2580 self.check_results(report, expected_counts)
2581
2582+ def test_check_security_template_nondefault_1504(self):
2583+ '''Test check_security_template() - nondefault - 15.04'''
2584+ self.set_test_pkgfmt("snap", "15.04")
2585+ self.set_test_security_manifest(self.default_appname,
2586+ "template", "nondefault")
2587+ self._set_yaml_binary([('security-template', 'nondefault')])
2588+ c = ClickReviewSecurity(self.test_name)
2589+ c.check_security_template()
2590+ report = c.click_report
2591+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2592+ self.check_results(report, expected_counts)
2593+
2594+ def test_check_security_template_nondefault_1604(self):
2595+ '''Test check_security_template() - nondefault - 16.04'''
2596+ self.set_test_pkgfmt("snap", "16.04")
2597+ self.set_test_security_manifest(self.default_appname,
2598+ "template", "nondefault")
2599+ self._set_yaml_binary([('security-template', 'nondefault')])
2600+ c = ClickReviewSecurity(self.test_name)
2601+ c.check_security_template()
2602+ report = c.click_report
2603+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2604+ self.check_results(report, expected_counts)
2605+
2606 def test_check_security_template_bad(self):
2607 '''Test check_security_template() - {}'''
2608 self._set_yaml_binary([('security-template', {})])
2609@@ -1455,6 +1521,33 @@
2610 expected_counts = {'info': 5, 'warn': 0, 'error': 0}
2611 self.check_results(report, expected_counts)
2612
2613+ def test_check_security_yaml_and_click_snappy_1504(self):
2614+ '''Test check_security_yaml_and_click() - snappy 15.04'''
2615+ self.set_test_pkgfmt("snap", "15.04")
2616+ self._set_yaml_binary([('caps', ['networking'])],
2617+ name="bin/%s" % self.default_appname)
2618+ c = ClickReviewSecurity(self.test_name)
2619+
2620+ # update the manifest and test_manifest
2621+ c.manifest["hooks"][self.default_appname]['bin-path'] = "bin/path"
2622+
2623+ c.check_security_yaml_and_click()
2624+ report = c.click_report
2625+ expected_counts = {'info': 5, 'warn': 0, 'error': 0}
2626+ self.check_results(report, expected_counts)
2627+
2628+ def test_check_security_yaml_and_click_snappy_1604(self):
2629+ '''Test check_security_yaml_and_click() - snappy 16.04'''
2630+ self.set_test_pkgfmt("snap", "16.04")
2631+ self._set_yaml_binary([('caps', ['networking'])],
2632+ name="bin/%s" % self.default_appname)
2633+ c = ClickReviewSecurity(self.test_name)
2634+
2635+ c.check_security_yaml_and_click()
2636+ report = c.click_report
2637+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2638+ self.check_results(report, expected_counts)
2639+
2640 def test_check_security_yaml_and_click_name_exec(self):
2641 '''Test check_security_yaml_and_click() - uses exec'''
2642 self._set_yaml_binary([('caps', ['networking']),
2643@@ -1923,6 +2016,28 @@
2644 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2645 self.check_results(report, expected_counts)
2646
2647+ def test_check_security_yaml_override_and_click_1504(self):
2648+ '''Test check_security_yaml_override_and_click() - 15.04'''
2649+ self.set_test_pkgfmt("snap", "15.04")
2650+ self.set_test_security_manifest(self.default_appname, "template", None)
2651+ self._set_yaml_binary([])
2652+ c = ClickReviewSecurity(self.test_name)
2653+ c.check_security_yaml_override_and_click()
2654+ report = c.click_report
2655+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2656+ self.check_results(report, expected_counts)
2657+
2658+ def test_check_security_yaml_override_and_click_1604(self):
2659+ '''Test check_security_yaml_override_and_click() - 16.04'''
2660+ self.set_test_pkgfmt("snap", "16.04")
2661+ self.set_test_security_manifest(self.default_appname, "template", None)
2662+ self._set_yaml_binary([])
2663+ c = ClickReviewSecurity(self.test_name)
2664+ c.check_security_yaml_override_and_click()
2665+ report = c.click_report
2666+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2667+ self.check_results(report, expected_counts)
2668+
2669 def test_check_security_yaml_override_and_click_bad(self):
2670 '''Test check_security_yaml_override_and_click() - bad'''
2671 self.set_test_security_manifest(self.default_appname, "template", None)
2672@@ -1945,8 +2060,31 @@
2673 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2674 self.check_results(report, expected_counts)
2675
2676+ def test_check_security_yaml_override_1504(self):
2677+ '''Test check_security_yaml_override() - 15.04'''
2678+ self.set_test_pkgfmt("snap", "15.04")
2679+ self.set_test_security_manifest(self.default_appname, "template", None)
2680+ self._set_yaml_binary([])
2681+ c = ClickReviewSecurity(self.test_name)
2682+ c.check_security_yaml_override()
2683+ report = c.click_report
2684+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2685+ self.check_results(report, expected_counts)
2686+
2687+ def test_check_security_yaml_override_1604(self):
2688+ '''Test check_security_yaml_override() - 16.04'''
2689+ self.set_test_pkgfmt("snap", "16.04")
2690+ self.set_test_security_manifest(self.default_appname, "template", None)
2691+ self._set_yaml_binary([])
2692+ c = ClickReviewSecurity(self.test_name)
2693+ c.check_security_yaml_override()
2694+ report = c.click_report
2695+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2696+ self.check_results(report, expected_counts)
2697+
2698 def test_check_security_yaml_override2(self):
2699 '''Test check_security_yaml_override() - seccomp/apparmor specified'''
2700+ self.set_test_pkgfmt("snap", "15.04")
2701 self._set_yaml_binary([('security-override', {'apparmor': 'aa',
2702 'seccomp': 'sc'})],
2703 name=self.default_appname)
2704@@ -1956,6 +2094,84 @@
2705 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2706 self.check_results(report, expected_counts)
2707
2708+ def test_check_security_yaml_override3(self):
2709+ '''Test check_security_yaml_override() - seccomp/apparmor specified
2710+ with 16.04
2711+ '''
2712+ self.set_test_pkgfmt("snap", "16.04")
2713+ self._set_yaml_binary([('security-override', {'apparmor': 'aa',
2714+ 'seccomp': 'sc'})],
2715+ name=self.default_appname)
2716+ c = ClickReviewSecurity(self.test_name)
2717+ c.check_security_yaml_override()
2718+ report = c.click_report
2719+ expected_counts = {'info': None, 'warn': 0, 'error': 2}
2720+ self.check_results(report, expected_counts)
2721+
2722+ def test_check_security_yaml_override4(self):
2723+ '''Test check_security_yaml_override() - syscalls specified with
2724+ 15.04
2725+ '''
2726+ self.set_test_pkgfmt("snap", "15.04")
2727+ self._set_yaml_binary([('security-override', {'syscalls': 'foo'})],
2728+ name=self.default_appname)
2729+ c = ClickReviewSecurity(self.test_name)
2730+ c.check_security_yaml_override()
2731+ report = c.click_report
2732+ expected_counts = {'info': None, 'warn': 0, 'error': 1}
2733+ self.check_results(report, expected_counts)
2734+
2735+ def test_check_security_yaml_override5(self):
2736+ '''Test check_security_yaml_override() - syscalls specified with
2737+ 16.04
2738+ '''
2739+ self.set_test_pkgfmt("snap", "16.04")
2740+ self._set_yaml_binary([('security-override', {'syscalls': 'foo'})],
2741+ name=self.default_appname)
2742+ c = ClickReviewSecurity(self.test_name)
2743+ c.check_security_yaml_override()
2744+ report = c.click_report
2745+ # the error is security-override not allowed
2746+ expected_counts = {'info': 1, 'warn': 0, 'error': 1}
2747+ self.check_results(report, expected_counts)
2748+
2749+ def test_check_security_yaml_override6(self):
2750+ '''Test check_security_yaml_override() - read-paths'''
2751+ self.set_test_pkgfmt("snap", "16.04")
2752+ self._set_yaml_binary([('security-override', {'read-paths': '/foo'})],
2753+ name=self.default_appname)
2754+ c = ClickReviewSecurity(self.test_name)
2755+ c.check_security_yaml_override()
2756+ report = c.click_report
2757+ # the error is security-override not allowed
2758+ expected_counts = {'info': 1, 'warn': 0, 'error': 1}
2759+ self.check_results(report, expected_counts)
2760+
2761+ def test_check_security_yaml_override7(self):
2762+ '''Test check_security_yaml_override() - write-paths'''
2763+ self.set_test_pkgfmt("snap", "16.04")
2764+ self._set_yaml_binary([('security-override', {'write-paths': '/foo'})],
2765+ name=self.default_appname)
2766+ c = ClickReviewSecurity(self.test_name)
2767+ c.check_security_yaml_override()
2768+ report = c.click_report
2769+ # the error is security-override not allowed
2770+ expected_counts = {'info': 1, 'warn': 0, 'error': 1}
2771+ self.check_results(report, expected_counts)
2772+
2773+ def test_check_security_yaml_override8(self):
2774+ '''Test check_security_yaml_override() - abstractions'''
2775+ self.set_test_pkgfmt("snap", "16.04")
2776+ self._set_yaml_binary([('security-override',
2777+ {'abstractions': '/foo'})],
2778+ name=self.default_appname)
2779+ c = ClickReviewSecurity(self.test_name)
2780+ c.check_security_yaml_override()
2781+ report = c.click_report
2782+ # the error is security-override not allowed
2783+ expected_counts = {'info': 1, 'warn': 0, 'error': 1}
2784+ self.check_results(report, expected_counts)
2785+
2786 def test_check_security_yaml_override_missing1(self):
2787 '''Test check_security_yaml_override() - missing apparmor'''
2788 self._set_yaml_binary([('security-override', {'seccomp': 'sc'})],
2789@@ -2049,6 +2265,34 @@
2790 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2791 self.check_results(report, expected_counts)
2792
2793+ def test_check_template_online_account_provider_1504(self):
2794+ '''Test check_template_online_account_provider - 15.04'''
2795+ self.set_test_pkgfmt("snap", "15.04")
2796+ self.set_test_account(self.default_appname, "account-provider", "foo")
2797+ self.set_test_security_manifest(self.default_appname,
2798+ "template", "ubuntu-account-plugin")
2799+ self.set_test_security_manifest(self.default_appname,
2800+ "policy_groups", ["accounts"])
2801+ c = ClickReviewSecurity(self.test_name)
2802+ c.check_template_online_accounts_provider()
2803+ report = c.click_report
2804+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2805+ self.check_results(report, expected_counts)
2806+
2807+ def test_check_template_online_account_provider_1604(self):
2808+ '''Test check_template_online_account_provider - 16.04'''
2809+ self.set_test_pkgfmt("snap", "16.04")
2810+ self.set_test_account(self.default_appname, "account-provider", "foo")
2811+ self.set_test_security_manifest(self.default_appname,
2812+ "template", "ubuntu-account-plugin")
2813+ self.set_test_security_manifest(self.default_appname,
2814+ "policy_groups", ["accounts"])
2815+ c = ClickReviewSecurity(self.test_name)
2816+ c.check_template_online_accounts_provider()
2817+ report = c.click_report
2818+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2819+ self.check_results(report, expected_counts)
2820+
2821 def test_check_template_online_account_provider_no_hook(self):
2822 '''Test check_template_online_account_provider'''
2823 self.set_test_security_manifest(self.default_appname,
2824@@ -2099,6 +2343,36 @@
2825 expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2826 self.check_results(report, expected_counts)
2827
2828+ def test_check_template_online_account_qml_plugin_1504(self):
2829+ '''Test check_template_online_account_qml_plugin - 15.04'''
2830+ self.set_test_pkgfmt("snap", "15.04")
2831+ self.set_test_account(self.default_appname,
2832+ "account-qml-plugin", "foo")
2833+ self.set_test_security_manifest(self.default_appname,
2834+ "template", "ubuntu-account-plugin")
2835+ self.set_test_security_manifest(self.default_appname,
2836+ "policy_groups", ["accounts"])
2837+ c = ClickReviewSecurity(self.test_name)
2838+ c.check_template_online_accounts_qml_plugin()
2839+ report = c.click_report
2840+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2841+ self.check_results(report, expected_counts)
2842+
2843+ def test_check_template_online_account_qml_plugin_1604(self):
2844+ '''Test check_template_online_account_qml_plugin - 16.04'''
2845+ self.set_test_pkgfmt("snap", "16.04")
2846+ self.set_test_account(self.default_appname,
2847+ "account-qml-plugin", "foo")
2848+ self.set_test_security_manifest(self.default_appname,
2849+ "template", "ubuntu-account-plugin")
2850+ self.set_test_security_manifest(self.default_appname,
2851+ "policy_groups", ["accounts"])
2852+ c = ClickReviewSecurity(self.test_name)
2853+ c.check_template_online_accounts_qml_plugin()
2854+ report = c.click_report
2855+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2856+ self.check_results(report, expected_counts)
2857+
2858 def test_check_template_online_account_qml_plugin_no_hook(self):
2859 '''Test check_template_online_account_qml_plugin'''
2860 self.set_test_security_manifest(self.default_appname,
2861@@ -2139,8 +2413,6 @@
2862
2863 def test_check_policy_groups_ubuntu_account_plugin_no_hook(self):
2864 '''Test check_policy_groups_ubuntu_account_plugin() - no hook'''
2865- self.set_test_security_manifest(self.default_appname,
2866- "template", "ubuntu-account-plugin")
2867 c = ClickReviewSecurity(self.test_name)
2868 c.check_policy_groups_ubuntu_account_plugin()
2869 report = c.click_report
2870
2871=== modified file 'clickreviews/tests/test_cr_url_dispatcher.py'
2872--- clickreviews/tests/test_cr_url_dispatcher.py 2015-10-16 02:54:07 +0000
2873+++ clickreviews/tests/test_cr_url_dispatcher.py 2015-12-01 15:03:49 +0000
2874@@ -255,3 +255,27 @@
2875 r = c.click_report
2876 expected_counts = {'info': None, 'warn': 0, 'error': 1}
2877 self.check_results(r, expected_counts)
2878+
2879+ def test_check_required_snappy_1504(self):
2880+ '''Test check_required() - has protocol - snappy 15.04'''
2881+ self.set_test_pkgfmt("snap", "15.04")
2882+ self.set_test_url_dispatcher(self.default_appname,
2883+ key="protocol",
2884+ value="some-protocol")
2885+ c = ClickReviewUrlDispatcher(self.test_name)
2886+ c.check_required()
2887+ r = c.click_report
2888+ expected_counts = {'info': 1, 'warn': 0, 'error': 0}
2889+ self.check_results(r, expected_counts)
2890+
2891+ def test_check_required_snappy_1604(self):
2892+ '''Test check_required() - has protocol - snappy 16.04'''
2893+ self.set_test_pkgfmt("snap", "16.04")
2894+ self.set_test_url_dispatcher(self.default_appname,
2895+ key="protocol",
2896+ value="some-protocol")
2897+ c = ClickReviewUrlDispatcher(self.test_name)
2898+ c.check_required()
2899+ r = c.click_report
2900+ expected_counts = {'info': 0, 'warn': 0, 'error': 0}
2901+ self.check_results(r, expected_counts)
2902
2903=== modified file 'clickreviews/tests/utils.py'
2904--- clickreviews/tests/utils.py 2015-10-21 22:12:25 +0000
2905+++ clickreviews/tests/utils.py 2015-12-01 15:03:49 +0000
2906@@ -22,31 +22,36 @@
2907 import tempfile
2908
2909
2910-def make_package(name='test', package_format='click', package_types=None,
2911- version='1.0', title="An application",
2912- framework='ubuntu-sdk-15.04', extra_files=None, output_dir=None):
2913+def make_package(name='test', pkgfmt_type='click', pkgfmt_version='0.4',
2914+ package_types=None, version='1.0', title="An application",
2915+ framework='ubuntu-sdk-15.04', extra_files=None,
2916+ output_dir=None):
2917 """Return the path to a click/snap package with the given data.
2918
2919 Caller is responsible for deleting the output_dir afterwards.
2920 """
2921- is_snap = (package_format == "snap")
2922+ is_snap = (pkgfmt_type == "snap")
2923 build_dir = tempfile.mkdtemp()
2924 package_types = package_types or []
2925
2926 try:
2927- make_dir_structure(build_dir, extra_files=extra_files)
2928+ make_dir_structure(build_dir, pkgfmt_type=pkgfmt_type,
2929+ pkgfmt_version=pkgfmt_version,
2930+ extra_files=extra_files)
2931 write_icon(build_dir)
2932- write_manifest(build_dir, name, version,
2933- title, framework, package_types,
2934- is_snap)
2935- if is_snap:
2936- write_meta_data(build_dir, name, version,
2937- title, framework)
2938- write_control(build_dir, name, version, title)
2939- write_preinst(build_dir)
2940- write_apparmor_profile(build_dir, name)
2941- write_other_files(build_dir)
2942- pkg_path = build_package(build_dir, name, version, package_format,
2943+
2944+ if pkgfmt_type == 'click' or pkgfmt_version == 15.04:
2945+ write_manifest(build_dir, name, version,
2946+ title, framework, package_types,
2947+ is_snap)
2948+ write_control(build_dir, name, version, title, pkgfmt_version)
2949+ write_preinst(build_dir)
2950+ write_apparmor_profile(build_dir, name)
2951+ write_other_files(build_dir)
2952+ else:
2953+ write_meta_data(build_dir, name, version, title, framework)
2954+
2955+ pkg_path = build_package(build_dir, name, version, pkgfmt_type,
2956 output_dir=output_dir)
2957 finally:
2958 shutil.rmtree(build_dir)
2959@@ -54,9 +59,12 @@
2960 return pkg_path
2961
2962
2963-def make_dir_structure(path, extra_files=None):
2964+def make_dir_structure(path, pkgfmt_type, pkgfmt_version, extra_files=None):
2965 extra_files = extra_files or []
2966- directories = ['DEBIAN', 'meta']
2967+ directories = ['meta']
2968+ if pkgfmt_type == 'click' or pkgfmt_version == 15.04:
2969+ directories.append('DEBIAN')
2970+
2971 directories.extend(
2972 [os.path.dirname(extra_file) for extra_file in extra_files])
2973
2974@@ -128,11 +136,11 @@
2975 f.write(title)
2976
2977
2978-def write_control(path, name, version, title):
2979+def write_control(path, name, version, title, pkgfmt_version):
2980 control_path = os.path.join(path, 'DEBIAN', 'control')
2981 control_content = {'Package': name,
2982 'Version': version,
2983- 'Click-Version': '0.4',
2984+ 'Click-Version': pkgfmt_version,
2985 'Architecture': 'all',
2986 'Maintainer': 'Someone <someone@example.com>',
2987 'Installed-Size': '123',
2988
2989=== modified file 'debian/changelog'
2990--- debian/changelog 2015-12-01 14:44:03 +0000
2991+++ debian/changelog 2015-12-01 15:03:49 +0000
2992@@ -19,8 +19,37 @@
2993 - 'Maintainer' checks in the click manifest should only be done with click
2994 packages (LP: #1510522)
2995 - don't prompt manual review when find .excludes file
2996+ - add kernel and os as valid snap types
2997+ - remove package filename checks. They were meaningless and hard to
2998+ maintain
2999+ - sort unknown snappy yaml keys
3000+ * clickreviews/cr_common.py:
3001+ - add valid yaml keys for kernel snaps
3002 * update data/apparmor-easyprof-ubuntu.json for 16.04 policy
3003 * Makefile: add json syntax check
3004+ * several changes for squashfs snaps that won't have a click manifest, etc.
3005+ Importantly, this means that only package.yaml is looked at and a lot of
3006+ click specific tests can be skipped
3007+ - cr_common.py:
3008+ + rename a few variable to not be click specific
3009+ + add self.pkgfmt
3010+ + adjust __init__() to conditionally use package.yaml on squashfs,
3011+ otherwise click manifest
3012+ + make click data structure initialization conditional on if click
3013+ or not (eg, don't run hooks code on squashfs images)
3014+ - adjust clickreviews/cr_* to conditionally run certain click-only tests
3015+ on click packages
3016+ - adjust architecture checks to use self.pkg_arch and rename
3017+ control_architecture_specified_needed as architecture_specified_needed
3018+ - cr_security.py:
3019+ + revamp to use package.yaml on non-click instead of now nonexistent
3020+ security manifest
3021+ + update push-helper template test to not make hooks specific
3022+ + network-client should not be allowed with push helpers either
3023+ + conditionally look for INSTALL_DIR on 16.04 systems in security-policy
3024+ + adjust security-override checks on 16.04 to follow 16.04 yaml
3025+ + make click manifest checks conditional on if click
3026+ - cr_tests.py: mock _pkgfmt_type(), _pkgfmt_version() and _is_squashfs()
3027
3028 [ Michael Nelson ]
3029 * add support for non-mocked tests

Subscribers

People subscribed via source and target branches