Merge lp:~mvo/software-center/lp917096 into lp:software-center

Proposed by Michael Vogt
Status: Merged
Merged at revision: 2768
Proposed branch: lp:~mvo/software-center/lp917096
Merge into: lp:software-center
Diff against target: 263 lines (+100/-28)
8 files modified
debian/changelog (+7/-0)
softwarecenter/db/__init__.py (+3/-1)
softwarecenter/db/application.py (+2/-1)
softwarecenter/db/debfile.py (+12/-10)
softwarecenter/ui/gtk3/panes/availablepane.py (+7/-2)
softwarecenter/ui/gtk3/views/appdetailsview.py (+11/-9)
test/gtk3/test_debfile_view.py (+47/-0)
test/test_debfileapplication.py (+11/-5)
To merge this branch: bzr merge lp:~mvo/software-center/lp917096
Reviewer Review Type Date Requested Status
Gary Lasker (community) Approve
Review via email: mp+93371@code.launchpad.net

Description of the change

This fixes various issues around the debfile handling.

- it no longer crashes when viewing a debfile
- if a debfile is not installable it shows a error and hides the action button
- adds tests for this behavior

To post a comment you must log in.
Revision history for this message
Gary Lasker (gary-lasker) wrote :

Looks great, thanks mvo!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2012-02-15 18:32:24 +0000
3+++ debian/changelog 2012-02-16 10:28:26 +0000
4@@ -1,3 +1,10 @@
5+software-center (5.1.10) UNRELEASED; urgency=low
6+
7+ * fix crash when opening a debfile and add regression test
8+ (LP: #917096)
9+
10+ -- Michael Vogt <michael.vogt@ubuntu.com> Thu, 16 Feb 2012 10:50:56 +0100
11+
12 software-center (5.1.9) precise; urgency=low
13
14 [ Gabor Kelemen ]
15
16=== modified file 'softwarecenter/db/__init__.py'
17--- softwarecenter/db/__init__.py 2011-08-11 09:25:56 +0000
18+++ softwarecenter/db/__init__.py 2012-02-16 10:28:26 +0000
19@@ -1,6 +1,8 @@
20+import logging
21 try:
22 from debfile import DebFileApplication
23 DebFileApplication # pyflakes
24-except ImportError:
25+except:
26+ logging.exception("DebFileApplication import")
27 class DebFileApplication():
28 pass
29
30=== modified file 'softwarecenter/db/application.py'
31--- softwarecenter/db/application.py 2012-02-14 14:22:35 +0000
32+++ softwarecenter/db/application.py 2012-02-16 10:28:26 +0000
33@@ -32,7 +32,7 @@
34 from softwarecenter.paths import (APP_INSTALL_CHANNELS_PATH,
35 SOFTWARE_CENTER_ICON_CACHE_DIR,
36 )
37-from softwarecenter.utils import utf8, split_icon_ext, version_compare
38+from softwarecenter.utils import utf8, split_icon_ext
39 from softwarecenter.region import get_region_cached, REGIONTAG
40
41 LOG = logging.getLogger(__name__)
42@@ -613,6 +613,7 @@
43 """ take a screenshot result dict from screenshots.debian.org
44 and sort it
45 """
46+ from softwarecenter.utils import version_compare
47 my_version = self.version
48 # discard screenshots which are more recent than the available version
49 for item in screenshot_list[:]:
50
51=== modified file 'softwarecenter/db/debfile.py'
52--- softwarecenter/db/debfile.py 2012-01-05 08:44:43 +0000
53+++ softwarecenter/db/debfile.py 2012-02-16 10:28:26 +0000
54@@ -28,14 +28,16 @@
55 from softwarecenter.utils import ExecutionTime, utf8
56
57 class DebFileApplication(Application):
58+
59 def __init__(self, debfile):
60- # deb overrides this
61-# if not debfile.endswith(".deb") and not debfile.count('/') >= 2:
62- # raise ValueError("Need a deb file, got '%s'" % debfile)
63+ # sanity check
64+ if not debfile.endswith(".deb"):
65+ raise ValueError("Need a deb file, got '%s'" % debfile)
66+ # work out debname/appname
67 debname = os.path.splitext(os.path.basename(debfile))[0]
68- self.appname = ""
69- self.pkgname = debname.split('_')[0].lower()
70- self.request = debfile
71+ pkgname = debname.split('_')[0].lower()
72+ # call the constructor
73+ Application.__init__(self, pkgname=pkgname, request=debfile)
74 def get_details(self, db):
75 with ExecutionTime("get_details for DebFileApplication"):
76 details = AppDetailsDebFile(db, application=self)
77@@ -49,10 +51,10 @@
78 raise ValueError("doc must be None for deb files")
79
80 try:
81- # for some reason Cache() is much faster than "self._cache._cache"
82- # on startup
83 with ExecutionTime("create DebPackage"):
84- self._deb = DebPackage(self._app.request, Cache())
85+ # Cache() used to be faster here than self._cache._cache
86+ # but that is no longer the case with the latest apt
87+ self._deb = DebPackage(self._app.request, self._cache._cache)
88 except:
89 self._deb = None
90 self._pkg = None
91@@ -90,7 +92,7 @@
92 # check deb and set failure state on error
93 with ExecutionTime("AppDetailsDebFile._deb.check()"):
94 if not self._deb.check():
95- self._error = self._deb._failure_string
96+ self._error = self._deb._failure_string.strip()
97
98 @property
99 def description(self):
100
101=== modified file 'softwarecenter/ui/gtk3/panes/availablepane.py'
102--- softwarecenter/ui/gtk3/panes/availablepane.py 2012-01-19 16:39:15 +0000
103+++ softwarecenter/ui/gtk3/panes/availablepane.py 2012-02-16 10:28:26 +0000
104@@ -59,8 +59,13 @@
105 """
106
107 class Pages():
108- # page names, useful for debuggin
109- NAMES = ('lobby', 'subcategory', 'list', 'details', 'purchase')
110+ # page names, useful for debugging
111+ NAMES = ('lobby',
112+ 'subcategory',
113+ 'list',
114+ 'details',
115+ 'purchase',
116+ )
117 # actual page id's
118 (LOBBY,
119 SUBCATEGORY,
120
121=== modified file 'softwarecenter/ui/gtk3/views/appdetailsview.py'
122--- softwarecenter/ui/gtk3/views/appdetailsview.py 2012-02-15 17:11:44 +0000
123+++ softwarecenter/ui/gtk3/views/appdetailsview.py 2012-02-16 10:28:26 +0000
124@@ -309,9 +309,7 @@
125 elif state == PkgStates.NOT_FOUND:
126 self.hide()
127 elif state == PkgStates.ERROR:
128- self.progress.hide()
129- self.button.set_sensitive(False)
130- self.button.show()
131+ # error details are set below
132 self.show()
133 else:
134 # mvo: why do we override state here again?
135@@ -432,8 +430,10 @@
136 elif state == PkgStates.ERROR:
137 # this is used when the pkg can not be installed
138 # we display the error in the description field
139- self.set_button_label(_("Install"))
140- self.set_label("")
141+ self.installed_icon.hide()
142+ self.progress.hide()
143+ self.button.hide()
144+ self.set_label(_("Error"))
145 elif state == PkgStates.NOT_FOUND:
146 # this is used when the pkg is not in the cache and there is no
147 # request we display the error in the summary field and hide the
148@@ -1394,10 +1394,7 @@
149
150 def _update_app_description(self, app_details, appname):
151 # format new app description
152- if app_details.pkg_state == PkgStates.ERROR:
153- description = app_details.error
154- else:
155- description = app_details.description
156+ description = app_details.description
157 if not description:
158 description = " "
159 self.desc.set_description(description, appname)
160@@ -1452,6 +1449,11 @@
161 return
162
163 def _update_warning_bar(self, app_details):
164+ # generic error wins over HW issue
165+ if app_details.pkg_state == PkgStates.ERROR:
166+ self.pkg_warningbar.show()
167+ self.pkg_warningbar.label.set_text(app_details.error)
168+ return
169 if (app_details.hardware_requirements_satisfied and
170 app_details.region_requirements_satisfied):
171 self.pkg_warningbar.hide()
172
173=== added file 'test/gtk3/test_debfile_view.py'
174--- test/gtk3/test_debfile_view.py 1970-01-01 00:00:00 +0000
175+++ test/gtk3/test_debfile_view.py 2012-02-16 10:28:26 +0000
176@@ -0,0 +1,47 @@
177+#!/usr/bin/python
178+
179+import pickle
180+import os
181+import subprocess
182+import time
183+import unittest
184+
185+from mock import Mock
186+
187+from testutils import setup_test_env, do_events
188+setup_test_env()
189+
190+import softwarecenter.paths
191+from softwarecenter.ui.gtk3.app import SoftwareCenterAppGtk3
192+from softwarecenter.ui.gtk3.panes.availablepane import AvailablePane
193+
194+class DebFileOpenTestCase(unittest.TestCase):
195+
196+ def test_deb_file_view_error(self):
197+ mock_options = Mock()
198+ mock_options.display_navlog = False
199+ mock_options.disable_apt_xapian_index = False
200+ mock_options.disable_buy = False
201+ xapianpath = softwarecenter.paths.XAPIAN_BASE_PATH
202+ app = SoftwareCenterAppGtk3(
203+ softwarecenter.paths.datadir, xapianpath, mock_options)
204+ app.run(["./data/test_debs/gdebi-test1.deb"])
205+ # give it time
206+ for i in range(10):
207+ time.sleep(0.1)
208+ do_events()
209+ # its ok to break out early
210+ if (app.available_pane.app_details_view and
211+ app.available_pane.app_details_view.get_property("visible")):
212+ break
213+ # check that we are on the right page
214+ self.assertEqual(
215+ app.available_pane.get_current_page(), AvailablePane.Pages.DETAILS)
216+ # this is deb that is not installable
217+ action_button = app.available_pane.app_details_view.pkg_statusbar.button
218+ self.assertFalse(action_button.get_property("visible"))
219+
220+
221+
222+if __name__ == "__main__":
223+ unittest.main()
224
225=== modified file 'test/test_debfileapplication.py'
226--- test/test_debfileapplication.py 2012-01-16 14:42:49 +0000
227+++ test/test_debfileapplication.py 2012-02-16 10:28:26 +0000
228@@ -17,10 +17,10 @@
229 DEBFILE_VERSION = '1.0'
230 DEBFILE_WARNING = 'Only install this file if you trust the origin.'
231
232-DEBFILE_REINSTALLABLE = './data/test_debs/gdebi-test1.deb'
233 DEBFILE_PATH_NOTFOUND = './data/test_debs/notfound.deb'
234 DEBFILE_PATH_NOTADEB = './data/notadeb.txt'
235 DEBFILE_PATH_CORRUPT = './data/test_debs/corrupt.deb'
236+DEBFILE_NOT_INSTALLABLE = './data/test_debs/gdebi-test1.deb'
237
238 class TestDebFileApplication(unittest.TestCase):
239 """ Test the class DebFileApplication """
240@@ -46,13 +46,19 @@
241
242 self.assertEquals(debfiledetails.pkg_state, PkgStates.UNINSTALLED)
243
244- # disabled until the fixme gets fixed
245+ def test_get_pkg_state_not_installable(self):
246+ debfileapplication = DebFileApplication(DEBFILE_NOT_INSTALLABLE)
247+ debfiledetails = debfileapplication.get_details(self.db)
248+
249+ self.assertEquals(debfiledetails.pkg_state, PkgStates.ERROR)
250+
251 def disabled_for_now_test_get_pkg_state_reinstallable(self):
252 # FIMXE: add hand crafted dpkg status file into the testdir so
253 # that gdebi-test1 is marked install for the MockAptCache
254- debfileapplication = DebFileApplication(DEBFILE_REINSTALLABLE)
255- debfiledetails = debfileapplication.get_details(self.db)
256- self.assertEquals(debfiledetails.pkg_state, PkgStates.REINSTALLABLE)
257+ #debfileapplication = DebFileApplication(DEBFILE_REINSTALLABLE)
258+ #debfiledetails = debfileapplication.get_details(self.db)
259+ #self.assertEquals(debfiledetails.pkg_state, PkgStates.REINSTALLABLE)
260+ pass
261
262 def test_get_pkg_state_not_found(self):
263 debfileapplication = DebFileApplication(DEBFILE_PATH_NOTFOUND)

Subscribers

People subscribed via source and target branches