~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
Retrieving upload information
=============================

We can retrive the original upload information in the form of a
`PackageUpload` object for all `SourcePackageRelease` or `Build`
objects uploaded to system.

Both `SourcePackageRelease` and `Build` implement the following
properties:

 * 'package_upload': the `PackageUpload`
 * 'upload_changesfile': the `PackageUpload.changesfile`, an
      `LibraryFileAlias`.

Those fields are always not-null for sources and builds that were
'uploaded' to the system.

The only exception to this rule are packages 'imported' into the system
from other repositories. They do not have any relevant upload
information to be stored.


Auditing the sampledata
=======================

For the sake of consistency, we can implicitly probe the lookups
described above against all existing source publications and builds
in the sampladata.

    # Audit the source publication and builds of a given archive
    # and report missing uploads.
    >>> from lp.buildmaster.enums import BuildStatus
    >>> def check_upload_lookups(archive):
    ...     sources_missing_upload = []
    ...     sources = list(archive.getPublishedSources())
    ...     for source in sources:
    ...         source_release = source.sourcepackagerelease
    ...         package_upload = source_release.package_upload
    ...         changesfile = source_release.upload_changesfile
    ...         if package_upload is None or changesfile is None:
    ...            sources_missing_upload.append(source)
    ...     builds_missing_upload = []
    ...     builds = list(
    ...         archive.getBuildRecords(build_state=BuildStatus.FULLYBUILT))
    ...     for build in builds:
    ...         package_upload = build.package_upload
    ...         changesfile = build.upload_changesfile
    ...         if package_upload is None or changesfile is None:
    ...            builds_missing_upload.append(builds)
    ...     print '* %s' % archive.displayname
    ...     print '%d of %d sources and %d of %d builds missing uploads' % (
    ...        len(sources_missing_upload), len(sources),
    ...        len(builds_missing_upload), len(builds))

As we can see from the results below, most of our sampledata are
sources and builds directly imported into the system, not
uploaded. However it's a legitimate scenario that doesn't break the
assumptions done in the lookups.

    >>> from lp.registry.interfaces.distribution import (
    ...     IDistributionSet)
    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')

    >>> for archive in ubuntu.all_distro_archives:
    ...     check_upload_lookups(archive)
    * Primary Archive for Ubuntu Linux
    17 of 20 sources and 6 of 8 builds missing uploads
    * Partner Archive for Ubuntu Linux
    0 of 1 sources and 1 of 1 builds missing uploads
    * Ubuntu DEBUG archive
    0 of 0 sources and 0 of 0 builds missing uploads

    >>> for ppa in ubuntu.getAllPPAs():
    ...     check_upload_lookups(ppa)
    * PPA for Celso Providelo
    2 of 3 sources and 3 of 3 builds missing uploads
    * PPA for Mark Shuttleworth
    0 of 1 sources and 0 of 0 builds missing uploads
    * PPA for No Privileges Person
    0 of 0 sources and 0 of 0 builds missing uploads

    >>> ubuntutest = getUtility(IDistributionSet).getByName(
    ...     'ubuntutest')
    >>> for archive in ubuntutest.all_distro_archives:
    ...     check_upload_lookups(archive)
    * Primary Archive for Ubuntu Test
    1 of 2 sources and 0 of 0 builds missing uploads
    * Partner Archive for Ubuntu Test
    0 of 0 sources and 0 of 0 builds missing uploads


Upload lookups in action
========================

We will create a brand new source publication for the subsequent
tests.

    # Create a testing source and its binaries in
    # ubuntutest/breezy-autotest/i386.
    >>> from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
    >>> login('foo.bar@canonical.com')
    >>> test_publisher = SoyuzTestPublisher()
    >>> test_publisher.prepareBreezyAutotest()
    >>> source = test_publisher.getPubSource(
    ...     sourcename='testing', version='1.0')
    >>> binaries = test_publisher.getPubBinaries(
    ...     binaryname='testing-bin', pub_source=source)
    >>> [build] = source.getBuilds()
    >>> transaction.commit()
    >>> login(ANONYMOUS)

The `SourcePackageRelease` 'package_upload' and 'upload_changesfile'

    >>> original_source_upload = source.sourcepackagerelease.package_upload
    >>> print original_source_upload
    <PackageUpload ...>

    >>> source_changesfile = source.sourcepackagerelease.upload_changesfile
    >>> original_source_upload.changesfile == source_changesfile
    True

    >>> print source_changesfile.filename
    testing_1.0_source.changes

The `Build` 'package_upload' and 'upload_changesfile'

    >>> original_build_upload = build.package_upload
    >>> print original_build_upload
    <...PackageUpload ...>

    >>> build_changesfile = build.upload_changesfile
    >>> original_build_upload.changesfile == build_changesfile
    True

    >>> print build_changesfile.filename
    testing-bin_1.0_i386.changes

The `PackageUpload` lookups are not restricted to the status of the
upload, i.e., new, rejected, unapproved or accepted items are returned
as well.

    # Modify the `PackageUpload` records status in place.
    >>> login('foo.bar@canonical.com')
    >>> original_source_upload.setRejected()
    >>> original_build_upload.setNew()
    >>> transaction.commit()
    >>> login(ANONYMOUS)

    >>> original_source_upload == source.sourcepackagerelease.package_upload
    True

    >>> original_build_upload == build.package_upload
    True