Merge lp:~jpds/launchpad/fix_361650_model_changes into lp:launchpad

Proposed by Jonathan Davies
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 10619
Proposed branch: lp:~jpds/launchpad/fix_361650_model_changes
Merge into: lp:launchpad
Diff against target: 857 lines (+470/-93)
11 files modified
lib/lp/registry/configure.zcml (+47/-5)
lib/lp/registry/doc/distribution-mirror.txt (+119/-1)
lib/lp/registry/interfaces/distribution.py (+9/-1)
lib/lp/registry/interfaces/distributionmirror.py (+96/-47)
lib/lp/registry/model/distribution.py (+11/-0)
lib/lp/registry/model/distributionmirror.py (+63/-1)
lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt (+11/-11)
lib/lp/registry/stories/webservice/xx-distribution-mirror.txt (+20/-11)
lib/lp/registry/stories/webservice/xx-distribution.txt (+74/-0)
lib/lp/registry/tests/test_distributionmirror.py (+4/-14)
lib/lp/testing/factory.py (+16/-2)
To merge this branch: bzr merge lp:~jpds/launchpad/fix_361650_model_changes
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+20785@code.launchpad.net

Commit message

Added models and tests for DistributionMirror.country_dns_mirror.

Description of the change

= Summary =

This branch builds on the schema changes introduced for bug #361650. Adding stuff to our models.

It also adds the API parts and mirror checks when marking mirrors as country mirrors with complete test suite.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (23.1 KiB)

Your merge proposal should show the output of make lint to verify your
changes did not have any cruft. It will also inform you of style mistakes
that must be fixed before making a merge proposal.

I have some ideas to improve the code, and I think the interface and model
are missing essential documentation and unit tests. I suspect that the
story tests (which are integration tests) are test what should be testing
as documentation and unit tests.

> === modified file 'lib/lp/registry/interfaces/distribution.py'
> --- lib/lp/registry/interfaces/distribution.py 2010-02-27 10:19:18 +0000
> +++ lib/lp/registry/interfaces/distribution.py 2010-03-06 00:09:35 +0000
> @@ -318,6 +318,16 @@
> if it's not found.
> """
>
> + @operation_parameters(
> + country=copy_field(IDistributionMirror['country'], required=True),
> + mirror_type=copy_field(IDistributionMirror['content'], required=True))
> + @operation_returns_entry(IDistributionMirror)
> + @export_read_operation()
> + def getCountryMirror(country, mirror_type):
> + """Return the country DNS mirror for a given country and content
> + type.
> + """
> +

This docstring does not follow PEP 257. The first sentence must be one line.
Subsequent sentences may follow after a blank line:
    http://www.python.org/dev/peps/pep-0257/

Think this fixes the issue:

        """Return the country DNS mirror for a country and content type."""

> === modified file 'lib/lp/registry/interfaces/distributionmirror.py'
> --- lib/lp/registry/interfaces/distributionmirror.py 2010-02-22 15:50:06 +0000
> +++ lib/lp/registry/interfaces/distributionmirror.py 2010-03-06 00:09:35 +0000
> @@ -6,21 +6,23 @@
> __metaclass__ = type
>
> __all__ = [
> +'CannotTransitionToCountryMirror',
> +'CountryMirrorAlreadySet',
> 'IDistributionMirror',
> -'IDistributionMirrorAdminRestricted',
> -'IDistributionMirrorEditRestricted',
> -'IDistributionMirrorPublic',
> 'IMirrorDistroArchSeries',
> 'IMirrorDistroSeriesSource',
> 'IMirrorProbeRecord',
> 'IDistributionMirrorSet',
> 'IMirrorCDImageDistroSeries',
> 'PROBE_INTERVAL',
> -'UnableToFetchCDImageFileList',
> 'MirrorContent',
> 'MirrorFreshness',
> +'MirrorHasNoHTTPUrl',
> +'MirrorNotOfficial',
> +'MirrorNotProbed',
> 'MirrorSpeed',
> -'MirrorStatus']
> +'MirrorStatus',
> +'UnableToFetchCDImageFileList']

Per PEP 8, this list of single entries must each be indented and required a
trailing comma; the closing bracket on on a separate line to minimise diffs,
which I can see that this diff is already a victim:

    'MirrorStatus',
    'UnableToFetchCDImageFileList',
    ]

> @@ -47,6 +52,44 @@
> PROBE_INTERVAL = 23
>
> +class CannotTransitionToCountryMirror(Exception):
> + """Root exception for transitions to country mirrors.
> + """

The closing quotes belong on the previous line PEP 257.

> + webservice_error(400) # HTTP Error: 'Bad Request'.

Launchpad style does not use trailing comments because they interfere with
refactoring. I do not think comments about HTTP codes are informative;
we are expect to know them.

> @@ -386,6 +406,33 @@
> date_created = exported(Datetime(
> title=_('Date Crea...

review: Needs Fixing (code)
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (5.9 KiB)

Hi Jonathan.

I have some trivial suggestions to improve this branch. I think the implementation
is good and ready to land.

I can land the branch at the end of this week after these changes are made.

make lint reported these problems that need fixing:

lib/lp/registry/interfaces/distributionmirror.py
    339: [C0301] Line too long (83/78)
    436: [W0311] Bad indentation. Found 7 spaces, expected 8

> === modified file 'lib/lp/registry/doc/distribution-mirror.txt'
> --- lib/lp/registry/doc/distribution-mirror.txt 2009-12-09 10:03:20 +0000
> +++ lib/lp/registry/doc/distribution-mirror.txt 2010-03-29 15:54:12 +0000

@@ -814,3 +814,107 @@

> +Country DNS mirrors
> +-------------------
> +
> +Country DNS mirrors are mirrors which have been assigned $CC.archive.ubuntu.com
> +or $CC.releases.ubuntu.com. These assignments are tracked in Launchpad.

Wrap the narrative at 78 characters.

> + >>> login('<email address hidden>')
> + >>> ubuntu_distro = getUtility(IDistributionSet).getByName('ubuntu')
> + >>> de_archive_mirror = factory.makeMirror(ubuntu_distro,
> + ... "Technische Universitaet Dresden", country=82,
> + ... http_url="http://ubuntu.mirror.tudos.de/ubuntu/",
> + ... official_candidate=True)
> + >>> davis_station_archive = factory.makeMirror(ubuntu_distro,
> + ... "Davis Station", country=9,
> + ... http_url="http://mirror.davis.antarctica.org/ubuntu",
> + ... official_candidate=True)
> + >>> de_archive_mirror.status = MirrorStatus.OFFICIAL
> + >>> de_archive_prober_log = factory.makeMirrorProbeRecord(de_archive_mirror)
> + >>> logout()

Wrap the code at 78 characters.

...

> +Mirrors which are not official or do not have an HTTP URL may not be set as
> +country mirrors:
> +
> + >>> login('<email address hidden>')
> + >>> osuosl_mirror = factory.makeMirror(ubuntu_distro, "OSU Open Source Lab",
> + ... country=226,
> + ... ftp_url="ftp://ubuntu.osuosl.org/pub/ubuntu/",
> + ... official_candidate=True)
> + >>> osuosl_mirror.status = MirrorStatus.OFFICIAL
> + >>> print osuosl_mirror.http_base_url
> + None

Wrap the code at 78 characters.

> === modified file 'lib/lp/registry/interfaces/distribution.py'
> --- lib/lp/registry/interfaces/distribution.py 2010-03-24 21:59:58 +0000
> +++ lib/lp/registry/interfaces/distribution.py 2010-03-29 15:54:12 +0000
>
> @@ -321,6 +321,14 @@
> if it's not found.
> """
>
> + @operation_parameters(
> + country=copy_field(IDistributionMirror['country'], required=True),
> + mirror_type=copy_field(IDistributionMirror['content'], required=True))
> + @operation_returns_entry(IDistributionMirror)
> + @export_read_operation()
> + def getCountryMirror(country, mirror_type):
> + """Return the country DNS mirror for acountry and content type."""

grammar: s/acountry/a country/

> === modified file 'lib/lp/registry/interfaces/distributionmirror.py'
> --- lib/lp/registry/interfaces/distributionmirror.py 2010-02-22 15:50:06 +0000
> +++ lib/lp/registry/interfaces/distributionmirror.py 2010-03-29 15:54:12 +0000
> @@ -6,21 +6,24 @@
> __metaclass__ = type

 __all__ = [
...

> + ...

Read more...

review: Needs Fixing (code)
Revision history for this message
Curtis Hovey (sinzui) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml 2010-03-19 11:33:44 +0000
+++ lib/lp/registry/configure.zcml 2010-03-31 15:03:35 +0000
@@ -1644,18 +1644,60 @@
1644 <!-- DistributionMirror -->1644 <!-- DistributionMirror -->
1645 <class class="lp.registry.model.distributionmirror.DistributionMirror">1645 <class class="lp.registry.model.distributionmirror.DistributionMirror">
1646 <allow1646 <allow
1647 interface="lp.registry.interfaces.distributionmirror.IDistributionMirrorPublic" />1647 attributes="
1648 id
1649 name
1650 displayname
1651 description
1652 distribution
1653 http_base_url
1654 ftp_base_url
1655 rsync_base_url
1656 enabled
1657 speed
1658 status
1659 country
1660 content
1661 owner
1662 title
1663 cdimage_series
1664 source_series
1665 arch_series
1666 last_probe_record
1667 all_probe_records
1668 has_ftp_or_rsync_base_url
1669 base_url
1670 date_created
1671 country_dns_mirror
1672 mirrorMustHaveHTTPOrFTPURL
1673 getSummarizedMirroredSourceSeries
1674 getSummarizedMirroredArchSeries
1675 getOverallFreshness
1676 isOfficial
1677 shouldDisable
1678 disable
1679 newProbeRecord
1680 deleteMirrorDistroArchSeries
1681 ensureMirrorDistroArchSeries
1682 ensureMirrorDistroSeriesSource
1683 deleteMirrorDistroSeriesSource
1684 ensureMirrorCDImageSeries
1685 deleteMirrorCDImageSeries
1686 deleteAllMirrorCDImageSeries
1687 getExpectedPackagesPaths
1688 getExpectedSourcesPaths
1689 canTransitionToCountryMirror" />
1648 <require1690 <require
1649 permission="launchpad.Edit"1691 permission="launchpad.Edit"
1650 interface="lp.registry.interfaces.distributionmirror.IDistributionMirrorEditRestricted"
1651 set_attributes="name displayname description whiteboard1692 set_attributes="name displayname description whiteboard
1652 http_base_url ftp_base_url rsync_base_url enabled1693 http_base_url ftp_base_url rsync_base_url enabled
1653 speed country content official_candidate owner" />1694 speed country content official_candidate owner"
1695 attributes="official_candidate whiteboard" />
1654 <require1696 <require
1655 permission="launchpad.Admin"1697 permission="launchpad.Admin"
1656 interface="lp.registry.interfaces.distributionmirror.IDistributionMirrorAdminRestricted"
1657 set_attributes="status reviewer date_reviewed"1698 set_attributes="status reviewer date_reviewed"
1658 attributes="destroySelf" />1699 attributes="reviewer date_reviewed destroySelf
1700 transitionToCountryMirror" />
1659 </class>1701 </class>
16601702
1661 <adapter1703 <adapter
16621704
=== modified file 'lib/lp/registry/doc/distribution-mirror.txt'
--- lib/lp/registry/doc/distribution-mirror.txt 2009-12-09 10:03:20 +0000
+++ lib/lp/registry/doc/distribution-mirror.txt 2010-03-31 15:03:35 +0000
@@ -8,7 +8,7 @@
8 >>> from canonical.launchpad.interfaces import (8 >>> from canonical.launchpad.interfaces import (
9 ... ICountrySet, IDistributionSet, IDistributionMirrorSet,9 ... ICountrySet, IDistributionSet, IDistributionMirrorSet,
10 ... IDistroArchSeriesSet, IDistroSeriesSet, ILibraryFileAliasSet,10 ... IDistroArchSeriesSet, IDistroSeriesSet, ILibraryFileAliasSet,
11 ... IPersonSet, MirrorContent, MirrorSpeed)11 ... IPersonSet, MirrorContent, MirrorSpeed, MirrorStatus)
12 >>> from lp.registry.interfaces.pocket import PackagePublishingPocket12 >>> from lp.registry.interfaces.pocket import PackagePublishingPocket
13 >>> mirrorset = getUtility(IDistributionMirrorSet)13 >>> mirrorset = getUtility(IDistributionMirrorSet)
14 >>> distroset = getUtility(IDistributionSet)14 >>> distroset = getUtility(IDistributionSet)
@@ -814,3 +814,121 @@
814 >>> mirrorset.getByName('invalid-mirror') is None814 >>> mirrorset.getByName('invalid-mirror') is None
815 True815 True
816816
817Country DNS mirrors
818-------------------
819
820Country DNS mirrors are mirrors which have been assigned
821$CC.archive.ubuntu.com or $CC.releases.ubuntu.com. These assignments are
822tracked in Launchpad.
823
824 >>> login('admin@canonical.com')
825 >>> ubuntu_distro = getUtility(IDistributionSet).getByName('ubuntu')
826 >>> de_archive_mirror = factory.makeMirror(ubuntu_distro,
827 ... "Technische Universitaet Dresden", country=82,
828 ... http_url="http://ubuntu.mirror.tudos.de/ubuntu/",
829 ... official_candidate=True)
830 >>> davis_station_archive = factory.makeMirror(ubuntu_distro,
831 ... "Davis Station", country=9,
832 ... http_url="http://mirror.davis.antarctica.org/ubuntu",
833 ... official_candidate=True)
834 >>> de_archive_mirror.status = MirrorStatus.OFFICIAL
835 >>> de_archive_prober_log = factory.makeMirrorProbeRecord(de_archive_mirror)
836 >>> logout()
837
838Normal users can access country_dns_mirror, can see if a mirror is eligible
839for the status, however, they may not change it:
840
841 >>> login('test@canonical.com')
842 >>> de_archive_mirror.canTransitionToCountryMirror()
843 True
844 >>> de_archive_mirror.transitionToCountryMirror(True)
845 Traceback (most recent call last):
846 ...
847 Unauthorized: (<DistributionMirror at ...>, 'transitionToCountryMirror',
848 'launchpad.Admin')
849 >>> logout()
850
851Mirror listing administrators may change the status however:
852
853 >>> login('karl@canonical.com')
854 >>> de_archive_mirror.transitionToCountryMirror(True)
855
856Mirrors which are already set as country mirrors can't be 'set' as such
857again:
858
859 >>> de_archive_mirror.canTransitionToCountryMirror()
860 False
861 >>> de_archive_mirror.transitionToCountryMirror(True)
862 >>> logout()
863
864There cannot be multiple country mirrors of one type for one country:
865
866 >>> login('karl@canonical.com')
867 >>> proberecord = factory.makeMirrorProbeRecord(davis_station_archive)
868
869 >>> print davis_station_archive.content.name
870 ARCHIVE
871 >>> print davis_station_archive.country_dns_mirror
872 False
873 >>> print davis_station_archive.country.name
874 Antarctica
875
876 >>> archive_mirror2 = getUtility(IDistributionMirrorSet).getByName(
877 ... 'archive-mirror2')
878 >>> print archive_mirror2.content.name
879 ARCHIVE
880 >>> print archive_mirror2.country_dns_mirror
881 False
882 >>> print archive_mirror2.country.name
883 Antarctica
884
885 >>> davis_station_archive.status = MirrorStatus.OFFICIAL
886
887 >>> davis_station_archive.transitionToCountryMirror(True)
888 >>> archive_mirror2.transitionToCountryMirror(True)
889 Traceback (most recent call last):
890 ...
891 CountryMirrorAlreadySet: Antarctica already has a country Archive mirror
892 set.
893
894Mirrors which have not been probed may not be marked as country mirrors:
895
896 >>> linux_au_mirror = factory.makeMirror(ubuntu_distro,
897 ... "Linux.org.au", country=14,
898 ... http_url="http://mirror.linux.org.au/ubuntu",
899 ... official_candidate=True)
900 >>> linux_au_mirror.status = MirrorStatus.OFFICIAL
901 >>> linux_au_mirror.transitionToCountryMirror(True)
902 Traceback (most recent call last):
903 ...
904 MirrorNotProbed: This mirror may not be set as a country mirror as it has
905 not been probed.
906 >>> logout()
907
908Mirrors which are not official or do not have an HTTP URL may not be set as
909country mirrors:
910
911 >>> login('admin@canonical.com')
912 >>> osuosl_mirror = factory.makeMirror(ubuntu_distro,
913 ... "OSU Open Source Lab", country=226,
914 ... ftp_url="ftp://ubuntu.osuosl.org/pub/ubuntu/",
915 ... official_candidate=True)
916 >>> osuosl_mirror.status = MirrorStatus.OFFICIAL
917 >>> print osuosl_mirror.http_base_url
918 None
919
920 >>> osuosl_mirror.canTransitionToCountryMirror()
921 False
922
923 >>> osuosl_mirror.transitionToCountryMirror(None)
924 Traceback (most recent call last):
925 ...
926 NoneError: None isn't acceptable as a value for
927 DistributionMirror.country_dns_mirror
928
929 >>> osuosl_mirror.transitionToCountryMirror(True)
930 Traceback (most recent call last):
931 ...
932 MirrorHasNoHTTPURL: This mirror may not be set as a country mirror as it
933 does not have an HTTP URL set.
934 >>> logout()
817935
=== modified file 'lib/lp/registry/interfaces/distribution.py'
--- lib/lp/registry/interfaces/distribution.py 2010-03-24 21:59:58 +0000
+++ lib/lp/registry/interfaces/distribution.py 2010-03-31 15:03:35 +0000
@@ -25,7 +25,7 @@
2525
26from lazr.restful.fields import CollectionField, Reference26from lazr.restful.fields import CollectionField, Reference
27from lazr.restful.declarations import (27from lazr.restful.declarations import (
28 collection_default_content, export_as_webservice_collection,28 collection_default_content, copy_field, export_as_webservice_collection,
29 export_as_webservice_entry, export_operation_as,29 export_as_webservice_entry, export_operation_as,
30 export_read_operation, exported, operation_parameters,30 export_read_operation, exported, operation_parameters,
31 operation_returns_collection_of, operation_returns_entry,31 operation_returns_collection_of, operation_returns_entry,
@@ -321,6 +321,14 @@
321 if it's not found.321 if it's not found.
322 """322 """
323323
324 @operation_parameters(
325 country=copy_field(IDistributionMirror['country'], required=True),
326 mirror_type=copy_field(IDistributionMirror['content'], required=True))
327 @operation_returns_entry(IDistributionMirror)
328 @export_read_operation()
329 def getCountryMirror(country, mirror_type):
330 """Return the country DNS mirror for a country and content type."""
331
324 def newMirror(owner, speed, country, content, displayname=None,332 def newMirror(owner, speed, country, content, displayname=None,
325 description=None, http_base_url=None,333 description=None, http_base_url=None,
326 ftp_base_url=None, rsync_base_url=None, enabled=False,334 ftp_base_url=None, rsync_base_url=None, enabled=False,
327335
=== modified file 'lib/lp/registry/interfaces/distributionmirror.py'
--- lib/lp/registry/interfaces/distributionmirror.py 2010-02-22 15:50:06 +0000
+++ lib/lp/registry/interfaces/distributionmirror.py 2010-03-31 15:03:35 +0000
@@ -6,21 +6,24 @@
6__metaclass__ = type6__metaclass__ = type
77
8__all__ = [8__all__ = [
9'IDistributionMirror',9 'CannotTransitionToCountryMirror',
10'IDistributionMirrorAdminRestricted',10 'CountryMirrorAlreadySet',
11'IDistributionMirrorEditRestricted',11 'IDistributionMirror',
12'IDistributionMirrorPublic',12 'IMirrorDistroArchSeries',
13'IMirrorDistroArchSeries',13 'IMirrorDistroSeriesSource',
14'IMirrorDistroSeriesSource',14 'IMirrorProbeRecord',
15'IMirrorProbeRecord',15 'IDistributionMirrorSet',
16'IDistributionMirrorSet',16 'IMirrorCDImageDistroSeries',
17'IMirrorCDImageDistroSeries',17 'PROBE_INTERVAL',
18'PROBE_INTERVAL',18 'MirrorContent',
19'UnableToFetchCDImageFileList',19 'MirrorFreshness',
20'MirrorContent',20 'MirrorHasNoHTTPURL',
21'MirrorFreshness',21 'MirrorNotOfficial',
22'MirrorSpeed',22 'MirrorNotProbed',
23'MirrorStatus']23 'MirrorSpeed',
24 'MirrorStatus',
25 'UnableToFetchCDImageFileList',
26 ]
2427
25from cgi import escape28from cgi import escape
2629
@@ -31,8 +34,11 @@
31from zope.component import getUtility34from zope.component import getUtility
32from lazr.enum import DBEnumeratedType, DBItem35from lazr.enum import DBEnumeratedType, DBItem
33from lazr.restful.declarations import (36from lazr.restful.declarations import (
34 export_as_webservice_entry, export_read_operation, exported)37 export_as_webservice_entry, export_read_operation,
38 export_write_operation, exported, mutator_for, operation_parameters,
39 webservice_error)
35from lazr.restful.fields import Reference, ReferenceChoice40from lazr.restful.fields import Reference, ReferenceChoice
41from lazr.restful.interface import copy_field
3642
37from canonical.launchpad import _43from canonical.launchpad import _
38from canonical.launchpad.fields import (44from canonical.launchpad.fields import (
@@ -47,6 +53,43 @@
47PROBE_INTERVAL = 2353PROBE_INTERVAL = 23
4854
4955
56class CannotTransitionToCountryMirror(Exception):
57 """Root exception for transitions to country mirrors."""
58 webservice_error(400)
59
60
61class CountryMirrorAlreadySet(CannotTransitionToCountryMirror):
62 """Distribution mirror cannot be set as a country mirror.
63
64 Raised when a user tries to change set a distribution mirror as a country
65 mirror, however there is already one set for that country.
66 """
67
68
69class MirrorNotOfficial(CannotTransitionToCountryMirror):
70 """Distribution mirror is not permitted to become a country mirror.
71
72 Raised when a user tries to change set a distribution mirror as a country
73 mirror, however the mirror in question is not official.
74 """
75
76
77class MirrorHasNoHTTPURL(CannotTransitionToCountryMirror):
78 """Distribution mirror has no HTTP URL.
79
80 Raised when a user tries to make an official mirror a country mirror,
81 however the mirror has not HTTP URL set.
82 """
83
84
85class MirrorNotProbed(CannotTransitionToCountryMirror):
86 """Distribution mirror has not been probed.
87
88 Raised when a user tries to set an official mirror as a country mirror,
89 however the mirror has not been probed yet.
90 """
91
92
50class MirrorContent(DBEnumeratedType):93class MirrorContent(DBEnumeratedType):
51 """The content that is mirrored."""94 """The content that is mirrored."""
5295
@@ -284,33 +327,10 @@
284 def getMirrorByURI(self, url):327 def getMirrorByURI(self, url):
285 return getUtility(IDistributionMirrorSet).getByRsyncUrl(url)328 return getUtility(IDistributionMirrorSet).getByRsyncUrl(url)
286329
287class IDistributionMirrorAdminRestricted(Interface):330
288 """IDistributionMirror properties requiring launchpad.Admin permission."""331class IDistributionMirror(Interface):
289332 """A mirror of a given distribution."""
290 reviewer = exported(PublicPersonChoice(333 export_as_webservice_entry()
291 title=_('Reviewer'), required=False, readonly=True,
292 vocabulary='ValidPersonOrTeam', description=_(
293 "The person who last reviewed this mirror.")))
294 date_reviewed = exported(Datetime(
295 title=_('Date reviewed'), required=False, readonly=True,
296 description=_(
297 "The date on which this mirror was last reviewed by a mirror admin.")))
298
299
300class IDistributionMirrorEditRestricted(Interface):
301 """IDistributionMirror properties requiring launchpad.Edit permission."""
302
303 official_candidate = exported(Bool(
304 title=_('Apply to be an official mirror of this distribution'),
305 required=False, readonly=False, default=True))
306 whiteboard = exported(Whiteboard(
307 title=_('Whiteboard'), required=False, readonly=False,
308 description=_("Notes on the current status of the mirror (only "
309 "visible to admins and the mirror's registrant).")))
310
311
312class IDistributionMirrorPublic(Interface):
313 """Public IDistributionMirror properties."""
314334
315 id = Int(title=_('The unique id'), required=True, readonly=True)335 id = Int(title=_('The unique id'), required=True, readonly=True)
316 owner = exported(PublicPersonChoice(336 owner = exported(PublicPersonChoice(
@@ -386,6 +406,39 @@
386 date_created = exported(Datetime(406 date_created = exported(Datetime(
387 title=_('Date Created'), required=True, readonly=True,407 title=_('Date Created'), required=True, readonly=True,
388 description=_("The date on which this mirror was registered.")))408 description=_("The date on which this mirror was registered.")))
409 country_dns_mirror = exported(Bool(
410 title=_('Country DNS Mirror'),
411 description=_('Whether this is a country mirror in DNS.'),
412 required=False, readonly=True, default=False))
413
414 reviewer = exported(PublicPersonChoice(
415 title=_('Reviewer'), required=False, readonly=True,
416 vocabulary='ValidPersonOrTeam', description=_(
417 "The person who last reviewed this mirror.")))
418 date_reviewed = exported(Datetime(
419 title=_('Date reviewed'), required=False, readonly=True,
420 description=_(
421 "The date on which this mirror was last reviewed by a mirror "
422 "admin.")))
423
424 official_candidate = exported(Bool(
425 title=_('Apply to be an official mirror of this distribution'),
426 required=False, readonly=False, default=True))
427 whiteboard = exported(Whiteboard(
428 title=_('Whiteboard'), required=False, readonly=False,
429 description=_("Notes on the current status of the mirror (only "
430 "visible to admins and the mirror's registrant).")))
431
432 @export_read_operation()
433 def canTransitionToCountryMirror():
434 """Verify if a mirror can be set as a country mirror or return
435 False."""
436
437 @mutator_for(country_dns_mirror)
438 @operation_parameters(country_dns_mirror=copy_field(country_dns_mirror))
439 @export_write_operation()
440 def transitionToCountryMirror(country_dns_mirror):
441 """Method run on changing country_dns_mirror."""
389442
390 @invariant443 @invariant
391 def mirrorMustHaveHTTPOrFTPURL(mirror):444 def mirrorMustHaveHTTPOrFTPURL(mirror):
@@ -521,10 +574,6 @@
521 Sources.gz file refer to and the path to the file itself.574 Sources.gz file refer to and the path to the file itself.
522 """575 """
523576
524class IDistributionMirror(IDistributionMirrorAdminRestricted,
525 IDistributionMirrorEditRestricted, IDistributionMirrorPublic):
526 """A mirror of a given distribution."""
527 export_as_webservice_entry()
528577
529578
530class UnableToFetchCDImageFileList(Exception):579class UnableToFetchCDImageFileList(Exception):
531580
=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py 2010-03-24 02:53:42 +0000
+++ lib/lp/registry/model/distribution.py 2010-03-31 15:03:35 +0000
@@ -402,6 +402,17 @@
402 """See `IDistribution`."""402 """See `IDistribution`."""
403 return DistributionMirror.selectOneBy(distribution=self, name=name)403 return DistributionMirror.selectOneBy(distribution=self, name=name)
404404
405 def getCountryMirror(self, country, mirror_type):
406 """See `IDistribution`."""
407 store = Store.of(self)
408 results = store.find(
409 DistributionMirror,
410 DistributionMirror.distribution == self,
411 DistributionMirror.country == country,
412 DistributionMirror.content == mirror_type,
413 DistributionMirror.country_dns_mirror == True)
414 return results.one()
415
405 def newMirror(self, owner, speed, country, content, displayname=None,416 def newMirror(self, owner, speed, country, content, displayname=None,
406 description=None, http_base_url=None,417 description=None, http_base_url=None,
407 ftp_base_url=None, rsync_base_url=None,418 ftp_base_url=None, rsync_base_url=None,
408419
=== modified file 'lib/lp/registry/model/distributionmirror.py'
--- lib/lp/registry/model/distributionmirror.py 2010-03-23 20:42:23 +0000
+++ lib/lp/registry/model/distributionmirror.py 2010-03-31 15:03:35 +0000
@@ -45,9 +45,11 @@
45from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities45from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
46from lp.soyuz.interfaces.publishing import PackagePublishingStatus46from lp.soyuz.interfaces.publishing import PackagePublishingStatus
47from lp.registry.interfaces.distributionmirror import (47from lp.registry.interfaces.distributionmirror import (
48 CannotTransitionToCountryMirror, CountryMirrorAlreadySet,
48 IDistributionMirror, IDistributionMirrorSet, IMirrorCDImageDistroSeries,49 IDistributionMirror, IDistributionMirrorSet, IMirrorCDImageDistroSeries,
49 IMirrorDistroArchSeries, IMirrorDistroSeriesSource, IMirrorProbeRecord,50 IMirrorDistroArchSeries, IMirrorDistroSeriesSource, IMirrorProbeRecord,
50 MirrorContent, MirrorFreshness, MirrorSpeed, MirrorStatus, PROBE_INTERVAL)51 MirrorContent, MirrorFreshness, MirrorHasNoHTTPURL, MirrorNotOfficial,
52 MirrorNotProbed, MirrorSpeed, MirrorStatus, PROBE_INTERVAL)
51from lp.registry.interfaces.distroseries import IDistroSeries53from lp.registry.interfaces.distroseries import IDistroSeries
52from lp.registry.interfaces.sourcepackage import SourcePackageFileType54from lp.registry.interfaces.sourcepackage import SourcePackageFileType
53from canonical.launchpad.mail import simple_sendmail, format_address55from canonical.launchpad.mail import simple_sendmail, format_address
@@ -100,6 +102,8 @@
100 date_reviewed = UtcDateTimeCol(default=None)102 date_reviewed = UtcDateTimeCol(default=None)
101 whiteboard = StringCol(103 whiteboard = StringCol(
102 notNull=False, default=None)104 notNull=False, default=None)
105 country_dns_mirror = BoolCol(
106 notNull=True, default=False)
103107
104 @property108 @property
105 def base_url(self):109 def base_url(self):
@@ -145,6 +149,64 @@
145 "This mirror has been probed and thus can't be removed.")149 "This mirror has been probed and thus can't be removed.")
146 SQLBase.destroySelf(self)150 SQLBase.destroySelf(self)
147151
152 def verifyTransitionToCountryMirror(self):
153 """Verify that a mirror can be set as a country mirror.
154
155 Return True if valid, otherwise raise a subclass of
156 CannotTransitionToCountryMirror.
157 """
158
159 current_country_mirror = self.distribution.getCountryMirror(
160 self.country, self.content)
161
162 if current_country_mirror is not None:
163 # Country already has a country mirror.
164 raise CountryMirrorAlreadySet(
165 "%s already has a country %s mirror set." % (
166 self.country.name, self.content))
167
168 if not self.isOfficial():
169 # Only official mirrors may be set as country mirrors.
170 raise MirrorNotOfficial(
171 "This mirror may not be set as a country mirror as it is not "
172 "an official mirror.")
173
174 if self.http_base_url is None:
175 # Country mirrors must have HTTP URLs set.
176 raise MirrorHasNoHTTPURL(
177 "This mirror may not be set as a country mirror as it does "
178 "not have an HTTP URL set.")
179
180 if not self.last_probe_record:
181 # Only mirrors which have been probed may be set as country
182 # mirrors.
183 raise MirrorNotProbed(
184 "This mirror may not be set as a country mirror as it has "
185 "not been probed.")
186
187 # Verification done.
188 return True
189
190 def canTransitionToCountryMirror(self):
191 """See `IDistributionMirror`."""
192 try:
193 return self.verifyTransitionToCountryMirror()
194 except CannotTransitionToCountryMirror:
195 return False
196
197 def transitionToCountryMirror(self, country_dns_mirror):
198 """See `IDistributionMirror`."""
199
200 # country_dns_mirror has not been changed, do nothing.
201 if self.country_dns_mirror == country_dns_mirror:
202 return
203
204 # Environment sanity checks.
205 if country_dns_mirror:
206 self.verifyTransitionToCountryMirror()
207
208 self.country_dns_mirror = country_dns_mirror
209
148 def getOverallFreshness(self):210 def getOverallFreshness(self):
149 """See IDistributionMirror"""211 """See IDistributionMirror"""
150 # XXX Guilherme Salgado 2006-08-16:212 # XXX Guilherme Salgado 2006-08-16:
151213
=== modified file 'lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt'
--- lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt 2009-12-10 23:32:13 +0000
+++ lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt 2010-03-31 15:03:35 +0000
@@ -40,13 +40,14 @@
40 >>> print browser.title40 >>> print browser.title
41 Mirrors of Ubuntu Linux...41 Mirrors of Ubuntu Linux...
42 >>> print_mirrors_by_countries(browser.contents)42 >>> print_mirrors_by_countries(browser.contents)
43 Antarctica:43 Antarctica: [(u'Archive-mirror2', u'http', u'128 Kbps',
44 [(u'Archive-mirror2', u'http', u'128 Kbps', u'Six hours behind')]44 u'Six hours behind')]
45 France:45 France:
46 [(u'Archive-404-mirror', u'http', u'512 Kbps', u'Last update unknown'),46 [(u'Archive-404-mirror', u'http', u'512 Kbps', u'Last update unknown'),
47 (u'Archive-mirror', u'http', u'128 Kbps', u'Last update unknown')]47 (u'Archive-mirror', u'http', u'128 Kbps', u'Last update unknown')]
48 United Kingdom:48 United Kingdom: [(u'Canonical-archive', u'http', u'100 Mbps',
49 [(u'Canonical-archive', u'http', u'100 Mbps', u'Last update unknown')]49 u'Last update unknown')]
50
50 >>> find_tags_by_class(browser.contents, 'distromirrorstatusSIXHOURSBEHIND')51 >>> find_tags_by_class(browser.contents, 'distromirrorstatusSIXHOURSBEHIND')
51 [<span class="distromirrorstatusSIXHOURSBEHIND">Six hours behind</span>]52 [<span class="distromirrorstatusSIXHOURSBEHIND">Six hours behind</span>]
52 >>> find_tags_by_class(browser.contents, 'distromirrorstatusUNKNOWN')[0]53 >>> find_tags_by_class(browser.contents, 'distromirrorstatusUNKNOWN')[0]
@@ -59,13 +60,12 @@
59 >>> browser.url60 >>> browser.url
60 'http://launchpad.dev/ubuntu/+cdmirrors'61 'http://launchpad.dev/ubuntu/+cdmirrors'
61 >>> print_mirrors_by_countries(browser.contents)62 >>> print_mirrors_by_countries(browser.contents)
62 France:63 France:
63 [(u'Releases-mirror', u'http', u'2 Mbps'),64 [(u'Releases-mirror', u'http', u'2 Mbps'),
64 (u'Unreachable-mirror', u'http', u'512 Kbps')]65 (u'Unreachable-mirror', u'http', u'512 Kbps')]
65 Germany:66 Germany: [(u'Releases-mirror2', u'http', u'2 Mbps')]
66 [(u'Releases-mirror2', u'http', u'2 Mbps')]67 United Kingdom: [(u'Canonical-releases', u'http', u'100 Mbps')]
67 United Kingdom:68
68 [(u'Canonical-releases', u'http', u'100 Mbps')]
6969
70=== Disabled mirrors ===70=== Disabled mirrors ===
7171
7272
=== modified file 'lib/lp/registry/stories/webservice/xx-distribution-mirror.txt'
--- lib/lp/registry/stories/webservice/xx-distribution-mirror.txt 2010-02-23 19:40:45 +0000
+++ lib/lp/registry/stories/webservice/xx-distribution-mirror.txt 2010-03-31 15:03:35 +0000
@@ -8,10 +8,12 @@
8 >>> distro = distros['entries'][0]8 >>> distro = distros['entries'][0]
9 >>> ubuntu = webservice.get(distro['self_link']).jsonBody()9 >>> ubuntu = webservice.get(distro['self_link']).jsonBody()
10 >>> ubuntu_archive_mirrors = webservice.get(ubuntu['archive_mirrors_collection_link']).jsonBody()10 >>> ubuntu_archive_mirrors = webservice.get(ubuntu['archive_mirrors_collection_link']).jsonBody()
11 >>> canonical_archive = ubuntu_archive_mirrors['entries'][0]11 >>> canonical_archive = webservice.named_get(
12 >>> canonical_archive_json = webservice.get(canonical_archive['self_link']).jsonBody()12 ... ubuntu['self_link'], 'getMirrorByName',
13 >>> pprint_entry(canonical_archive_json)13 ... name='canonical-archive').jsonBody()
14 >>> pprint_entry(canonical_archive)
14 content: u'Archive'15 content: u'Archive'
16 country_dns_mirror: False
15 country_link: u'http://.../+countries/GB'17 country_link: u'http://.../+countries/GB'
16 date_created: u'2006-10-16T18:31:43.434567+00:00'18 date_created: u'2006-10-16T18:31:43.434567+00:00'
17 date_reviewed: None19 date_reviewed: None
@@ -39,6 +41,7 @@
39 >>> canonical_releases_json = webservice.get(canonical_releases['self_link']).jsonBody()41 >>> canonical_releases_json = webservice.get(canonical_releases['self_link']).jsonBody()
40 >>> pprint_entry(canonical_releases_json)42 >>> pprint_entry(canonical_releases_json)
41 content: u'CD Image'43 content: u'CD Image'
44 country_dns_mirror: False
42 country_link: u'http://.../+countries/GB'45 country_link: u'http://.../+countries/GB'
43 date_created: u'2006-10-16T18:31:43.434567+00:00'46 date_created: u'2006-10-16T18:31:43.434567+00:00'
44 date_reviewed: None47 date_reviewed: None
@@ -73,12 +76,12 @@
73 >>> karl_db = getUtility(IPersonSet).getByName('karl')76 >>> karl_db = getUtility(IPersonSet).getByName('karl')
74 >>> test_db = getUtility(IPersonSet).getByName('name12')77 >>> test_db = getUtility(IPersonSet).getByName('name12')
75 >>> no_priv_db = getUtility(IPersonSet).getByName('no-priv')78 >>> no_priv_db = getUtility(IPersonSet).getByName('no-priv')
76 >>> karl_webservice = webservice_for_person(karl_db,79 >>> karl_webservice = webservice_for_person(
77 ... permission=OAuthPermission.WRITE_PUBLIC)80 ... karl_db, permission=OAuthPermission.WRITE_PUBLIC)
78 >>> test_webservice = webservice_for_person(test_db,81 >>> test_webservice = webservice_for_person(
79 ... permission=OAuthPermission.WRITE_PUBLIC)82 ... test_db, permission=OAuthPermission.WRITE_PUBLIC)
80 >>> no_priv_webservice = webservice_for_person(no_priv_db,83 >>> no_priv_webservice = webservice_for_person(
81 ... permission=OAuthPermission.READ_PUBLIC)84 ... no_priv_db, permission=OAuthPermission.READ_PUBLIC)
82 >>> logout()85 >>> logout()
8386
84Ensure that anonymous API sessions can view mirror listings; archive/releases.87Ensure that anonymous API sessions can view mirror listings; archive/releases.
@@ -97,7 +100,9 @@
97100
98One must have special permissions to access certain attributes:101One must have special permissions to access certain attributes:
99102
100 >>> archive_404_mirror = ubuntu_archive_mirrors['entries'][1]103 >>> archive_404_mirror = webservice.named_get(
104 ... ubuntu['self_link'], 'getMirrorByName',
105 ... name="archive-404-mirror").jsonBody()
101 >>> response = no_priv_webservice.get(106 >>> response = no_priv_webservice.get(
102 ... archive_404_mirror['self_link']).jsonBody()107 ... archive_404_mirror['self_link']).jsonBody()
103 >>> pprint_entry(response)108 >>> pprint_entry(response)
@@ -128,6 +133,7 @@
128 ... archive_404_mirror['self_link']).jsonBody()133 ... archive_404_mirror['self_link']).jsonBody()
129 >>> pprint_entry(response)134 >>> pprint_entry(response)
130 content: u'Archive'135 content: u'Archive'
136 country_dns_mirror: False
131 country_link: u'http://.../+countries/FR'137 country_link: u'http://.../+countries/FR'
132 date_created: u'2006-10-16T18:31:43.438573+00:00'138 date_created: u'2006-10-16T18:31:43.438573+00:00'
133 date_reviewed: None139 date_reviewed: None
@@ -209,6 +215,7 @@
209 ... canonical_releases['self_link'], 'application/json', dumps(patch)).jsonBody()215 ... canonical_releases['self_link'], 'application/json', dumps(patch)).jsonBody()
210 >>> pprint_entry(response)216 >>> pprint_entry(response)
211 content: u'CD Image'217 content: u'CD Image'
218 country_dns_mirror: False
212 country_link: u'http://.../+countries/GL'219 country_link: u'http://.../+countries/GL'
213 date_created: u'2006-10-16T18:31:43.434567+00:00'220 date_created: u'2006-10-16T18:31:43.434567+00:00'
214 date_reviewed: None221 date_reviewed: None
@@ -244,7 +251,9 @@
244"getOverallFreshness" returns the freshness of the mirror determined by the251"getOverallFreshness" returns the freshness of the mirror determined by the
245mirror prober from the mirror's last probe.252mirror prober from the mirror's last probe.
246253
247 >>> releases_mirror2 = ubuntu_cd_mirrors['entries'][2]254 >>> releases_mirror2 = webservice.named_get(
255 ... ubuntu['self_link'], 'getMirrorByName',
256 ... name='releases-mirror2').jsonBody()
248 >>> freshness = webservice.named_get(releases_mirror2['self_link'],257 >>> freshness = webservice.named_get(releases_mirror2['self_link'],
249 ... 'getOverallFreshness').jsonBody()258 ... 'getOverallFreshness').jsonBody()
250 >>> print freshness259 >>> print freshness
251260
=== modified file 'lib/lp/registry/stories/webservice/xx-distribution.txt'
--- lib/lp/registry/stories/webservice/xx-distribution.txt 2010-02-23 17:36:27 +0000
+++ lib/lp/registry/stories/webservice/xx-distribution.txt 2010-03-31 15:03:35 +0000
@@ -123,6 +123,7 @@
123 ... name='canonical-releases').jsonBody()123 ... name='canonical-releases').jsonBody()
124 >>> pprint_entry(canonical_releases)124 >>> pprint_entry(canonical_releases)
125 content: u'CD Image'125 content: u'CD Image'
126 country_dns_mirror: False
126 country_link: u'http://.../+countries/GB'127 country_link: u'http://.../+countries/GB'
127 date_created: u'2006-10-16T18:31:43.434567+00:00'128 date_created: u'2006-10-16T18:31:43.434567+00:00'
128 date_reviewed: None129 date_reviewed: None
@@ -142,3 +143,76 @@
142 speed: u'100 Mbps'143 speed: u'100 Mbps'
143 status: u'Official'144 status: u'Official'
144 whiteboard: None145 whiteboard: None
146
147"getCountryMirror" returns the country DNS mirror for a given country;
148returning None if there isn't one.
149
150 >>> # Prepare stuff.
151 >>> from lp.registry.interfaces.distribution import IDistributionSet
152 >>> from zope.component import getUtility
153 >>> from canonical.launchpad.testing.pages import webservice_for_person
154 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission
155 >>> from lp.registry.interfaces.person import IPersonSet
156 >>> from simplejson import dumps
157
158 >>> login('admin@canonical.com')
159 >>> ubuntu_distro = getUtility(IDistributionSet).getByName('ubuntu')
160 >>> showa_station = factory.makeMirror(ubuntu_distro,
161 ... "Showa Station", country=9,
162 ... http_url="http://mirror.showa.antarctica.org/ubuntu",
163 ... official_candidate=True)
164 >>> showa_station_log = factory.makeMirrorProbeRecord(showa_station)
165 >>> logout()
166
167 >>> login(ANONYMOUS)
168 >>> karl_db = getUtility(IPersonSet).getByName('karl')
169 >>> karl_webservice = webservice_for_person(karl_db,
170 ... permission=OAuthPermission.WRITE_PUBLIC)
171 >>> logout()
172
173 >>> # Mark new mirror as official and a country mirror.
174 >>> patch = {
175 ... u'status': 'Official',
176 ... u'country_dns_mirror': True
177 ... }
178
179 >>> antarctica_patch_target = webservice.named_get(
180 ... ubuntu['self_link'], 'getMirrorByName',
181 ... name='mirror.showa.antarctica.org-archive').jsonBody()
182 ... )
183
184 >>> response = karl_webservice.patch(
185 ... antarctica_patch_target['self_link'], 'application/json',
186 ... dumps(patch))
187
188 >>> antarctica = webservice.get("/+countries/AQ").jsonBody()
189 >>> antarctica_country_mirror_archive = webservice.named_get(
190 ... ubuntu['self_link'], 'getCountryMirror',
191 ... country=antarctica['self_link'],
192 ... mirror_type="Archive").jsonBody()
193 >>> pprint_entry(antarctica_country_mirror_archive)
194 content: u'Archive'
195 country_dns_mirror: True
196 country_link: u'http://.../+countries/AQ'
197 ...
198
199 >>> uk = webservice.get("/+countries/GB").jsonBody()
200 >>> uk_country_mirror_archive = webservice.named_get(
201 ... ubuntu['self_link'], 'getCountryMirror',
202 ... country=uk['self_link'],
203 ... mirror_type="Archive")
204 >>> print uk_country_mirror_archive.jsonBody()
205 None
206
207For "getCountryMirror", the mirror_type parameter must be "Archive" or
208"CD Images":
209
210 >>> uk_country_mirror_archive = webservice.named_get(
211 ... ubuntu['self_link'], 'getCountryMirror',
212 ... country=uk['self_link'],
213 ... mirror_type="Bogus")
214 >>> print uk_country_mirror_archive.jsonBody()
215 Traceback (most recent call last):
216 ...
217 ValueError: mirror_type: Invalid value "Bogus". Acceptable values are:
218 Archive, CD Image
145219
=== modified file 'lib/lp/registry/tests/test_distributionmirror.py'
--- lib/lp/registry/tests/test_distributionmirror.py 2009-10-26 18:40:04 +0000
+++ lib/lp/registry/tests/test_distributionmirror.py 2010-03-31 15:03:35 +0000
@@ -3,7 +3,6 @@
33
4__metaclass__ = type4__metaclass__ = type
55
6from StringIO import StringIO
7import unittest6import unittest
87
9import transaction8import transaction
@@ -17,19 +16,19 @@
17from lp.registry.interfaces.distributionmirror import (16from lp.registry.interfaces.distributionmirror import (
18 IDistributionMirrorSet, MirrorContent, MirrorFreshness)17 IDistributionMirrorSet, MirrorContent, MirrorFreshness)
19from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities18from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
20from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
21from lp.registry.interfaces.pocket import PackagePublishingPocket19from lp.registry.interfaces.pocket import PackagePublishingPocket
22from lp.registry.interfaces.distribution import IDistributionSet20from lp.registry.interfaces.distribution import IDistributionSet
23from lp.services.mail import stub21from lp.services.mail import stub
22from lp.testing.factory import LaunchpadObjectFactory
2423
25from canonical.testing import LaunchpadFunctionalLayer24from canonical.testing import LaunchpadFunctionalLayer
2625
27
28class TestDistributionMirror(unittest.TestCase):26class TestDistributionMirror(unittest.TestCase):
29 layer = LaunchpadFunctionalLayer27 layer = LaunchpadFunctionalLayer
3028
31 def setUp(self):29 def setUp(self):
32 login('test@canonical.com')30 login('test@canonical.com')
31 self.factory = LaunchpadObjectFactory()
33 mirrorset = getUtility(IDistributionMirrorSet)32 mirrorset = getUtility(IDistributionMirrorSet)
34 self.cdimage_mirror = getUtility(IDistributionMirrorSet).getByName(33 self.cdimage_mirror = getUtility(IDistributionMirrorSet).getByName(
35 'releases-mirror')34 'releases-mirror')
@@ -132,15 +131,6 @@
132 self.archive_mirror.getOverallFreshness(),131 self.archive_mirror.getOverallFreshness(),
133 MirrorFreshness.TWODAYSBEHIND)132 MirrorFreshness.TWODAYSBEHIND)
134133
135 def _create_probe_record(self, mirror):
136 log_file = StringIO()
137 log_file.write("Fake probe, nothing useful here.")
138 log_file.seek(0)
139 library_alias = getUtility(ILibraryFileAliasSet).create(
140 name='foo', size=len(log_file.getvalue()),
141 file=log_file, contentType='text/plain')
142 proberecord = mirror.newProbeRecord(library_alias)
143
144 def test_disabling_mirror_and_notifying_owner(self):134 def test_disabling_mirror_and_notifying_owner(self):
145 login('karl@canonical.com')135 login('karl@canonical.com')
146136
@@ -148,7 +138,7 @@
148 # If a mirror has been probed only once, the owner will always be138 # If a mirror has been probed only once, the owner will always be
149 # notified when it's disabled --it doesn't matter whether it was139 # notified when it's disabled --it doesn't matter whether it was
150 # previously enabled or disabled.140 # previously enabled or disabled.
151 self._create_probe_record(mirror)141 self.factory.makeMirrorProbeRecord(mirror)
152 self.failUnless(mirror.enabled)142 self.failUnless(mirror.enabled)
153 log = 'Got a 404 on http://foo/baz'143 log = 'Got a 404 on http://foo/baz'
154 mirror.disable(notify_owner=True, log=log)144 mirror.disable(notify_owner=True, log=log)
@@ -166,7 +156,7 @@
166156
167 # For mirrors that have been probed more than once, we'll only notify157 # For mirrors that have been probed more than once, we'll only notify
168 # the owner if the mirror was previously enabled.158 # the owner if the mirror was previously enabled.
169 self._create_probe_record(mirror)159 self.factory.makeMirrorProbeRecord(mirror)
170 mirror.enabled = True160 mirror.enabled = True
171 mirror.disable(notify_owner=True, log=log)161 mirror.disable(notify_owner=True, log=log)
172 # A notification was sent to the owner and other to the mirror admins.162 # A notification was sent to the owner and other to the mirror admins.
173163
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-03-25 02:21:15 +0000
+++ lib/lp/testing/factory.py 2010-03-31 15:03:35 +0000
@@ -1981,8 +1981,22 @@
1981 team_list = self.makeMailingList(team, owner)1981 team_list = self.makeMailingList(team, owner)
1982 return team, team_list1982 return team, team_list
19831983
1984 def makeMirrorProbeRecord(self, mirror):
1985 """Create a probe record for a mirror of a distribution."""
1986 log_file = StringIO()
1987 log_file.write("Fake probe, nothing useful here.")
1988 log_file.seek(0)
1989
1990 library_alias = getUtility(ILibraryFileAliasSet).create(
1991 name='foo', size=len(log_file.getvalue()),
1992 file=log_file, contentType='text/plain')
1993
1994 proberecord = mirror.newProbeRecord(library_alias)
1995 return proberecord
1996
1984 def makeMirror(self, distribution, displayname, country=None,1997 def makeMirror(self, distribution, displayname, country=None,
1985 http_url=None, ftp_url=None, rsync_url=None):1998 http_url=None, ftp_url=None, rsync_url=None,
1999 official_candidate=False):
1986 """Create a mirror for the distribution."""2000 """Create a mirror for the distribution."""
1987 # If no URL is specified create an HTTP URL.2001 # If no URL is specified create an HTTP URL.
1988 if http_url is None and ftp_url is None and rsync_url is None:2002 if http_url is None and ftp_url is None and rsync_url is None:
@@ -2001,7 +2015,7 @@
2001 http_base_url=http_url,2015 http_base_url=http_url,
2002 ftp_base_url=ftp_url,2016 ftp_base_url=ftp_url,
2003 rsync_base_url=rsync_url,2017 rsync_base_url=rsync_url,
2004 official_candidate=False)2018 official_candidate=official_candidate)
2005 return mirror2019 return mirror
20062020
2007 def makeUniqueRFC822MsgId(self):2021 def makeUniqueRFC822MsgId(self):