Merge lp:~larryprice/libertine/new-list-apps into lp:libertine
- new-list-apps
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Christopher Townsend |
Approved revision: | 393 |
Merged at revision: | 392 |
Proposed branch: | lp:~larryprice/libertine/new-list-apps |
Merge into: | lp:libertine |
Diff against target: |
654 lines (+20/-438) 16 files modified
debian/python3-libertine.install (+0/-1) python/libertine/AppDiscovery.py (+0/-220) python/libertine/Libertine.py (+0/-18) python/libertine/service/container.py (+0/-9) python/libertine/service/manager.py (+0/-7) python/libertine/service/task_dispatcher.py (+0/-4) python/libertine/service/tasks/__init__.py (+0/-2) python/libertine/service/tasks/list_apps_task.py (+0/-34) tests/integration/test_libertine_service.py (+1/-2) tests/unit/service/tasks/CMakeLists.txt (+0/-1) tests/unit/service/tasks/test_list_app_ids_task.py (+1/-1) tests/unit/service/tasks/test_list_apps_task.py (+0/-59) tests/unit/service/test_container.py (+3/-11) tests/unit/service/test_task_dispatcher.py (+7/-14) tests/unit/test_app_discovery.py (+0/-52) tools/libertine-container-manager (+8/-3) |
To merge this branch: | bzr merge lp:~larryprice/libertine/new-list-apps |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christopher Townsend | Approve | ||
Libertine CI Bot | continuous-integration | Approve | |
Review via email: mp+316556@code.launchpad.net |
Commit message
Migrate the list-apps subcommand to list application ids.
Description of the change
Migrate the list-apps subcommand to list application ids.
Libertine CI Bot (libertine-ci-bot) wrote : | # |
- 392. By Larry Price
-
missed a spot
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:392
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 393. By Larry Price
-
test method was using wrong dbus service giving false positive
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:393
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'debian/python3-libertine.install' |
2 | --- debian/python3-libertine.install 2017-01-31 18:21:43 +0000 |
3 | +++ debian/python3-libertine.install 2017-02-07 13:30:52 +0000 |
4 | @@ -1,4 +1,3 @@ |
5 | -usr/lib/python*/*/libertine/AppDiscovery.py |
6 | usr/lib/python*/*/libertine/ContainersConfig.py |
7 | usr/lib/python*/*/libertine/HostInfo.py |
8 | usr/lib/python*/*/libertine/Libertine.py |
9 | |
10 | === removed file 'python/libertine/AppDiscovery.py' |
11 | --- python/libertine/AppDiscovery.py 2017-01-17 21:46:43 +0000 |
12 | +++ python/libertine/AppDiscovery.py 1970-01-01 00:00:00 +0000 |
13 | @@ -1,220 +0,0 @@ |
14 | -# Copyright 2015 Canonical Ltd. |
15 | -# |
16 | -# This program is free software: you can redistribute it and/or modify it |
17 | -# under the terms of the GNU General Public License version 3, as published |
18 | -# by the Free Software Foundation. |
19 | -# |
20 | -# This program is distributed in the hope that it will be useful, but |
21 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
22 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
23 | -# PURPOSE. See the GNU General Public License for more details. |
24 | -# |
25 | -# You should have received a copy of the GNU General Public License along |
26 | -# with this program. If not, see <http://www.gnu.org/licenses/>. |
27 | - |
28 | -from . import utils |
29 | -from xdg.BaseDirectory import xdg_data_dirs |
30 | -import configparser |
31 | -import glob |
32 | -import io |
33 | -import json |
34 | -import os |
35 | -import re |
36 | -import sys |
37 | - |
38 | - |
39 | -class IconCache(object): |
40 | - """ |
41 | - Caches the names of all icon files available in the standard places (possibly |
42 | - in a container) and provides a search function to deliver icon file names |
43 | - matching a given icon name. |
44 | - |
45 | - See the `Freedesktop.org icon theme specification |
46 | - <http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html>`_ |
47 | - for the detailed specification. |
48 | - """ |
49 | - |
50 | - def __init__(self, root_path, file_loader=None): |
51 | - """ |
52 | - :param root_path: Where to start the file scan. |
53 | - :type root_path: A valid filesystem path string. |
54 | - :param file_loader: A function that builds a cache of filenames. |
55 | - :type file_loader: Function returning a list of filenames. |
56 | - """ |
57 | - if file_loader: |
58 | - self._icon_cache = file_loader(root_path) |
59 | - else: |
60 | - self._icon_cache = self._file_loader(root_path) |
61 | - |
62 | - def _get_icon_search_paths(self, root_path): |
63 | - """ |
64 | - Gets a list of paths on which to search for icons. |
65 | - |
66 | - :param root_path: Where to start the file scan. |
67 | - :type root_path: A valid filesystem path string. |
68 | - :rtype: A list of filesystem patch to serarch for qualifying icon files. |
69 | - """ |
70 | - icon_search_paths = [] |
71 | - icon_search_paths.append(os.path.join(root_path, os.environ['HOME'], ".icons")) |
72 | - for d in reversed(xdg_data_dirs): |
73 | - icon_search_paths.append(os.path.join(root_path, d.lstrip('/'), "icons")) |
74 | - icon_search_paths.append(os.path.join(root_path, "usr/share/pixmaps")) |
75 | - return icon_search_paths |
76 | - |
77 | - def _file_loader(self, root_path): |
78 | - """ |
79 | - Loads a cache of file names by scanning the filesystem rooted at |
80 | - ``root_path``. |
81 | - |
82 | - :param root_path: Where to start the file scan. |
83 | - :type root_path: A valid filesystem path. |
84 | - :rtype: A list of fully-qualified file paths. |
85 | - """ |
86 | - file_names = [] |
87 | - pattern = re.compile(r".*\.(png|svg|xpm)") |
88 | - for path in self._get_icon_search_paths(root_path): |
89 | - for base, dirs, files in os.walk(path): |
90 | - for file in files: |
91 | - if pattern.match(file): |
92 | - file_names.append(os.path.join(base, file)) |
93 | - return file_names |
94 | - |
95 | - def _find_icon_files(self, icon_name): |
96 | - """ |
97 | - Finds a list of file name strings matching the given icon name. |
98 | - |
99 | - :param icon_name: An icon name, pobably from a .desktop file. |
100 | - :rtype: A list of filename strings matching the icon name. |
101 | - """ |
102 | - icon_file_names = [] |
103 | - match_string = r"/" + os.path.splitext(icon_name)[0] + r"\....$" |
104 | - pattern = re.compile(match_string) |
105 | - for icon_file in self._icon_cache: |
106 | - if pattern.search(icon_file): |
107 | - icon_file_names.append(icon_file) |
108 | - return icon_file_names |
109 | - |
110 | - def expand_icons(self, desktop_icon_list): |
111 | - """ |
112 | - Expands a string containing a list of icon names into a list of matching |
113 | - file names. |
114 | - |
115 | - :param desktop_icon_list: A string containing a list of icon names |
116 | - separated by semicolons. |
117 | - :rtype: A list of filename stings matching the icon names passed in. |
118 | - |
119 | - See `the Freedesktop.org desktop file specification |
120 | - <http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#recognized-keys>`_ |
121 | - for more information. |
122 | - """ |
123 | - if desktop_icon_list: |
124 | - icon_list = desktop_icon_list.split(';') |
125 | - if icon_list[0][0] == '/': |
126 | - return icon_list |
127 | - icon_files = [] |
128 | - for i in icon_list: |
129 | - icon_files += self._find_icon_files(i) |
130 | - return icon_files |
131 | - return [] |
132 | - |
133 | - |
134 | -def expand_mime_types(desktop_mime_types): |
135 | - if desktop_mime_types: |
136 | - return desktop_mime_types.split(';') |
137 | - return [] |
138 | - |
139 | - |
140 | -class AppInfo(object): |
141 | - |
142 | - def __init__(self, desktop_file_name, config_entry, icon_cache): |
143 | - self.desktop_file_name = desktop_file_name |
144 | - self.name = config_entry.get('Name') |
145 | - if not self.name: |
146 | - raise RuntimeError("required Name attribute is missing") |
147 | - d = config_entry.get('NoDisplay') |
148 | - self.no_display = (d != None and d == 'true') |
149 | - self.exec_line = config_entry.get('Exec') |
150 | - if not self.exec_line: |
151 | - raise RuntimeError("required Exec attribute is missing") |
152 | - self.icons = icon_cache.expand_icons(config_entry.get('Icon')) |
153 | - self.mime_types = expand_mime_types(config_entry.get('MimeType')) |
154 | - |
155 | - def __str__(self): |
156 | - with io.StringIO() as ostr: |
157 | - print(self.name, file=ostr) |
158 | - print(" desktop_file={}".format(self.desktop_file_name), file=ostr) |
159 | - print(" no-display={}".format(self.no_display), file=ostr) |
160 | - print(" exec='{}'".format(self.exec_line), file=ostr) |
161 | - for icon in self.icons: |
162 | - print(" icon: {}".format(icon), file=ostr) |
163 | - for mime in self.mime_types: |
164 | - print(" mime: {}".format(mime), file=ostr) |
165 | - return ostr.getvalue() |
166 | - |
167 | - def to_json(self): |
168 | - return json.dumps(self.__dict__) |
169 | - |
170 | - |
171 | -def desktop_file_is_showable(desktop_entry): |
172 | - """ |
173 | - Determines if a particular application entry should be reported: the entry |
174 | - can not be hidden and must be showable in Unity. |
175 | - """ |
176 | - t = desktop_entry.get('Type') |
177 | - if t != 'Application': |
178 | - return False |
179 | - n = desktop_entry.get('Hidden') |
180 | - if n and n == 'true': |
181 | - return False |
182 | - n = desktop_entry.get('NoShowIn') |
183 | - if n: |
184 | - targets = n.split(';') |
185 | - if 'Unity' in targets: |
186 | - return False |
187 | - n = desktop_entry.get('OnlyShowIn') |
188 | - if n: |
189 | - targets = n.split(';') |
190 | - if 'Unity' not in targets: |
191 | - return False |
192 | - return True |
193 | - |
194 | - |
195 | -def get_app_info(desktop_path, icon_cache): |
196 | - for desktop_file_name in glob.glob(desktop_path): |
197 | - desktop_file = configparser.ConfigParser(strict=False, interpolation=None) |
198 | - try: |
199 | - desktop_file.read(desktop_file_name) |
200 | - desktop_entry = desktop_file['Desktop Entry'] |
201 | - if desktop_file_is_showable(desktop_entry): |
202 | - yield AppInfo(desktop_file_name, desktop_entry, icon_cache) |
203 | - except Exception as ex: |
204 | - utils.get_logger().error("error processing {}: {}".format(desktop_file_name, ex)) |
205 | - |
206 | - |
207 | -class AppLauncherCache(object): |
208 | - """ |
209 | - Caches a list of application launcher information (derived from .desktop |
210 | - files installed in a container. |
211 | - """ |
212 | - |
213 | - def __init__(self, name, root_path): |
214 | - self.name = name |
215 | - self.app_launchers = [] |
216 | - icon_cache = IconCache(root_path) |
217 | - for dir in reversed(xdg_data_dirs): |
218 | - path = os.path.join(root_path, dir.lstrip('/'), "applications") |
219 | - for app_info in get_app_info(os.path.join(path, "*.desktop"), icon_cache): |
220 | - self.app_launchers.append(app_info) |
221 | - |
222 | - def __str__(self): |
223 | - with io.StringIO() as ostr: |
224 | - print("{}\n".format(self.name), file=ostr) |
225 | - for app_info in self.app_launchers: |
226 | - print(" {}".format(app_info), file=ostr) |
227 | - return ostr.getvalue() |
228 | - |
229 | - def to_json(self): |
230 | - return json.dumps(self, |
231 | - default=lambda o: o.__dict__, |
232 | - sort_keys=True, |
233 | - indent=4) |
234 | |
235 | === modified file 'python/libertine/Libertine.py' |
236 | --- python/libertine/Libertine.py 2017-02-01 21:13:14 +0000 |
237 | +++ python/libertine/Libertine.py 2017-02-07 13:30:52 +0000 |
238 | @@ -12,7 +12,6 @@ |
239 | # You should have received a copy of the GNU General Public License along |
240 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
241 | |
242 | -from .AppDiscovery import AppLauncherCache |
243 | import abc |
244 | import contextlib |
245 | import os |
246 | @@ -525,23 +524,6 @@ |
247 | """ |
248 | self.container.finish_application(app) |
249 | |
250 | - def list_app_launchers(self, use_json=False): |
251 | - """ |
252 | - Enumerates all application launchers (based on .desktop files) available |
253 | - in the container. |
254 | - |
255 | - :param use_json: Indicates the returned string should be in JSON format. |
256 | - The default format is some human-readble format. |
257 | - :rtype: A printable string containing a list of application launchers |
258 | - available in the container. |
259 | - """ |
260 | - if use_json: |
261 | - return AppLauncherCache(self.container.name, |
262 | - self.container.root_path).to_json() |
263 | - else: |
264 | - return str(AppLauncherCache(self.container.name, |
265 | - self.container.root_path)) |
266 | - |
267 | def list_app_ids(self): |
268 | """ |
269 | Finds application ids (based on .desktop files) available in the |
270 | |
271 | === modified file 'python/libertine/service/container.py' |
272 | --- python/libertine/service/container.py 2017-01-24 16:03:25 +0000 |
273 | +++ python/libertine/service/container.py 2017-02-07 13:30:52 +0000 |
274 | @@ -144,15 +144,6 @@ |
275 | task.start() |
276 | return task.id |
277 | |
278 | - def list_apps(self): |
279 | - utils.get_logger().debug("List all apps in container '%s'" % self.id) |
280 | - |
281 | - task = ListAppsTask(self.id, self._config, self._connection, self._cleanup_task) |
282 | - |
283 | - self._tasks.append(task) |
284 | - task.start() |
285 | - return task.id |
286 | - |
287 | def list_app_ids(self): |
288 | utils.get_logger().debug("List all app ids in container '%s'" % self.id) |
289 | |
290 | |
291 | === modified file 'python/libertine/service/manager.py' |
292 | --- python/libertine/service/manager.py 2017-01-31 19:24:32 +0000 |
293 | +++ python/libertine/service/manager.py 2017-02-07 13:30:52 +0000 |
294 | @@ -69,13 +69,6 @@ |
295 | @dbus.service.method(LIBERTINE_MANAGER_INTERFACE, |
296 | in_signature='s', |
297 | out_signature='o') |
298 | - def list_apps(self, container_id): |
299 | - utils.get_logger().debug("list_apps('{}')".format(container_id)) |
300 | - return self._dispatcher.list_apps(container_id) |
301 | - |
302 | - @dbus.service.method(LIBERTINE_MANAGER_INTERFACE, |
303 | - in_signature='s', |
304 | - out_signature='o') |
305 | def list_app_ids(self, container_id): |
306 | utils.get_logger().debug("list_app_ids('{}')".format(container_id)) |
307 | return self._dispatcher.list_app_ids(container_id) |
308 | |
309 | === modified file 'python/libertine/service/task_dispatcher.py' |
310 | --- python/libertine/service/task_dispatcher.py 2017-01-24 18:00:57 +0000 |
311 | +++ python/libertine/service/task_dispatcher.py 2017-02-07 13:30:52 +0000 |
312 | @@ -84,10 +84,6 @@ |
313 | utils.get_logger().debug("dispatching update container '%s'" % container_id) |
314 | return self._find_or_create_container(container_id).update() |
315 | |
316 | - def list_apps(self, container_id): |
317 | - utils.get_logger().debug("dispatching list all apps in container '%s'" % container_id) |
318 | - return self._find_or_create_container(container_id).list_apps() |
319 | - |
320 | def list_app_ids(self, container_id): |
321 | utils.get_logger().debug("dispatching list apps ids in container '%s'" % container_id) |
322 | return self._find_or_create_container(container_id).list_app_ids() |
323 | |
324 | === modified file 'python/libertine/service/tasks/__init__.py' |
325 | --- python/libertine/service/tasks/__init__.py 2017-01-24 18:00:57 +0000 |
326 | +++ python/libertine/service/tasks/__init__.py 2017-02-07 13:30:52 +0000 |
327 | @@ -22,7 +22,6 @@ |
328 | from .search_task import SearchTask |
329 | from .update_task import UpdateTask |
330 | from .list_task import ListTask |
331 | -from .list_apps_task import ListAppsTask |
332 | from .list_app_ids_task import ListAppIdsTask |
333 | |
334 | __all__ = [ |
335 | @@ -36,6 +35,5 @@ |
336 | 'SearchTask', |
337 | 'UpdateTask', |
338 | 'ListTask', |
339 | - 'ListAppsTask', |
340 | 'ListAppIdsTask' |
341 | ] |
342 | |
343 | === removed file 'python/libertine/service/tasks/list_apps_task.py' |
344 | --- python/libertine/service/tasks/list_apps_task.py 2017-01-11 17:28:54 +0000 |
345 | +++ python/libertine/service/tasks/list_apps_task.py 1970-01-01 00:00:00 +0000 |
346 | @@ -1,34 +0,0 @@ |
347 | -# Copyright 2016-2017 Canonical Ltd. |
348 | -# |
349 | -# This program is free software: you can redistribute it and/or modify |
350 | -# it under the terms of the GNU General Public License as published by |
351 | -# the Free Software Foundation; version 3 of the License. |
352 | -# |
353 | -# This program is distributed in the hope that it will be useful, |
354 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
355 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
356 | -# GNU General Public License for more details. |
357 | -# |
358 | -# You should have received a copy of the GNU General Public License |
359 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
360 | - |
361 | - |
362 | -from .base_task import BaseTask |
363 | -from libertine import LibertineContainer, utils |
364 | - |
365 | - |
366 | -class ListAppsTask(BaseTask): |
367 | - def __init__(self, container_id, config, connection, callback): |
368 | - super().__init__(lock=None, container_id=container_id, config=config, connection=connection, callback=callback) |
369 | - |
370 | - def _run(self): |
371 | - utils.get_logger().debug("Listing apps in container '%s'" % self._container) |
372 | - container = LibertineContainer(self._container, self._config) |
373 | - self._progress.data(str(container.list_app_launchers(use_json=True))) |
374 | - |
375 | - def _before(self): |
376 | - if not self._config.container_exists(self._container): |
377 | - self._progress.error("Container '%s' does not exist, skipping list" % self._container) |
378 | - return False |
379 | - |
380 | - return True |
381 | |
382 | === modified file 'tests/integration/test_libertine_service.py' |
383 | --- tests/integration/test_libertine_service.py 2017-01-24 18:00:57 +0000 |
384 | +++ tests/integration/test_libertine_service.py 2017-02-07 13:30:52 +0000 |
385 | @@ -147,8 +147,7 @@ |
386 | config = ContainersConfig() |
387 | |
388 | self._send(lambda: self._libertined.create('jarjar', 'JarJar Binks', 'xenial', 'mock')) |
389 | - self.assertEqual({'name': 'JarJar Binks', 'app_launchers': []}, |
390 | - ast.literal_eval(self._send(lambda: self._libertined.list_apps('jarjar')))) |
391 | + self.assertEqual([], ast.literal_eval(self._send(lambda: self._libertined.list_app_ids('jarjar')))) |
392 | |
393 | self._send(lambda: self._libertined.install('jarjar', 'the-force')) |
394 | config.refresh_database() |
395 | |
396 | === modified file 'tests/unit/service/tasks/CMakeLists.txt' |
397 | --- tests/unit/service/tasks/CMakeLists.txt 2017-01-20 18:30:21 +0000 |
398 | +++ tests/unit/service/tasks/CMakeLists.txt 2017-02-07 13:30:52 +0000 |
399 | @@ -4,7 +4,6 @@ |
400 | create_service_unit_test(test_destroy_task) |
401 | create_service_unit_test(test_install_task) |
402 | create_service_unit_test(test_list_task) |
403 | -create_service_unit_test(test_list_apps_task) |
404 | create_service_unit_test(test_list_app_ids_task) |
405 | create_service_unit_test(test_remove_task) |
406 | create_service_unit_test(test_search_task) |
407 | |
408 | === modified file 'tests/unit/service/tasks/test_list_app_ids_task.py' |
409 | --- tests/unit/service/tasks/test_list_app_ids_task.py 2017-01-20 18:30:21 +0000 |
410 | +++ tests/unit/service/tasks/test_list_app_ids_task.py 2017-02-07 13:30:52 +0000 |
411 | @@ -36,7 +36,7 @@ |
412 | task = tasks.ListAppIdsTask('palpatine', self.config, self.connection, self.callback) |
413 | task._instant_callback = True |
414 | |
415 | - with unittest.mock.patch('libertine.service.tasks.list_apps_task.LibertineContainer') as MockContainer: |
416 | + with unittest.mock.patch('libertine.service.tasks.list_app_ids_task.LibertineContainer') as MockContainer: |
417 | task.start().join() |
418 | |
419 | progress.error.assert_called_once_with('Container \'palpatine\' does not exist, skipping list') |
420 | |
421 | === removed file 'tests/unit/service/tasks/test_list_apps_task.py' |
422 | --- tests/unit/service/tasks/test_list_apps_task.py 2016-11-07 18:51:17 +0000 |
423 | +++ tests/unit/service/tasks/test_list_apps_task.py 1970-01-01 00:00:00 +0000 |
424 | @@ -1,59 +0,0 @@ |
425 | -# Copyright 2016 Canonical Ltd. |
426 | -# |
427 | -# This program is free software: you can redistribute it and/or modify it |
428 | -# under the terms of the GNU General Public License version 3, as published |
429 | -# by the Free Software Foundation. |
430 | -# |
431 | -# This program is distributed in the hope that it will be useful, but |
432 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
433 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
434 | -# PURPOSE. See the GNU General Public License for more details. |
435 | -# |
436 | -# You should have received a copy of the GNU General Public License along |
437 | -# with this program. If not, see <http://www.gnu.org/licenses/>. |
438 | - |
439 | - |
440 | -import unittest.mock |
441 | -from unittest import TestCase |
442 | -from libertine.service import tasks |
443 | -from libertine.ContainersConfig import ContainersConfig |
444 | - |
445 | - |
446 | -class TestListAppsTask(TestCase): |
447 | - def setUp(self): |
448 | - self.config = unittest.mock.create_autospec(ContainersConfig) |
449 | - self.connection = unittest.mock.Mock() |
450 | - self.lock = unittest.mock.MagicMock() |
451 | - self.called_with = None |
452 | - |
453 | - def callback(self, task): |
454 | - self.called_with = task |
455 | - |
456 | - def test_sends_error_on_non_existent_container(self): |
457 | - self.config.container_exists.return_value = False |
458 | - with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress: |
459 | - progress = MockProgress.return_value |
460 | - task = tasks.ListAppsTask('palpatine', self.config, self.connection, self.callback) |
461 | - task._instant_callback = True |
462 | - |
463 | - with unittest.mock.patch('libertine.service.tasks.list_apps_task.LibertineContainer') as MockContainer: |
464 | - task.start().join() |
465 | - |
466 | - progress.error.assert_called_once_with('Container \'palpatine\' does not exist, skipping list') |
467 | - self.assertEqual(task, self.called_with) |
468 | - |
469 | - def test_successfully_lists_apps(self): |
470 | - self.config.container_exists.return_value = True |
471 | - with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress: |
472 | - progress = MockProgress.return_value |
473 | - progress.done = False |
474 | - task = tasks.ListAppsTask('palpatine', self.config, self.connection, self.callback) |
475 | - task._instant_callback = True |
476 | - |
477 | - with unittest.mock.patch('libertine.service.tasks.list_apps_task.LibertineContainer') as MockContainer: |
478 | - MockContainer.return_value.list_app_launchers.return_value = 'jarjar\nsidius' |
479 | - task.start().join() |
480 | - |
481 | - progress.finished.assert_called_once_with('palpatine') |
482 | - progress.data.assert_called_once_with('jarjar\nsidius') |
483 | - self.assertEqual(task, self.called_with) |
484 | |
485 | === modified file 'tests/unit/service/test_container.py' |
486 | --- tests/unit/service/test_container.py 2017-01-20 20:51:27 +0000 |
487 | +++ tests/unit/service/test_container.py 2017-02-07 13:30:52 +0000 |
488 | @@ -149,21 +149,13 @@ |
489 | MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
490 | MockUpdateTask.return_value.start.assert_called_once_with() |
491 | |
492 | - def test_list_apps_creates_list_apps_task(self): |
493 | - with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
494 | - c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
495 | - with unittest.mock.patch('libertine.service.container.ListAppsTask') as MockListAppsTask: |
496 | - c.list_apps() |
497 | - MockListAppsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY) |
498 | - MockListAppsTask.return_value.start.assert_called_once_with() |
499 | - |
500 | def test_list_app_ids_creates_list_app_ids_task(self): |
501 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
502 | c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
503 | - with unittest.mock.patch('libertine.service.container.ListAppIdsTask') as MockListAppsTask: |
504 | + with unittest.mock.patch('libertine.service.container.ListAppIdsTask') as MockListAppIdsTask: |
505 | c.list_app_ids() |
506 | - MockListAppsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY) |
507 | - MockListAppsTask.return_value.start.assert_called_once_with() |
508 | + MockListAppIdsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY) |
509 | + MockListAppIdsTask.return_value.start.assert_called_once_with() |
510 | |
511 | def test_removes_task_during_callback(self): |
512 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
513 | |
514 | === modified file 'tests/unit/service/test_task_dispatcher.py' |
515 | --- tests/unit/service/test_task_dispatcher.py 2017-01-20 20:51:27 +0000 |
516 | +++ tests/unit/service/test_task_dispatcher.py 2017-02-07 13:30:52 +0000 |
517 | @@ -76,14 +76,7 @@ |
518 | self.assertEqual(123, self._dispatcher.update('palpatine')) |
519 | c.update.assert_called_once_with() |
520 | |
521 | - def test_list_apps_calls_list_apps_on_container(self): |
522 | - with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
523 | - c = MockContainer.return_value |
524 | - c.list_apps.return_value = 123 |
525 | - self.assertEqual(123, self._dispatcher.list_apps('palpatine')) |
526 | - c.list_apps.assert_called_once_with() |
527 | - |
528 | - def test_list_apps_calls_list_apps_on_container(self): |
529 | + def test_list_app_ids_calls_list_app_ids_on_container(self): |
530 | with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
531 | c = MockContainer.return_value |
532 | c.list_app_ids.return_value = 123 |
533 | @@ -94,20 +87,20 @@ |
534 | with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
535 | c = MockContainer.return_value |
536 | c.id = 'palpatine' |
537 | - self._dispatcher.list_apps('palpatine') |
538 | - self._dispatcher.list_apps('palpatine') |
539 | - self._dispatcher.list_apps('palpatine') |
540 | + self._dispatcher.list_app_ids('palpatine') |
541 | + self._dispatcher.list_app_ids('palpatine') |
542 | + self._dispatcher.list_app_ids('palpatine') |
543 | MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
544 | |
545 | def test_container_callback_removes_container(self): |
546 | with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
547 | c = MockContainer.return_value |
548 | c.id = 'palpatine' |
549 | - self._dispatcher.list_apps('palpatine') |
550 | + self._dispatcher.list_app_ids('palpatine') |
551 | MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
552 | name, args, kwargs = MockContainer.mock_calls[0] |
553 | args[len(args)-1](MockContainer.return_value) |
554 | - self._dispatcher.list_apps('palpatine') |
555 | + self._dispatcher.list_app_ids('palpatine') |
556 | MockContainer.assert_has_calls([ # verify container constructed twice |
557 | unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY), |
558 | unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
559 | @@ -128,7 +121,7 @@ |
560 | c = MockContainer.return_value |
561 | c.tasks = [1, 2, 3] |
562 | c.id = 'palpatine' |
563 | - self._dispatcher.list_apps('palpatine') # creates container |
564 | + self._dispatcher.list_app_ids('palpatine') # creates container |
565 | self._dispatcher.container_info('palpatine') |
566 | MockContainerInfoTask.assert_called_once_with('palpatine', [1, 2, 3], unittest.mock.ANY, self._connection, unittest.mock.ANY) |
567 | task.start.assert_called_once_with() |
568 | |
569 | === removed file 'tests/unit/test_app_discovery.py' |
570 | --- tests/unit/test_app_discovery.py 2015-12-22 17:28:10 +0000 |
571 | +++ tests/unit/test_app_discovery.py 1970-01-01 00:00:00 +0000 |
572 | @@ -1,52 +0,0 @@ |
573 | -"""Unit tests for the AppLauncher module.""" |
574 | -# Copyright 2015 Canonical Ltd. |
575 | -# |
576 | -# This program is free software: you can redistribute it and/or modify it |
577 | -# under the terms of the GNU General Public License version 3, as published |
578 | -# by the Free Software Foundation. |
579 | -# |
580 | -# This program is distributed in the hope that it will be useful, but |
581 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
582 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
583 | -# PURPOSE. See the GNU General Public License for more details. |
584 | -# |
585 | -# You should have received a copy of the GNU General Public License along |
586 | -# with this program. If not, see <http://www.gnu.org/licenses/>. |
587 | - |
588 | -from libertine.AppDiscovery import IconCache |
589 | -from testtools import TestCase |
590 | -from testtools.matchers import Equals |
591 | - |
592 | - |
593 | -class TestIconSearching(TestCase): |
594 | - |
595 | - def mock_file_loader(self, root_path): |
596 | - return [ |
597 | - "/some/path/128x128/icon.png", |
598 | - "/somepath/icon.png", |
599 | - "/somepath/testme.png" |
600 | - ]; |
601 | - |
602 | - def test_full_path(self): |
603 | - some_root = "/some_root" |
604 | - icon_cache = IconCache(some_root, file_loader=self.mock_file_loader) |
605 | - |
606 | - some_full_path = "/this/is/a/full/path" |
607 | - self.assertThat(icon_cache.expand_icons(some_full_path)[0], |
608 | - Equals(some_full_path)) |
609 | - |
610 | - def test_icon_name(self): |
611 | - some_root = "/some_root" |
612 | - icon_cache = IconCache(some_root, file_loader=self.mock_file_loader) |
613 | - |
614 | - some_icon_list = "testme" |
615 | - self.assertThat(icon_cache.expand_icons(some_icon_list)[0], |
616 | - Equals("/somepath/testme.png")) |
617 | - |
618 | - def test_edge_case_relative_file_name(self): |
619 | - some_root = "/some_root" |
620 | - icon_cache = IconCache(some_root, file_loader=self.mock_file_loader) |
621 | - |
622 | - some_icon_list = "testme.png" |
623 | - self.assertThat(icon_cache.expand_icons(some_icon_list)[0], |
624 | - Equals("/somepath/testme.png")) |
625 | |
626 | === modified file 'tools/libertine-container-manager' |
627 | --- tools/libertine-container-manager 2017-02-01 21:13:14 +0000 |
628 | +++ tools/libertine-container-manager 2017-02-07 13:30:52 +0000 |
629 | @@ -17,8 +17,9 @@ |
630 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
631 | |
632 | import argparse |
633 | +import getpass |
634 | +import json |
635 | import libertine.utils |
636 | -import getpass |
637 | import os |
638 | import sys |
639 | import re |
640 | @@ -224,8 +225,12 @@ |
641 | def list_apps(self, args): |
642 | container_id = self.containers_config.check_container_id(args.id) |
643 | |
644 | - container = LibertineContainer(container_id) |
645 | - print(container.list_app_launchers(use_json=args.json)) |
646 | + app_ids = LibertineContainer(container_id).list_app_ids() |
647 | + if args.json: |
648 | + print(json.dumps(app_ids)) |
649 | + else: |
650 | + for app in app_ids: |
651 | + print(app) |
652 | |
653 | def exec(self, args): |
654 | container_id = self.containers_config.check_container_id(args.id) |
FAILED: Continuous integration, rev:391 /jenkins. canonical. com/libertine/ job/lp- libertine- ci/368/ /jenkins. canonical. com/libertine/ job/build/ 707/console /jenkins. canonical. com/libertine/ job/build- 0-fetch/ 717 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 698/console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= zesty/698/ console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 698/console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= zesty/698/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/libertine/ job/lp- libertine- ci/368/ rebuild
https:/