launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #03493
[Merge] lp:~jtv/launchpad/bug-747546 into lp:launchpad
Jeroen T. Vermeulen has proposed merging lp:~jtv/launchpad/bug-747546 into lp:launchpad with lp:~jtv/launchpad/pre-747546 as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #747546 in Launchpad itself: "Derived Distros: Add a button to sync all packages changed in parent but not changed in child"
https://bugs.launchpad.net/launchpad/+bug/747546
For more details, see:
https://code.launchpad.net/~jtv/launchpad/bug-747546/+merge/59765
Work in progress. Please update this MP when the time comes.
This branch adds a button to the +localpackagediffs page that syncs all updates into a derived series for packages that have not been changed in the derived series.
--
https://code.launchpad.net/~jtv/launchpad/bug-747546/+merge/59765
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/launchpad/bug-747546 into lp:launchpad.
=== modified file 'lib/lp/registry/browser/distroseries.py'
--- lib/lp/registry/browser/distroseries.py 2011-04-26 14:40:00 +0000
+++ lib/lp/registry/browser/distroseries.py 2011-05-03 12:15:18 +0000
@@ -12,7 +12,6 @@
'DistroSeriesEditView',
'DistroSeriesFacets',
'DistroSeriesInitializeView',
- 'DistroSeriesLocalDifferences',
'DistroSeriesNavigation',
'DistroSeriesPackageSearchView',
'DistroSeriesPackagesView',
@@ -101,12 +100,21 @@
from lp.services.worlddata.interfaces.language import ILanguageSet
from lp.soyuz.browser.archive import PackageCopyingMixin
from lp.soyuz.browser.packagesearch import PackageSearchViewBase
+from lp.soyuz.interfaces.distributionjob import IPackageCopyJobSource
from lp.soyuz.interfaces.queue import IPackageUploadSet
from lp.translations.browser.distroseries import (
check_distroseries_translations_viewable,
)
+# DistroSeries statuses that benefit from mass package upgrade support.
+UPGRADEABLE_SERIESSTATUSES = [
+ SeriesStatus.FUTURE,
+ SeriesStatus.EXPERIMENTAL,
+ SeriesStatus.DEVELOPMENT,
+ ]
+
+
class DistroSeriesNavigation(GetitemNavigation, BugTargetTraversalMixin,
StructuralSubscriptionTargetTraversalMixin):
@@ -925,6 +933,47 @@
def sync_sources(self, action, data):
self._sync_sources(action, data)
+ def getUpgrades(self):
+ """Find straightforward package upgrades.
+
+ These are updates for packages that this distroseries shares
+ with a parent series, for which there have been updates in the
+ parent, and which do not have any changes in this series that
+ might complicate a sync.
+
+ :return: A result set of `DistroSeriesDifference`s.
+ """
+ return getUtility(IDistroSeriesDifferenceSource).getSimpleUpgrades(
+ self.context)
+
+ @action(_("Upgrade Packages"), name="upgrade",
+ condition='canUpgrade')
+ def upgrade(self, action, data):
+ """Request synchronization of straightforward package upgrades."""
+ self.requestUpgrades()
+
+ def requestUpgrades(self):
+ """Request sync of packages that can be easily upgraded."""
+ job_source = getUtility(IPackageCopyJobSource)
+# XXX: Create jobs.
+ self.request.response.addInfoNotification("""
+ Upgrades of %s packages have been requested.
+ Please give Launchpad some time to complete these.
+ """ % self.context.displayname)
+
+ def canUpgrade(self):
+ """Should the form offer a packages upgrade?"""
+ if self.context.status not in UPGRADEABLE_SERIESSTATUSES:
+ # A feature freeze precludes blanket updates.
+ return False
+# XXX: Check privilege. We don't know who should be allowed to do this
+# yet.
+ elif self.getUpgrades().is_empty():
+ # There are no simple updates to perform.
+ return False
+ else:
+ return True
+
class DistroSeriesMissingPackagesView(DistroSeriesDifferenceBaseView,
LaunchpadFormView):
=== modified file 'lib/lp/registry/browser/tests/test_distroseries.py'
--- lib/lp/registry/browser/tests/test_distroseries.py 2011-04-27 07:27:55 +0000
+++ lib/lp/registry/browser/tests/test_distroseries.py 2011-05-03 12:15:18 +0000
@@ -47,6 +47,7 @@
DistroSeriesDifferenceStatus,
DistroSeriesDifferenceType,
)
+from lp.registry.interfaces.series import SeriesStatus
from lp.services.features import (
get_relevant_feature_controller,
getFeatureFlag,
@@ -57,6 +58,7 @@
FeatureFlag,
getFeatureStore,
)
+from lp.soyuz.interfaces.distributionjob import IPackageCopyJobSource
from lp.soyuz.enums import (
PackagePublishingStatus,
SourcePackageFormat,
@@ -173,11 +175,11 @@
derived_series,
'+index',
principal=self.simple_user)
- html = view()
+ html_text = view()
self.assertEqual(
None, getFeatureFlag('soyuz.derived-series-ui.enabled'))
- self.assertThat(html, Not(portlet_header))
+ self.assertThat(html_text, Not(portlet_header))
def test_differences_portlet_all_differences(self):
# The difference portlet shows the differences with the parent
@@ -209,9 +211,9 @@
# XXX rvb 2011-04-12 bug=758649: LaunchpadTestRequest overrides
# self.features to NullFeatureController.
view.request.features = get_relevant_feature_controller()
- html = view()
+ html_text = view()
- self.assertThat(html, portlet_display)
+ self.assertThat(html_text, portlet_display)
def test_differences_portlet_no_differences(self):
# The difference portlet displays 'No differences' if there is no
@@ -235,9 +237,9 @@
# XXX rvb 2011-04-12 bug=758649: LaunchpadTestRequest overrides
# self.features to NullFeatureController.
view.request.features = get_relevant_feature_controller()
- html = view()
+ html_text = view()
- self.assertThat(html, portlet_display)
+ self.assertThat(html_text, portlet_display)
def test_differences_portlet_initialising(self):
# The difference portlet displays 'The series is initialising.' if
@@ -263,10 +265,10 @@
# XXX rvb 2011-04-12 bug=758649: LaunchpadTestRequest overrides
# self.features to NullFeatureController.
view.request.features = get_relevant_feature_controller()
- html = view()
+ html_text = view()
self.assertTrue(derived_series.is_initialising)
- self.assertThat(html, portlet_display)
+ self.assertThat(html_text, portlet_display)
class TestMilestoneBatchNavigatorAttribute(TestCaseWithFactory):
@@ -401,7 +403,7 @@
class DistroSeriesDifferenceMixin:
"""A helper class for testing differences pages"""
- def _test_packagesets(self, html, packageset_text,
+ def _test_packagesets(self, html_text, packageset_text,
packageset_class, msg_text):
parent_packagesets = soupmatchers.HTMLContains(
soupmatchers.Tag(
@@ -409,7 +411,7 @@
attrs={'class': packageset_class},
text=packageset_text))
- self.assertThat(html, parent_packagesets)
+ self.assertThat(html_text, parent_packagesets)
class TestDistroSeriesLocalDifferences(
@@ -471,11 +473,12 @@
ds_diff.derived_series,
'+localpackagediffs',
principal=self.simple_user)
- html = view()
+ html_text = view()
packageset_text = re.compile('\s*' + ps.name)
self._test_packagesets(
- html, packageset_text, 'parent-packagesets', 'Parent packagesets')
+ html_text, packageset_text, 'parent-packagesets',
+ 'Parent packagesets')
def test_parent_packagesets_localpackagediffs_sorts(self):
# Multiple packagesets are sorted in a comma separated list.
@@ -493,12 +496,13 @@
ds_diff.derived_series,
'+localpackagediffs',
principal=self.simple_user)
- html = view()
+ html_text = view()
packageset_text = re.compile(
'\s*' + ', '.join(sorted(unsorted_names)))
self._test_packagesets(
- html, packageset_text, 'parent-packagesets', 'Parent packagesets')
+ html_text, packageset_text, 'parent-packagesets',
+ 'Parent packagesets')
def test_queries(self):
# With no DistroSeriesDifferences the query count should be low and
@@ -616,6 +620,28 @@
layer = LaunchpadZopelessLayer
+ def makePackageUpgrade(self):
+ """Create a `DistroSeriesDifference` for a package upgrade."""
+ base_version = '1.%d' % self.factory.getUniqueInteger()
+ versions = {
+ 'base': base_version,
+ 'parent': base_version + '-' + self.factory.getUniqueString(),
+ 'derived': base_version,
+ }
+ return self.factory.makeDistroSeriesDifference(
+ versions=versions, set_base_version=True)
+
+ def makeDerivedSeries(self):
+ """Create a derived `DistroSeries`."""
+ return self.factory.makeDistroSeries(
+ parent_series=self.factory.makeDistroSeries())
+
+ def makeView(self, distroseries=None):
+ """Create a +localpackagediffs view for `distroseries`."""
+ if distroseries is None:
+ distroseries = self.makeDerivedSeries()
+ return create_initialized_view(distroseries, '+localpackagediffs')
+
def test_view_redirects_without_feature_flag(self):
# If the feature flag soyuz.derived-series-ui.enabled is not set the
# view simply redirects to the derived series.
@@ -625,8 +651,7 @@
self.assertIs(
None, getFeatureFlag('soyuz.derived-series-ui.enabled'))
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
response = view.request.response
self.assertEqual(302, response.getStatus())
@@ -639,8 +664,7 @@
name='derilucid', parent_series=self.factory.makeDistroSeries(
name='lucid'))
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
self.assertEqual(
"Source package differences between 'Derilucid' and "
@@ -659,8 +683,7 @@
derived_series=derived_series,
status=DistroSeriesDifferenceStatus.RESOLVED)
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
self.assertContentEqual(
[current_difference], view.cached_differences.batch)
@@ -677,8 +700,7 @@
difference_type=(
DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES))
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
self.assertContentEqual(
[different_versions_diff], view.cached_differences.batch)
@@ -690,8 +712,7 @@
name='lucid'))
set_derived_series_ui_feature_flag(self)
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
soup = BeautifulSoup(view())
help_links = soup.findAll(
@@ -709,8 +730,7 @@
difference.addComment(difference.owner, "Latest comment")
set_derived_series_ui_feature_flag(self)
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
# Find all the rows within the body of the table
# listing the differences.
@@ -731,8 +751,7 @@
derived_series=derived_series)
set_derived_series_ui_feature_flag(self)
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
soup = BeautifulSoup(view())
diff_table = soup.find('table', {'class': 'listing'})
row = diff_table.tbody.findAll('tr')[0]
@@ -770,8 +789,7 @@
version=new_version)
set_derived_series_ui_feature_flag(self)
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
soup = BeautifulSoup(view())
diff_table = soup.find('table', {'class': 'listing'})
row = diff_table.tbody.tr
@@ -814,8 +832,7 @@
flush_database_caches()
set_derived_series_ui_feature_flag(self)
- view = create_initialized_view(
- derived_series, '+localpackagediffs')
+ view = self.makeView(derived_series)
soup = BeautifulSoup(view())
diff_table = soup.find('table', {'class': 'listing'})
row = diff_table.tbody.tr
@@ -832,6 +849,89 @@
self.assertEqual(versions['derived'], derived_span[0].string.strip())
self.assertEqual(versions['parent'], parent_span[0].string.strip())
+ def test_getUpgrades_shows_updates_in_parent(self):
+ # The view's getUpgrades methods lists packages that can be
+ # trivially upgraded: changed in the parent, not changed in the
+ # derived series, but present in both.
+ dsd = self.makePackageUpgrade()
+ view = self.makeView(dsd.derived_series)
+ self.assertContentEqual([dsd], view.getUpgrades())
+
+ def test_upgrades_are_offered_if_appropriate(self):
+ # canUpgrade is the condition for the form showing an "Upgrade
+ # Packages" button.
+ dsd = self.makePackageUpgrade()
+ view = self.makeView(dsd.derived_series)
+ self.assertTrue(view.canUpgrade())
+
+ def test_upgrades_offered_only_if_available(self):
+ # If there are no upgrades, the "Upgrade Packages" button won't
+ # be shown.
+ view = self.makeView()
+ self.assertFalse(view.canUpgrade())
+
+ def test_upgrades_not_offered_after_feature_freeze(self):
+ # There won't be an "Upgrade Packages" button once feature
+ # freeze has occurred. Mass updates would not make sense after
+ # that point.
+ upgradeable = {}
+ for status in SeriesStatus.items:
+ dsd = self.makePackageUpgrade()
+ dsd.derived_series.status = status
+ view = self.makeView(dsd.derived_series)
+ upgradeable[status] = view.canUpgrade()
+ expected = {
+ SeriesStatus.FUTURE: True,
+ SeriesStatus.EXPERIMENTAL: True,
+ SeriesStatus.DEVELOPMENT: True,
+ SeriesStatus.FROZEN: False,
+ SeriesStatus.CURRENT: False,
+ SeriesStatus.SUPPORTED: False,
+ SeriesStatus.OBSOLETE: False,
+ }
+ self.assertEqual(expected, upgradeable)
+
+ def test_upgrade_creates_sync_jobs(self):
+ # requestUpgrades generates PackageCopyJobs for the upgrades
+ # that need doing.
+ dsd = self.makePackageUpgrade()
+ series = dsd.derived_series
+ view = self.makeView(series)
+ view.requestUpgrades()
+ job_source = getUtility(IPackageCopyJobSource)
+ jobs = list(
+ job_source.getActiveJobs(series.distribution.main_archive))
+ self.assertEquals(1, len(jobs))
+ job = jobs[0]
+ self.assertEquals(series, job.distroseries)
+ spphs = job.source_packages
+ self.assertEquals(1, len(spphs))
+ self.assertEqual(dsd.source_package_name, spphs[0].sourcepackagename)
+
+ def test_upgrade_gives_feedback(self):
+ # requestUpgrades doesn't instantly perform package upgrades,
+ # but it shows the user a notice that the upgrades have been
+ # requested.
+ dsd = self.makePackageUpgrade()
+ view = self.makeView(dsd.derived_series)
+ view.requestUpgrades()
+# XXX: Test.
+ self.assertTrue(False)
+
+ def test_upgrade_is_privileged(self):
+# XXX: Privileged to whom? For Ubuntu this would be the ubuntu-archive
+# team, ideally, but we don't know of any formal role that that team has
+# w.r.t. Ubuntu in Launchpad.
+# XXX: Test.
+ self.assertTrue(False)
+
+ def test_requestUpgrade_is_efficient(self):
+ # A single web request may need to schedule large numbers of
+ # package upgrades. It must do so without issuing large numbers
+ # of database queries.
+# XXX: Test.
+ self.assertTrue(False)
+
class TestDistroSeriesLocalDifferencesFunctional(TestCaseWithFactory):
@@ -1228,11 +1328,12 @@
self.ds_diff.derived_series,
'+missingpackages',
principal=self.simple_user)
- html = view()
+ html_text = view()
packageset_text = re.compile('\s*' + ps.name)
self._test_packagesets(
- html, packageset_text, 'parent-packagesets', 'Parent packagesets')
+ html_text, packageset_text, 'parent-packagesets',
+ 'Parent packagesets')
class DistroSerieUniquePackageDiffsTestCase(TestCaseWithFactory):
@@ -1314,8 +1415,8 @@
self.ds_diff.derived_series,
'+uniquepackages',
principal=self.simple_user)
- html = view()
+ html_text = view()
packageset_text = re.compile('\s*' + ps.name)
self._test_packagesets(
- html, packageset_text, 'packagesets', 'Packagesets')
+ html_text, packageset_text, 'packagesets', 'Packagesets')
=== modified file 'lib/lp/registry/interfaces/distroseriesdifference.py'
--- lib/lp/registry/interfaces/distroseriesdifference.py 2011-04-19 02:57:38 +0000
+++ lib/lp/registry/interfaces/distroseriesdifference.py 2011-05-03 12:15:18 +0000
@@ -303,3 +303,12 @@
:param source_package_name: The name of the package difference.
:type source_package_name: unicode.
"""
+
+ def getSimpleUpgrades(distro_series):
+ """Find pending upgrades that can be performed mindlessly.
+
+ These are `DistroSeriesDifferences` where the parent has been
+ updated and the child still has the old version, unchanged.
+
+ Blacklisted items are excluded.
+ """
=== modified file 'lib/lp/registry/model/distroseriesdifference.py'
--- lib/lp/registry/model/distroseriesdifference.py 2011-04-22 00:58:35 +0000
+++ lib/lp/registry/model/distroseriesdifference.py 2011-05-03 12:15:18 +0000
@@ -277,29 +277,26 @@
And(*conditions)).order_by(SourcePackageName.name)
def eager_load(dsds):
+ active_statuses = (
+ PackagePublishingStatus.PUBLISHED,
+ PackagePublishingStatus.PENDING,
+ )
source_pubs = dict(
most_recent_publications(
- dsds, in_parent=False, statuses=(
- PackagePublishingStatus.PUBLISHED,
- PackagePublishingStatus.PENDING)))
+ dsds, statuses=active_statuses,
+ in_parent=False, match_version=False))
parent_source_pubs = dict(
most_recent_publications(
- dsds, in_parent=True, statuses=(
- PackagePublishingStatus.PUBLISHED,
- PackagePublishingStatus.PENDING)))
-
+ dsds, statuses=active_statuses,
+ in_parent=True, match_version=False))
source_pubs_for_release = dict(
most_recent_publications(
- dsds, in_parent=False, statuses=(
- PackagePublishingStatus.PUBLISHED,
- PackagePublishingStatus.PENDING),
- match_version=True))
+ dsds, statuses=active_statuses,
+ in_parent=False, match_version=True))
parent_source_pubs_for_release = dict(
most_recent_publications(
- dsds, in_parent=True, statuses=(
- PackagePublishingStatus.PUBLISHED,
- PackagePublishingStatus.PENDING),
- match_version=True))
+ dsds, statuses=active_statuses,
+ in_parent=True, match_version=True))
latest_comment_by_dsd_id = dict(
(comment.distro_series_difference_id, comment)
@@ -376,6 +373,23 @@
SourcePackageName.id),
SourcePackageName.name == source_package_name).one()
+ @staticmethod
+ def getSimpleUpgrades(distro_series):
+ """See `IDistroSeriesDifferenceSource`."""
+ return IStore(DistroSeriesDifference).find(
+ DistroSeriesDifference,
+ SourcePackageName.id ==
+ DistroSeriesDifference.source_package_name_id,
+ DistroSeriesDifference.derived_series == distro_series,
+ DistroSeriesDifference.difference_type ==
+ DistroSeriesDifferenceType.DIFFERENT_VERSIONS,
+ DistroSeriesDifference.status ==
+ DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
+ DistroSeriesDifference.parent_source_version !=
+ DistroSeriesDifference.base_version,
+ DistroSeriesDifference.source_version ==
+ DistroSeriesDifference.base_version)
+
@cachedproperty
def source_pub(self):
"""See `IDistroSeriesDifference`."""
=== modified file 'lib/lp/registry/tests/test_distroseriesdifference.py'
--- lib/lp/registry/tests/test_distroseriesdifference.py 2011-04-21 16:11:51 +0000
+++ lib/lp/registry/tests/test_distroseriesdifference.py 2011-05-03 12:15:18 +0000
@@ -1,4 +1,4 @@
-# Copyright 2010 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2011 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Model tests for the DistroSeriesDifference class."""
@@ -903,6 +903,36 @@
return self.factory.makeDistroSeries(
parent_series=self.factory.makeDistroSeries())
+ def makeVersionDifference(self, derived_series=None, changed_parent=False,
+ changed_child=False, status=None):
+ """Create a `DistroSeriesDifference` between package versions.
+
+ The differing package will exist in both the parent series and in the
+ child.
+
+ :param derived_series: Optional `DistroSeries` that the difference is
+ for. If not given, one will be created.
+ :param changed_parent: Whether the difference should show a change in
+ the parent's version of the package.
+ :param changed_child: Whether the difference should show a change in
+ the child's version of the package.
+ :param status: Optional status for the `DistroSeriesDifference`. If
+ not given, defaults to `NEEDS_ATTENTION`.
+ """
+ if status is None:
+ status = DistroSeriesDifferenceStatus.NEEDS_ATTENTION
+ base_version = "1.%d" % self.factory.getUniqueInteger()
+ versions = dict(
+ (key, base_version)
+ for key in ['base', 'parent', 'derived'])
+ if changed_parent:
+ versions['parent'] += "-%s" % self.factory.getUniqueString()
+ if changed_child:
+ versions['derived'] += "-%s" % self.factory.getUniqueString()
+ return self.factory.makeDistroSeriesDifference(
+ derived_series=derived_series, versions=versions, status=status,
+ set_base_version=True)
+
def test_getForDistroSeries_default(self):
# By default all differences needing attention for the given
# series are returned.
@@ -987,6 +1017,61 @@
self.assertEqual(ds_diff, result)
+ def test_getSimpleUpdates_finds_simple_update(self):
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ dsd = self.makeVersionDifference(changed_parent=True)
+ self.assertEqual(dsd.base_version, dsd.source_version)
+ self.assertContentEqual(
+ [dsd], dsd_source.getSimpleUpdates(dsd.derived_series))
+
+ def test_getSimpleUpdates_ignores_hidden_differences(self):
+ invisible_statuses = [
+ DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT,
+ DistroSeriesDifferenceStatus.BLACKLISTED_ALWAYS,
+ DistroSeriesDifferenceStatus.RESOLVED,
+ ]
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ series = self.makeDerivedSeries()
+ for status in invisible_statuses:
+ self.makeVersionDifference(
+ derived_series=series, changed_parent=True, status=status)
+ self.assertContentEqual([], dsd_source.getSimpleUpdates(series))
+
+ def test_getSimpleUpdates_ignores_other_distroseries(self):
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ self.makeVersionDifference(changed_parent=True)
+ self.assertContentEqual(
+ [], dsd_source.getSimpleUpdates(self.factory.makeDistroSeries()))
+
+ def test_getSimpleUpdates_ignores_packages_changed_in_child(self):
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ dsd = self.makeVersionDifference(
+ changed_parent=True, changed_child=True)
+ self.assertContentEqual(
+ [], dsd_source.getSimpleUpdates(dsd.derived_series))
+
+ def test_getSimpleUpdates_ignores_packages_not_updated_in_parent(self):
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ dsd = self.makeVersionDifference(changed_parent=False)
+ self.assertContentEqual(
+ [], dsd_source.getSimpleUpdates(dsd.derived_series))
+
+ def test_getSimpleUpdates_ignores_packages_unique_to_child(self):
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ diff_type = DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES
+ dsd = self.factory.makeDistroSeriesDifference(
+ difference_type=diff_type)
+ self.assertContentEqual(
+ [], dsd_source.getSimpleUpdates(dsd.derived_series))
+
+ def test_getSimpleUpdates_ignores_packages_missing_from_child(self):
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ diff_type = DistroSeriesDifferenceType.MISSING_FROM_DERIVED_SERIES
+ dsd = self.factory.makeDistroSeriesDifference(
+ difference_type=diff_type)
+ self.assertContentEqual(
+ [], dsd_source.getSimpleUpdates(dsd.derived_series))
+
class TestMostRecentComments(TestCaseWithFactory):
Follow ups