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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
XXX Julian 2010-08-03 bug=613096
Most of this doctest is really a unit test in disguise. It should get
re-written and unit tests moved to buildmaster/tests/test_builder.py
=============
Builder Class
=============
The Builder class represents a slave machine in the build farm. These
slaves are used to execute untrusted code -- for example when building
packages.
There are several builders in the sample data. Let's examine the first.
>>> from lp.buildmaster.model.builder import Builder
>>> builder = Builder.get(1)
As expected, it implements IBuilder.
>>> from canonical.launchpad.webapp.testing import verifyObject
>>> print builder.name
bob
>>> print builder.builderok
True
>>> print builder.failnotes
None
Builders can take on different behaviors depending on the type of build
they are currently processing. Each builder provides an attribute
(current_build_behavior) to which all the build-type specific behavior
for the current build is delegated. In the sample data, bob's current
behavior is dealing with binary packages.
>>> from zope.security.proxy import isinstance
>>> from lp.soyuz.model.binarypackagebuildbehavior import (
... BinaryPackageBuildBehavior)
>>> isinstance(
... builder.current_build_behavior, BinaryPackageBuildBehavior)
True
BuilderSet
==========
Builders and groups thereof are managed through a utility, IBuilderSet.
>>> from zope.component import getUtility
>>> from lp.buildmaster.interfaces.builder import IBuilderSet
>>> builderset = getUtility(IBuilderSet)
>>> verifyObject(IBuilderSet, builderset)
True
Iterating over a BuilderSet yields all registered builders.
>>> for b in builderset:
... print b.name
bob
frog
count() return the number of builders registered:
>>> builderset.count()
2
Builders can be retrieved by name.
>>> print builderset['bob'].name
bob
>>> print builderset['bad']
None
And also by ID.
>>> print builderset.get(2).name
frog
>>> print builderset.get(100).name
Traceback (most recent call last):
...
SQLObjectNotFound: Object not found
The 'new' method will create a new builder in the database.
>>> bnew = builderset.new(1, 'http://dummy.com:8221/', 'dummy',
... 'Dummy Title', 'eh ?', 1)
>>> bnew.name
u'dummy'
'getBuilders' returns builders with the 'active' flag set, ordered by
virtualization status, architecture, then name.
>>> for b in builderset.getBuilders():
... print b.name
bob
dummy
frog
>>> login('foo.bar@canonical.com')
>>> bnew.active = False
>>> login(ANONYMOUS)
>>> for b in builderset.getBuilders():
... print b.name
bob
frog
'getBuildQueueSizes' returns the number of pending builds for each
Processor/virtualization.
>>> queue_sizes = builderset.getBuildQueueSizes()
>>> queue_sizes['nonvirt']['386']
(1L, datetime.timedelta(0, 60))
There are no 'amd64' build queue entries.
>>> queue_sizes['nonvirt'].keys()
[u'386']
The virtualized build queue for 386 is also empty.
>>> queue_sizes['virt'].keys()
[]
The queue size is not affect by builds target to disabled
archives. Builds for disabled archive are not dispatched as well, this
is an effective manner to hold activity in a specific archive.
We will temporarily disable the ubuntu primary archive.
>>> login('foo.bar@canonical.com')
>>> from lp.registry.interfaces.distribution import IDistributionSet
>>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
>>> ubuntu.main_archive.disable()
>>> import transaction
>>> transaction.commit()
>>> login(ANONYMOUS)
That done, the non-virtualized queue for i386 becomes empty.
>>> queue_sizes = builderset.getBuildQueueSizes()
>>> queue_sizes['nonvirt'].keys()
[]
Let's re-enable the ubuntu primary archive.
>>> login('foo.bar@canonical.com')
>>> ubuntu.main_archive.enable()
>>> transaction.commit()
>>> login(ANONYMOUS)
The build for the ubuntu primary archive shows up again.
>>> queue_sizes = builderset.getBuildQueueSizes()
>>> queue_sizes['nonvirt']['386']
(1L, datetime.timedelta(0, 60))
All job types are included. If we create a recipe build job, it will
show up in the calculated queue size.
>>> recipe_bq = factory.makeSourcePackageRecipeBuildJob()
>>> # XXX wgrant 20100625 bug=598397: The factory erroneously creates
>>> # architecture-independent jobs.
>>> print recipe_bq.processor
None
>>> from lp.soyuz.interfaces.processor import IProcessorFamilySet
>>> i386_family = getUtility(IProcessorFamilySet).getByName('x86')
>>> recipe_bq.processor = i386_family.processors[0]
>>> recipe_bq.virtualized = True
>>> transaction.commit()
>>> queue_sizes = builderset.getBuildQueueSizes()
>>> print queue_sizes['virt']['386']
(1L, datetime.timedelta(0, 64))
Any BuildQueues with a null `virtualized` property are considered virtual
by default.
>>> recipe_bq = factory.makeSourcePackageRecipeBuildJob()
>>> recipe_bq.virtualized = None
>>> recipe_bq.processor = i386_family.processors[0]
>>> transaction.commit()
>>> queue_sizes = builderset.getBuildQueueSizes()
The virtual queue size has increased accordingly:
>>> print queue_sizes['virt']['386']
(2L, datetime.timedelta(0, 128))
|