Merge lp:~henninge/launchpad/bug-545354-enable-sharing into lp:~launchpad/launchpad/recife
| Status: | Merged | ||||
|---|---|---|---|---|---|
| Approved by: | Edwin Grubbs on 2010-06-16 | ||||
| Approved revision: | no longer in the source branch. | ||||
| Merged at revision: | 9139 | ||||
| Proposed branch: | lp:~henninge/launchpad/bug-545354-enable-sharing | ||||
| Merge into: | lp:~launchpad/launchpad/recife | ||||
| Diff against target: |
918 lines (+666/-82) 5 files modified
database/schema/security.cfg (+1/-0) lib/lp/translations/doc/potemplate.txt (+7/-3) lib/lp/translations/interfaces/potemplate.py (+23/-0) lib/lp/translations/model/potemplate.py (+161/-65) lib/lp/translations/tests/test_shared_potemplate.py (+474/-14) |
||||
| To merge this branch: | bzr merge lp:~henninge/launchpad/bug-545354-enable-sharing | ||||
| Related bugs: |
|
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Edwin Grubbs (community) | 2010-06-09 | Approve on 2010-06-16 | |
|
Review via email:
|
|||
Commit Message
Enable message sharing between products and source packages.
Description of the Change
= Bug 545354 =
Enlarges the collection of sharing templates in a POTemplateShari
== Pre-implementation discussion ==
We discussed some of this in Recife in March but also just recently. The latest findings can be found in my comments on the bug. One design goal was to make sure the number of SQL queries remains constant and independent of the number of templates in the collection.
== Implementation details ==
The query in _queryByProduct is best understood by looking at this little picture: http://
Also in this method I used ID throughout although not all relations need to be that explicit but I found mixing those more confusing to read.
== Tests ==
A new test case was created to test getSharingPOTem
./test -vvt MessageSharingP
== Lint ==
No lint left.
| Henning Eggers (henninge) wrote : | # |
| Edwin Grubbs (edwin-grubbs) wrote : | # |
Hi Henning,
This looks good. I just have a few comments below.
merge-conditional
-Edwin
>=== modified file 'lib/lp/
>--- lib/lp/
>+++ lib/lp/
>@@ -184,6 +184,21 @@
>
> _uses_english_
>
>+ @cachedproperty
>+ def _sharing_ids(self):
>+ """Return the IDs of all sharing templates including this one."""
>+ subset = getUtility(
>+ product=
>+ distribution=
>+ sourcepackagena
>+ # Convert to a list for caching.
>+ result = list(subset.
>+ if len(result) == 0:
>+ # Always return at least the template itself.
>+ return [self.id]
>+ else:
>+ return result
Should you also make sure that self.id is in result even if len != 0?
> def __storm_
> self.clearPOFil
> self._uses_
>@@ -1387,45 +1425,102 @@
> package = template.
> return (template.name, package)
>
>- def _iterate_
>- """Yield all templates matching the provided argument.
>-
>- This is much like a `IPOTemplateSub
>- `Product`s and `Distribution`s rather than `ProductSeries` and
>- `DistroSeries`.
>- """
>- if self.product:
>- subsets = [
>- self.potemplate
>- for series in self.product.series
>- ]
>+ def _queryByProduct
>+ """Build the query that finds POTemplates by their linked product.
>+
>+ Queries the Packaging table to find templates in linked source
>+ packages, too.
>+
>+ :param templatename_
>+ add to the where clause of the query that will select the template
>+ name.
>+ :return: A ResultSet for the query.
>+ """
>+ from lp.registry.
>+
>+ ProductSeries1 = ClassAlias(
>+ origin = LeftJoin(
>+ LeftJoin(
>+ POTemplate, ProductSeries,
>+ POTemplate.
>+ Join(
>+ Packaging, ProductSeries1,
>+ Packaging.
>+ And(
>+ Packaging.
>+ Packaging.
>+ POTemplate.
>+ )
>+ )
>+ return Store.of(
>+ POTemplate,
>+ And(
>+ Or(
>+ ProductSeries.
>+ ProductSeries1.
>+ ),
>+ ...
| Henning Eggers (henninge) wrote : | # |
Am 16.06.2010 23:24, schrieb Edwin Grubbs:
> This looks good. I just have a few comments below.
Thanks for the review. I explained one away and fixed two. ;)
>> === modified file 'lib/lp/
>> --- lib/lp/
>> +++ lib/lp/
>> @@ -184,6 +184,21 @@
>>
>> _uses_english_
>>
>> + @cachedproperty
>> + def _sharing_ids(self):
>> + """Return the IDs of all sharing templates including this one."""
>> + subset = getUtility(
>> + product=
>> + distribution=
>> + sourcepackagena
>> + # Convert to a list for caching.
>> + result = list(subset.
>> + if len(result) == 0:
>> + # Always return at least the template itself.
>> + return [self.id]
>> + else:
>> + return result
>
>
> Should you also make sure that self.id is in result even if len != 0?
No. Actually, the len == 0 case is basically a "no sharing possible case" and
with a single id in the list no sharing happens. If we get any ids back, those
are the sharing ones and we can trust them to include all we need.
[...]
>> def groupEquivalent
>>
>> - for template in self._iterate_
>> + if name_pattern is None:
>> + templatename_clause = "1=1"
>> + else:
>> + templatename_clause = "potemplate.name ~ '%s'" % name_pattern
>
>
> I think you should either escape the name_pattern with sqlvalues,
> or you should convert it to a storm conditional.
Yes, thank you. I fixed that by using sqlvalues. Also I replaced "1=1" with
True since we are still in storm land here. I also pulled this out into
another variant of getSharingPOTem
>
>
>> +
>> + for template in self._queryPOTe
>> key = self._get_
>> if key not in equivalents:
>> equivalents[key] = []
>> === modified file 'lib/lp/
>> --- lib/lp/
>> +++ lib/lp/
>> @@ -177,5 +176,398 @@
>> self.assertEqua
>>
>>
>> +class TestMessageShar
>> + """Test message sharing between a product and a package.
>> +
>> + Each test uses assertStatement
>> + queries does not change. This was integrated here to avoid having
>> + a second test case just for statement counts.
>> + The current implementation is good and only needs one statement."""
>
>
> Ending triple-quotes belongs by itself on the following line, since
> this is a multiline docstring.
>
True, thanks.
...
| Jeroen T. Vermeulen (jtv) wrote : | # |
I looked over the incremental diff at Henning's request. A few notes, mostly already discussed on IRC. I think having the separate unit test for the regex matching (which was a bit of a wildcard, ha ha) worked out really well.
These came up on IRC:
* Backquote identifiers in docstrings: "See `IPOTemplateSha
* getSharingPOTem
* No need to create a Product and ProductSeries; create a series and use its product.
The unit tests mostly follow the pattern "create templates with names [...]; create a subset; select from subset by regex; verify output." Most of these would be one-liners if you had a method for "create templates with names [...] (parameter 1); create a subset; select from subset by regex (parameter 2); return list of names of the selected templates." The caller could then assertContentsEqual the result against a list of expected strings. That would also help with:
* Making the output more obvious (the relevance of "templates[1:]" is less clear).
* Testing lots of other things that could go wrong; see below.
* Eliminating implicit state. You wouldn't need any setUp at all.
Other notes:
* You may want to test that you're really getting a match, not a search: "xyz" should not match "y.*" As long as we're not taking the regex from user input but from existing template names, this is a bigger risk than unescaped quotes. (Not that I disagree with your approach of testing for those right from the start!)
* "# Quotes in the pattern can be dangerous." To me that looks like you're specifying the appropriate behaviour! How about "quotes do not confuse the regex match"?
* I'd test single and double quotes separately, not in the same string.
* When you test for quoting robustness, you might as well set up a template to establish that you don't get any unexpected matches.
* You don't exercise the case where no templates match.
Apart from those notes, the incremental diff has my unreserved blessing.
Jeroen

Seeing how many tests were affected, I'd suggest the following test command which tests all translation tests:
bin/test -vvt lp.translations