Merge lp:~rvb/launchpad/dsd-api-bug-766158 into lp:launchpad/db-devel

Proposed by Raphaël Badin
Status: Merged
Approved by: Данило Шеган
Approved revision: no longer in the source branch.
Merged at revision: 10513
Proposed branch: lp:~rvb/launchpad/dsd-api-bug-766158
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~stevenk/launchpad/db-use-dsp
Diff against target: 378 lines (+180/-22)
9 files modified
lib/canonical/launchpad/interfaces/_schema_circular_imports.py (+14/-0)
lib/lp/registry/browser/tests/test_distroseries_webservice.py (+44/-0)
lib/lp/registry/interfaces/distribution.py (+1/-1)
lib/lp/registry/interfaces/distroseries.py (+41/-0)
lib/lp/registry/interfaces/distroseriesdifference.py (+7/-3)
lib/lp/registry/model/distroseries.py (+15/-0)
lib/lp/registry/model/distroseriesdifference.py (+10/-3)
lib/lp/registry/tests/test_distroseriesdifference.py (+34/-4)
lib/lp/testing/factory.py (+14/-11)
To merge this branch: bzr merge lp:~rvb/launchpad/dsd-api-bug-766158
Reviewer Review Type Date Requested Status
Данило Шеган (community) Approve
Review via email: mp+59227@code.launchpad.net

Commit message

[r=danilo][bug=766158] Add an method IDistroSeries.getDifferencesTo to retrieve differences to a specific parent or all parents of the series. Expose this method on the 'devel' api.

Description of the change

This branch adds a method IDistroSeries.getDifferencesTo to find DistroSeriesDifferences for a DistroSeries (this method is exposed on the 'devel' api).

= Details =
This branch is branched off lp:~stevenk/launchpad/db-use-dsp which removes the usage of IDistroSeries.parent_series in DSDs and DSDJs.
The method getDifferencesTo is a simple wrapper around IDistroSeriesDifferenceSource.getForDistroSeries. This branch fixes IDSDS.getForDistroSeries and the testing factory methods to work in the context of multiple parents.

= Tests =
(added test)
./bin/test -cvv test_distroseriesdifference test_getForDistroSeries_filters_by_parent
./bin/test -cvv test_distroseries_webservice test_getDifferencesTo
(fixed test)
./bin/test -cvv test_distroseriesdifference test_getForDistroSeries_filters_by_type

= QA =
Once lp:~stevenk/launchpad/db-use-dsp is merged and qa-ed, this can be tested by calling the api on a distroseries with multiple parents to fetch differences.

= Drive-by fixes =
- Add missing assert statement in test_getForDistroSeries_filters_by_type (lib/lp/registry/tests/test_distroseriesdifference.py).
- his branch also fixes a small glitch in lib/lp/registry/interfaces/distribution.py.

To post a comment you must log in.
Revision history for this message
Данило Шеган (danilo) wrote :

Several issues as discussed on IRC:

1. There is now a easy-to-fix conflict :)

2. operation_parameters seem to abuse TextLine quite a bit: please use appropriate interface definitions (Choices, Bools, etc) and make sure appropriate enums are exported as well

3. A tiny whitespace issue:

At line 89 of the diff, you've got double space inside a string (at EOL and SOL :):

+ title=_("Only return differences for packages matching this "
+ " name."),

review: Needs Fixing
Revision history for this message
Данило Шеган (danilo) wrote :

Oh, also (lest it be forgotten :):

 - assertSameDiffs could use assertContentEqual to avoid sorted() calls, and "ds_diff_ws" should instead be named "derived_ds_ws" or something

Revision history for this message
Raphaël Badin (rvb) wrote :

> Oh, also (lest it be forgotten :):
>
> - assertSameDiffs could use assertContentEqual to avoid sorted() calls, and
> "ds_diff_ws" should instead be named "derived_ds_ws" or something

2, 3, 4 done.

I also refactored my test to pass actual parameters to the api method. (I'd like to have your opinion about passing str(Enum) to the api method though).

I still need to merge db-devel to fix the conflict but I guess it's going to be easier to review my changes *before* I merge db-devel and thus diverge from Steven's branch.

Revision history for this message
Данило Шеган (danilo) wrote :

Looks good. It seems str(Enum) is the right way to pass the enum value around, though it'd be best to check with someone else more knowledgeable as well (i.e. I looked at https://launchpad.net/+apidoc/devel.html for a few enums and they basically expect a string like that).

(fwiw, merging db-devel should not have introduced any other changes into your diff because it is proposed against db-devel, but would introduce bigger differences between Steve's and your branch)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/interfaces/_schema_circular_imports.py'
2--- lib/canonical/launchpad/interfaces/_schema_circular_imports.py 2011-04-12 13:43:36 +0000
3+++ lib/canonical/launchpad/interfaces/_schema_circular_imports.py 2011-05-02 14:04:48 +0000
4@@ -112,6 +112,10 @@
5 IHWSubmissionDevice,
6 IHWVendorID,
7 )
8+from lp.registry.enum import (
9+ DistroSeriesDifferenceStatus,
10+ DistroSeriesDifferenceType,
11+ )
12 from lp.registry.interfaces.commercialsubscription import (
13 ICommercialSubscription,
14 )
15@@ -486,6 +490,16 @@
16 IDistroSeries, 'deriveDistroSeries', 'distribution', IDistribution)
17 patch_collection_return_type(
18 IDistroSeries, 'getDerivedSeries', IDistroSeries)
19+patch_plain_parameter_type(
20+ IDistroSeries, 'getDifferencesTo', 'parent_series', IDistroSeries)
21+patch_choice_parameter_type(
22+ IDistroSeries, 'getDifferencesTo', 'status', DistroSeriesDifferenceStatus)
23+patch_choice_parameter_type(
24+ IDistroSeries, 'getDifferencesTo', 'difference_type',
25+ DistroSeriesDifferenceType)
26+patch_collection_return_type(
27+ IDistroSeries, 'getDifferencesTo', IDistroSeriesDifference)
28+
29
30 # IDistroSeriesDifference
31 patch_reference_property(
32
33=== added file 'lib/lp/registry/browser/tests/test_distroseries_webservice.py'
34--- lib/lp/registry/browser/tests/test_distroseries_webservice.py 1970-01-01 00:00:00 +0000
35+++ lib/lp/registry/browser/tests/test_distroseries_webservice.py 2011-05-02 14:04:48 +0000
36@@ -0,0 +1,44 @@
37+# Copyright 2011 Canonical Ltd. This software is licensed under the
38+# GNU Affero General Public License version 3 (see the file LICENSE).
39+
40+__metaclass__ = type
41+
42+from canonical.testing import AppServerLayer
43+from lp.registry.enum import (
44+ DistroSeriesDifferenceStatus,
45+ DistroSeriesDifferenceType,
46+ )
47+from lp.testing import (
48+ TestCaseWithFactory,
49+ ws_object,
50+ )
51+
52+
53+class DistroSeriesWebServiceTestCase(TestCaseWithFactory):
54+
55+ layer = AppServerLayer
56+
57+ def assertSameDiffs(self, diffs, ws_diffs):
58+ self.assertContentEqual(
59+ [self._wsFor(diff) for diff in diffs],
60+ [ws_diff for ws_diff in ws_diffs])
61+
62+ def _wsFor(self, obj):
63+ return ws_object(
64+ self.factory.makeLaunchpadService(version="devel"), obj)
65+
66+ def test_getDifferencesTo(self):
67+ # Distroseries' DistroSeriesDifferences are available
68+ # on the web service.
69+ # This method is a simple wrapper around getForDistroSeries
70+ # that is thoroughly tested in test_distroseriesdifference.
71+ ds_diff = self.factory.makeDistroSeriesDifference()
72+ ds_ws = self._wsFor(ds_diff.derived_series)
73+
74+ self.assertSameDiffs([ds_diff], ds_ws.getDifferencesTo(
75+ status=str(DistroSeriesDifferenceStatus.NEEDS_ATTENTION),
76+ difference_type=str(
77+ DistroSeriesDifferenceType.DIFFERENT_VERSIONS),
78+ source_package_name_filter=ds_diff.source_package_name.name,
79+ child_version_higher=False,
80+ parent_series=self._wsFor(ds_diff.parent_series)))
81
82=== modified file 'lib/lp/registry/interfaces/distribution.py'
83--- lib/lp/registry/interfaces/distribution.py 2011-04-14 20:40:03 +0000
84+++ lib/lp/registry/interfaces/distribution.py 2011-05-02 14:04:48 +0000
85@@ -156,7 +156,7 @@
86 Summary(
87 title=_("Summary"),
88 description=_(
89- "A short paragraph to introduce the the goals and highlights "
90+ "A short paragraph to introduce the goals and highlights "
91 "of the distribution."),
92 required=True))
93 homepage_content = exported(
94
95=== modified file 'lib/lp/registry/interfaces/distroseries.py'
96--- lib/lp/registry/interfaces/distroseries.py 2011-05-02 14:04:47 +0000
97+++ lib/lp/registry/interfaces/distroseries.py 2011-05-02 14:04:48 +0000
98@@ -24,6 +24,7 @@
99 export_write_operation,
100 exported,
101 LAZR_WEBSERVICE_EXPORTED,
102+ operation_for_version,
103 operation_parameters,
104 operation_returns_collection_of,
105 operation_returns_entry,
106@@ -893,6 +894,46 @@
107 def getDerivedSeries():
108 """Get all `DistroSeries` derived from this one."""
109
110+ @operation_parameters(
111+ parent_series=Reference(
112+ schema=Interface, # IDistroSeries
113+ title=_("The parent series to consider."),
114+ required=False),
115+ difference_type=Choice(
116+ vocabulary=DBEnumeratedType, # DistroSeriesDifferenceType
117+ title=_("Only return differences of this type."), required=False),
118+ source_package_name_filter=TextLine(
119+ title=_("Only return differences for packages matching this "
120+ "name."),
121+ required=False),
122+ status=Choice(
123+ vocabulary=DBEnumeratedType, # DistroSeriesDifferenceStatus
124+ title=_("Only return differences of this status."),
125+ required=False),
126+ child_version_higher=Bool(
127+ title=_("Only return differences for which the child's version "
128+ "is higher than the parent's."),
129+ required=False),
130+ )
131+ @operation_returns_collection_of(Interface)
132+ @export_read_operation()
133+ @operation_for_version('devel')
134+ def getDifferencesTo(parent_series, difference_type,
135+ source_package_name_filter, status,
136+ child_version_higher):
137+ """Return the differences between this series and the specified
138+ parent_series (or all the parent series if parent_series is None).
139+
140+ :param parent_series: The parent series for which the differences
141+ should be returned. All parents are considered if this is None.
142+ :param difference_type: The type of the differences to return.
143+ :param source_package_name_filter: A package name to use as a filter
144+ for the differences.
145+ :param status: The status of the differences to return.
146+ :param child_version_higher: Only return differences for which the
147+ child's version is higher than the parent's version.
148+ """
149+
150
151 class IDistroSeries(IDistroSeriesEditRestricted, IDistroSeriesPublic,
152 IStructuralSubscriptionTarget):
153
154=== modified file 'lib/lp/registry/interfaces/distroseriesdifference.py'
155--- lib/lp/registry/interfaces/distroseriesdifference.py 2011-05-02 14:04:47 +0000
156+++ lib/lp/registry/interfaces/distroseriesdifference.py 2011-05-02 14:04:48 +0000
157@@ -280,10 +280,11 @@
158
159 def getForDistroSeries(
160 distro_series,
161- difference_type=DistroSeriesDifferenceType.DIFFERENT_VERSIONS,
162+ difference_type=None,
163 source_package_name_filter=None,
164 status=None,
165- child_version_higher=False):
166+ child_version_higher=False,
167+ parent_series=None):
168 """Return differences for the derived distro series sorted by
169 package name.
170
171@@ -301,7 +302,10 @@
172 :param child_version_higher: Only differences for which the child's
173 version is higher than the parent's version will be included.
174 :type child_version_higher: bool.
175- :return: A result set of differences.
176+ :param parent_series: The parent series to consider. Consider all
177+ parent series if this parameter is None.
178+ :type distro_series: `IDistroSeries`.
179+ :return: A result set of `IDistroSeriesDifference`.
180 """
181
182 def getByDistroSeriesAndName(distro_series, source_package_name):
183
184=== modified file 'lib/lp/registry/model/distroseries.py'
185--- lib/lp/registry/model/distroseries.py 2011-05-02 14:04:47 +0000
186+++ lib/lp/registry/model/distroseries.py 2011-05-02 14:04:48 +0000
187@@ -99,6 +99,9 @@
188 IDistroSeries,
189 IDistroSeriesSet,
190 )
191+from lp.registry.interfaces.distroseriesdifference import (
192+ IDistroSeriesDifferenceSource,
193+ )
194 from lp.registry.interfaces.person import validate_public_person
195 from lp.registry.interfaces.pocket import (
196 PackagePublishingPocket,
197@@ -2021,6 +2024,18 @@
198 return OrderedBugTask(3, bugtask.id, bugtask)
199 return weight_function
200
201+ def getDifferencesTo(self, parent_series=None, difference_type=None,
202+ source_package_name_filter=None, status=None,
203+ child_version_higher=False):
204+ """See `IDistroSeries`."""
205+ return getUtility(
206+ IDistroSeriesDifferenceSource).getForDistroSeries(
207+ self,
208+ difference_type = difference_type,
209+ source_package_name_filter=source_package_name_filter,
210+ status=status,
211+ child_version_higher=child_version_higher)
212+
213
214 class DistroSeriesSet:
215 implements(IDistroSeriesSet)
216
217=== modified file 'lib/lp/registry/model/distroseriesdifference.py'
218--- lib/lp/registry/model/distroseriesdifference.py 2011-05-02 14:04:47 +0000
219+++ lib/lp/registry/model/distroseriesdifference.py 2011-05-02 14:04:48 +0000
220@@ -258,11 +258,14 @@
221 @staticmethod
222 def getForDistroSeries(
223 distro_series,
224- difference_type=DistroSeriesDifferenceType.DIFFERENT_VERSIONS,
225+ difference_type=None,
226 source_package_name_filter=None,
227 status=None,
228- child_version_higher=False):
229+ child_version_higher=False,
230+ parent_series=None):
231 """See `IDistroSeriesDifferenceSource`."""
232+ if difference_type is None:
233+ difference_type=DistroSeriesDifferenceType.DIFFERENT_VERSIONS
234 if status is None:
235 status = (
236 DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
237@@ -276,7 +279,11 @@
238 DistroSeriesDifference.status.is_in(status),
239 DistroSeriesDifference.source_package_name ==
240 SourcePackageName.id,
241- ]
242+ ]
243+
244+ if parent_series:
245+ conditions.extend([
246+ DistroSeriesDifference.parent_series == parent_series.id])
247
248 if source_package_name_filter:
249 conditions.extend([
250
251=== modified file 'lib/lp/registry/tests/test_distroseriesdifference.py'
252--- lib/lp/registry/tests/test_distroseriesdifference.py 2011-05-02 14:04:47 +0000
253+++ lib/lp/registry/tests/test_distroseriesdifference.py 2011-05-02 14:04:48 +0000
254@@ -871,7 +871,7 @@
255
256 verifyObject(IDistroSeriesDifferenceSource, dsd_source)
257
258- def makeDiffsForDistroSeries(self, derived_series):
259+ def makeDiffsForDistroSeries(self, derived_series, parent_series=None):
260 # Helper that creates a range of differences for a derived
261 # series.
262 diffs = {
263@@ -881,21 +881,24 @@
264 }
265 diffs['normal'].append(
266 self.factory.makeDistroSeriesDifference(
267- derived_series=derived_series))
268+ derived_series=derived_series, parent_series=parent_series))
269 diffs['unique'].append(
270 self.factory.makeDistroSeriesDifference(
271 derived_series=derived_series,
272+ parent_series=parent_series,
273 difference_type=(
274 DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES)))
275 diffs['ignored'].append(
276 self.factory.makeDistroSeriesDifference(
277 derived_series=derived_series,
278+ parent_series=parent_series,
279 status=DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT))
280 return diffs
281
282- def makeDerivedSeries(self):
283+ def makeDerivedSeries(self, derived_series=None):
284 # Keep tests DRY.
285- dsp = self.factory.makeDistroSeriesParent()
286+ dsp = self.factory.makeDistroSeriesParent(
287+ derived_series=derived_series)
288 return dsp.derived_series
289
290 def test_getForDistroSeries_default(self):
291@@ -930,6 +933,8 @@
292 derived_series,
293 DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES)
294
295+ self.assertContentEqual(diffs['unique'], result)
296+
297 def test_getForDistroSeries_filters_by_status(self):
298 # A single status can be used to filter results.
299 derived_series = self.makeDerivedSeries()
300@@ -971,6 +976,31 @@
301 sorted(names),
302 [result.source_package_name.name for result in results])
303
304+ def test_getForDistroSeries_filters_by_parent(self):
305+ # The differences can be filtered by parent series.
306+ dsp = self.factory.makeDistroSeriesParent()
307+ derived_series = dsp.derived_series
308+ parent_series = dsp.parent_series
309+
310+ # Add another parent to this series.
311+ parent_series2 = self.factory.makeDistroSeriesParent(
312+ derived_series=derived_series).parent_series
313+
314+ diffs = self.makeDiffsForDistroSeries(
315+ derived_series, parent_series=parent_series)
316+ diffs2 = self.makeDiffsForDistroSeries(
317+ derived_series, parent_series=parent_series2)
318+
319+ results = getUtility(
320+ IDistroSeriesDifferenceSource).getForDistroSeries(
321+ derived_series, parent_series=parent_series)
322+ results2 = getUtility(
323+ IDistroSeriesDifferenceSource).getForDistroSeries(
324+ derived_series, parent_series=parent_series2)
325+
326+ self.assertContentEqual(diffs['normal'], results)
327+ self.assertContentEqual(diffs2['normal'], results2)
328+
329 def test_getByDistroSeriesAndName(self):
330 # An individual difference is obtained using the name.
331 ds_diff = self.factory.makeDistroSeriesDifference(
332
333=== modified file 'lib/lp/testing/factory.py'
334--- lib/lp/testing/factory.py 2011-05-02 14:04:47 +0000
335+++ lib/lp/testing/factory.py 2011-05-02 14:04:48 +0000
336@@ -2314,21 +2314,24 @@
337 versions=None,
338 difference_type=DistroSeriesDifferenceType.DIFFERENT_VERSIONS,
339 status=DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
340- changelogs=None, set_base_version=False):
341+ changelogs=None, set_base_version=False, parent_series=None):
342 """Create a new distro series source package difference."""
343 if derived_series is None:
344- dsp = self.makeDistroSeriesParent()
345+ dsp = self.makeDistroSeriesParent(
346+ parent_series=parent_series)
347 derived_series = dsp.derived_series
348 parent_series = dsp.parent_series
349 else:
350- dsp = getUtility(IDistroSeriesParentSet).getByDerivedSeries(
351- derived_series)
352- if dsp.count() == 0:
353- new_dsp = self.makeDistroSeriesParent(
354- derived_series=derived_series)
355- parent_series = new_dsp.parent_series
356- else:
357- parent_series = dsp[0].parent_series
358+ if parent_series is None:
359+ dsp = getUtility(IDistroSeriesParentSet).getByDerivedSeries(
360+ derived_series)
361+ if dsp.count() == 0:
362+ new_dsp = self.makeDistroSeriesParent(
363+ derived_series=derived_series,
364+ parent_series=parent_series)
365+ parent_series = new_dsp.parent_series
366+ else:
367+ parent_series = dsp[0].parent_series
368
369 if source_package_name_str is None:
370 source_package_name_str = self.getUniqueString('src-name')
371@@ -2373,7 +2376,7 @@
372 status = PackagePublishingStatus.PUBLISHED)
373
374 diff = getUtility(IDistroSeriesDifferenceSource).new(
375- derived_series, source_package_name)
376+ derived_series, source_package_name, parent_series)
377
378 removeSecurityProxy(diff).status = status
379

Subscribers

People subscribed via source and target branches

to status/vote changes: