Merge lp:~larryprice/libertine/new-list-apps into lp:libertine

Proposed by Larry Price
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
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.

To post a comment you must log in.
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
392. By Larry Price

missed a spot

Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
393. By Larry Price

test method was using wrong dbus service giving false positive

Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:393
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/371/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/710
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/581
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/581
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/581
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/581
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/720
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/701
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/701/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/701
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/701/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/701
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/701/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/701
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/701/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/371/rebuild

review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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)

Subscribers

People subscribed via source and target branches