Merge lp:~julian-edwards/launchpad/localdiff-sync-bug-739525 into lp:launchpad

Proposed by Julian Edwards
Status: Merged
Approved by: Данило Шеган
Approved revision: no longer in the source branch.
Merged at revision: 12653
Proposed branch: lp:~julian-edwards/launchpad/localdiff-sync-bug-739525
Merge into: lp:launchpad
Diff against target: 175 lines (+65/-21)
3 files modified
lib/lp/registry/browser/distroseries.py (+18/-7)
lib/lp/registry/browser/tests/test_series_views.py (+46/-14)
lib/lp/testing/factory.py (+1/-0)
To merge this branch: bzr merge lp:~julian-edwards/launchpad/localdiff-sync-bug-739525
Reviewer Review Type Date Requested Status
Данило Шеган (community) Approve
Review via email: mp+54496@code.launchpad.net

Commit message

[r=danilo][bug=739525] Derived Distros: Connect the sync button on +localpackagediffs to code that will actually do the sync

Description of the change

= Summary =
Derived Distros feature:
Connect the "Synchronise" button on the +localpackagediffs form to code that will actually perform the diff.

== Implementation details ==
The button was originally left doing nothing, with a stub function. This is because we thought that we needed a job runner to do the synchronisation as package syncing is a fairly db-intensive operation. However, recent improvements to the package copier infrastructure have made it much faster, so we want to try out this direct copying method inside a webapp request (which is exactly how the PPA copying page works).

The code does a very simple call to IArchive.syncSourceS() to perform the sync. Most of the changes in the branch are test changes.

If we ever need to make this an asynchronous operation, we'll do it in tandem with the PPA copying code, but for now we'll see how it goes like this.

== Tests ==
bin/test -cvv test_series_views

== Demo and Q/A ==
See https://dogfood.launchpad.net/deribuntu/dangerous/+localpackagediffs
(the button doesn't do anything there yet but you can click it to get an idea of how it works)

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/testing/factory.py
  lib/lp/registry/browser/distroseries.py
  lib/lp/registry/browser/tests/test_series_views.py

./lib/lp/testing/factory.py
     265: E501 line too long (84 characters)
     265: Line exceeds 78 characters.

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

<danilos> bigjools, branch sounds like a nice feature, but you've got a single lint issue so please fix it (I understand it may not be from your changes :)
 looking at the code now
<bigjools> :/
<bigjools> it was my lint
<danilos> bigjools, I am sad to see a message like "The following sources *would have been* synced if..." go from the real UI
<bigjools> :)
<wgrant> bigjools: Have you worked out how permissions are going to work?
<bigjools> no
<wgrant> Heh
<danilos> bigjools, r=me, but I'd also remove the "XXX" from a comment about a thing you are not really going to fix unless it proves to be broken

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/distroseries.py'
2--- lib/lp/registry/browser/distroseries.py 2011-03-08 11:56:40 +0000
3+++ lib/lp/registry/browser/distroseries.py 2011-03-23 17:35:11 +0000
4@@ -90,6 +90,9 @@
5 from lp.services.worlddata.interfaces.country import ICountry
6 from lp.services.worlddata.interfaces.language import ILanguageSet
7 from lp.soyuz.browser.packagesearch import PackageSearchViewBase
8+from lp.soyuz.interfaces.archive import (
9+ CannotCopy,
10+ )
11 from lp.soyuz.interfaces.queue import IPackageUploadSet
12 from lp.translations.browser.distroseries import (
13 check_distroseries_translations_viewable,
14@@ -618,19 +621,27 @@
15 @action(_("Sync Sources"), name="sync", validator='validate_sync',
16 condition='canPerformSync')
17 def sync_sources(self, action, data):
18- """Mark the diffs as syncing and request the sync.
19+ """Synchronise packages from the parent series to this one."""
20+ # We're doing a direct copy sync here as an interim measure
21+ # until we work out if it's fast enough to work reliably. If it
22+ # isn't, we need to implement a way of flagging sources 'to be
23+ # synced' and write a job runner to do it in the background.
24
25- Currently this is a stub operation, the details of which will
26- be implemented later.
27- """
28 selected_differences = data['selected_differences']
29 diffs = [
30 diff.source_package_name.name
31 for diff in selected_differences]
32
33- self.request.response.addNotification(
34- "The following sources would have been synced if this "
35- "wasn't just a stub operation: " + ", ".join(diffs))
36+ try:
37+ self.context.main_archive.syncSources(
38+ diffs, from_archive=self.context.parent_series.main_archive,
39+ to_pocket='Release', to_series=self.context.name)
40+ except CannotCopy, e:
41+ self.request.response.addErrorNotification("Cannot copy: %s" % e)
42+ else:
43+ self.request.response.addNotification(
44+ "The following sources were synchronized: " +
45+ ", ".join(diffs))
46
47 self.next_url = self.request.URL
48
49
50=== modified file 'lib/lp/registry/browser/tests/test_series_views.py'
51--- lib/lp/registry/browser/tests/test_series_views.py 2011-03-21 09:15:49 +0000
52+++ lib/lp/registry/browser/tests/test_series_views.py 2011-03-23 17:35:11 +0000
53@@ -33,6 +33,12 @@
54 getFeatureFlag,
55 install_feature_controller,
56 )
57+from lp.soyuz.interfaces.sourcepackageformat import (
58+ ISourcePackageFormatSelectionSet,
59+ )
60+from lp.soyuz.enums import (
61+ SourcePackageFormat,
62+ )
63 from lp.testing import (
64 TestCaseWithFactory,
65 login_person,
66@@ -267,8 +273,15 @@
67
68 layer = LaunchpadFunctionalLayer
69
70+ def _set_source_selection(self, series):
71+ # Set up source package format selection so that copying will
72+ # work with the default dsc_format used in
73+ # makeSourcePackageRelease.
74+ getUtility(ISourcePackageFormatSelectionSet).add(
75+ series, SourcePackageFormat.FORMAT_1_0)
76+
77 def test_batch_filtered(self):
78- # The name_filter parameter allows to filter packages by name.
79+ # The name_filter parameter allows filtering of packages by name.
80 set_derived_series_ui_feature_flag(self)
81 derived_series = self.factory.makeDistroSeries(
82 name='derilucid', parent_series=self.factory.makeDistroSeries(
83@@ -346,19 +359,28 @@
84 derived_series, '+localpackagediffs')
85 self.assertTrue(view.canPerformSync())
86
87- # XXX 2010-10-29 michaeln bug=668334
88- # The following three tests pass locally but there is a bug with
89- # per-thread features when running with a larger subset of tests.
90- # These should be re-enabled once the above bug is fixed.
91- def disabled_test_sync_notification_on_success(self):
92+ def test_sync_notification_on_success(self):
93 # Syncing one or more diffs results in a stub notification.
94+ versions = {
95+ 'base': '1.0',
96+ 'derived': '1.0derived1',
97+ 'parent': '1.0-1',
98+ }
99+ parent_series = self.factory.makeDistroSeries(name='warty')
100 derived_series = self.factory.makeDistroSeries(
101- name='derilucid', parent_series=self.factory.makeDistroSeries(
102- name='lucid'))
103+ name='derilucid', parent_series=parent_series)
104+ self._set_source_selection(derived_series)
105 difference = self.factory.makeDistroSeriesDifference(
106 source_package_name_str='my-src-name',
107- derived_series=derived_series)
108-
109+ derived_series=derived_series, versions=versions)
110+
111+ # The inital state is that 1.0-1 is not in the derived series.
112+ pubs = derived_series.main_archive.getPublishedSources(
113+ name='my-src-name', version=versions['parent'],
114+ distroseries=derived_series).any()
115+ self.assertIs(None, pubs)
116+
117+ # Now, sync the source from the parent using the form.
118 set_derived_series_ui_feature_flag(self)
119 with person_logged_in(derived_series.owner):
120 view = create_initialized_view(
121@@ -370,16 +392,25 @@
122 'field.actions.sync': 'Sync',
123 })
124
125+ # The parent's version should now be in the derived series:
126+ pub = derived_series.main_archive.getPublishedSources(
127+ name='my-src-name', version=versions['parent'],
128+ distroseries=derived_series).one()
129+ self.assertIsNot(None, pub)
130+ self.assertEqual(versions['parent'], pub.sourcepackagerelease.version)
131+
132+ # The view should show no errors, and the notification should
133+ # confirm the sync worked.
134 self.assertEqual(0, len(view.errors))
135 notifications = view.request.response.notifications
136 self.assertEqual(1, len(notifications))
137 self.assertEqual(
138- "The following sources would have been synced if this wasn't "
139- "just a stub operation: my-src-name",
140+ "The following sources were synchronized: my-src-name",
141 notifications[0].message)
142+ # 302 is a redirect back to the same page.
143 self.assertEqual(302, view.request.response.getStatus())
144
145- def disabled_test_sync_error_nothing_selected(self):
146+ def test_sync_error_nothing_selected(self):
147 # An error is raised when a sync is requested without any selection.
148 derived_series = self.factory.makeDistroSeries(
149 name='derilucid', parent_series=self.factory.makeDistroSeries(
150@@ -401,11 +432,12 @@
151 self.assertEqual(
152 'No differences selected.', view.errors[0])
153
154- def disabled_test_sync_error_invalid_selection(self):
155+ def test_sync_error_invalid_selection(self):
156 # An error is raised when an invalid difference is selected.
157 derived_series = self.factory.makeDistroSeries(
158 name='derilucid', parent_series=self.factory.makeDistroSeries(
159 name='lucid'))
160+ self._set_source_selection(derived_series)
161 difference = self.factory.makeDistroSeriesDifference(
162 source_package_name_str='my-src-name',
163 derived_series=derived_series)
164
165=== modified file 'lib/lp/testing/factory.py'
166--- lib/lp/testing/factory.py 2011-03-18 10:31:56 +0000
167+++ lib/lp/testing/factory.py 2011-03-23 17:35:11 +0000
168@@ -2266,6 +2266,7 @@
169 description=self.getUniqueString(),
170 parent_series=parent_series, owner=distribution.owner)
171 series.status = status
172+
173 return ProxyFactory(series)
174
175 def makeUbuntuDistroRelease(self, version=None,