Merge ~cjwatson/launchpad:rename-conjoined-bug-tasks into launchpad:master
- Git
- lp:~cjwatson/launchpad
- rename-conjoined-bug-tasks
- Merge into master
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 5d65b0763acbe446c92844a7ec3b2676366d3424 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:rename-conjoined-bug-tasks |
Merge into: | launchpad:master |
Diff against target: |
1323 lines (+238/-238) 26 files modified
lib/lp/bugs/browser/bugnomination.py (+1/-1) lib/lp/bugs/browser/bugtask.py (+14/-14) lib/lp/bugs/configure.zcml (+3/-3) lib/lp/bugs/doc/bug-set-status.txt (+4/-4) lib/lp/bugs/doc/bugtask-expiration.txt (+8/-8) lib/lp/bugs/doc/bugwatch.txt (+12/-12) lib/lp/bugs/interfaces/bug.py (+2/-2) lib/lp/bugs/interfaces/bugtask.py (+6/-6) lib/lp/bugs/model/bug.py (+6/-6) lib/lp/bugs/model/bugtask.py (+45/-45) lib/lp/bugs/model/bugtasksearch.py (+23/-23) lib/lp/bugs/model/bugwatch.py (+2/-2) lib/lp/bugs/model/tests/test_bugtask.py (+23/-24) lib/lp/bugs/model/tests/test_bugtasksearch.py (+1/-1) lib/lp/bugs/scripts/bugexpire.py (+2/-2) lib/lp/bugs/scripts/tests/test_bugimport.py (+1/-1) lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt (+5/-5) lib/lp/bugs/tests/bugtarget-questiontarget.txt (+1/-1) lib/lp/bugs/tests/test_bugsearch_conjoined.py (+41/-41) lib/lp/bugs/tests/test_bugwatch.py (+1/-1) lib/lp/registry/browser/__init__.py (+2/-2) lib/lp/registry/browser/milestone.py (+5/-5) lib/lp/registry/model/milestone.py (+2/-2) lib/lp/registry/model/person.py (+12/-11) lib/lp/registry/tests/test_milestonetag.py (+1/-1) lib/lp/registry/tests/test_person.py (+15/-15) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ioana Lasc (community) | Approve | ||
Review via email: mp+414348@code.launchpad.net |
Commit message
Rename conjoined master/slave bug tasks to primary/replica
Description of the change
Launchpad bugs have a peculiar feature called "conjoined tasks". For example, the tasks on a bug that's being primarily worked on in the jammy series of Ubuntu but whose fix then needs to be backported to focal and impish might look like this:
base-files (Ubuntu) Status tracked in Jammy
-> Focal Triaged Critical
-> Impish Triaged Critical
-> Jammy In Progress Critical
In this case, the task on base-files (Ubuntu) is currently referred to as a "conjoined slave", and the task on base-files (Ubuntu Jammy) is its corresponding "conjoined master". The metadata of the conjoined slave cannot be updated independently; instead, changes are automatically propagated from the conjoined master.
This terminology obviously doesn't fit with inclusive naming standards. Rename "conjoined master" to "conjoined primary" and "conjoined slave" to "conjoined replica", which I think also expresses the metadata replication relationship a little more clearly.
I also considered renaming "conjoined master" to "conjoined series-specific task" (or `conjoined_
Preview Diff
1 | diff --git a/lib/lp/bugs/browser/bugnomination.py b/lib/lp/bugs/browser/bugnomination.py |
2 | index 1c2319e..40dddbd 100644 |
3 | --- a/lib/lp/bugs/browser/bugnomination.py |
4 | +++ b/lib/lp/bugs/browser/bugnomination.py |
5 | @@ -143,7 +143,7 @@ class BugNominationTableRowView(LaunchpadView): |
6 | """Browser view class for rendering a nomination table row.""" |
7 | |
8 | # This method will be called to render the bug nomination. |
9 | - renderNonConjoinedSlave = LaunchpadView.__call__ |
10 | + renderNonConjoinedReplica = LaunchpadView.__call__ |
11 | |
12 | def getNominationPerson(self): |
13 | """Return the IPerson associated with this nomination. |
14 | diff --git a/lib/lp/bugs/browser/bugtask.py b/lib/lp/bugs/browser/bugtask.py |
15 | index f0197a2..1ae7e7c 100644 |
16 | --- a/lib/lp/bugs/browser/bugtask.py |
17 | +++ b/lib/lp/bugs/browser/bugtask.py |
18 | @@ -1937,17 +1937,17 @@ class BugTasksTableView(LaunchpadView): |
19 | )) |
20 | |
21 | def _getTableRowView(self, context, is_converted_to_question, |
22 | - is_conjoined_slave): |
23 | + is_conjoined_replica): |
24 | """Get the view for the context, and initialize it. |
25 | |
26 | - The view's is_conjoined_slave and is_converted_to_question |
27 | + The view's is_conjoined_replica and is_converted_to_question |
28 | attributes are set, as well as the edit view. |
29 | """ |
30 | view = getMultiAdapter( |
31 | (context, self.request), |
32 | name='+bugtasks-and-nominations-table-row') |
33 | view.is_converted_to_question = is_converted_to_question |
34 | - view.is_conjoined_slave = is_conjoined_slave |
35 | + view.is_conjoined_replica = is_conjoined_replica |
36 | |
37 | view.edit_view = getMultiAdapter( |
38 | (context, self.request), name='+edit-form') |
39 | @@ -1991,7 +1991,7 @@ class BugTasksTableView(LaunchpadView): |
40 | list(getUtility(IPersonSet).getPrecachedPersonsFromIDs( |
41 | ids, need_validity=True)) |
42 | |
43 | - # Build a cache we can pass on to getConjoinedMaster(), so that |
44 | + # Build a cache we can pass on to getConjoinedPrimary(), so that |
45 | # it doesn't have to iterate over all the bug tasks in each loop |
46 | # iteration. |
47 | bugtasks_by_package = bug.getBugTasksByPackageName(all_bugtasks) |
48 | @@ -2017,11 +2017,11 @@ class BugTasksTableView(LaunchpadView): |
49 | (parent, self.request), |
50 | name='+bugtasks-and-nominations-table-row')) |
51 | |
52 | - conjoined_master = bugtask.getConjoinedMaster( |
53 | + conjoined_primary = bugtask.getConjoinedPrimary( |
54 | all_bugtasks, bugtasks_by_package) |
55 | view = self._getTableRowView( |
56 | bugtask, is_converted_to_question, |
57 | - conjoined_master is not None) |
58 | + conjoined_primary is not None) |
59 | bugtask_and_nomination_views.append(view) |
60 | target = bugtask.product or bugtask.distribution |
61 | if not target: |
62 | @@ -2042,7 +2042,7 @@ class BugTaskTableRowView(LaunchpadView, BugTaskBugWatchMixin, |
63 | BugTaskPrivilegeMixin): |
64 | """Browser class for rendering a bugtask row on the bug page.""" |
65 | |
66 | - is_conjoined_slave = None |
67 | + is_conjoined_replica = None |
68 | is_converted_to_question = None |
69 | target_link_title = None |
70 | many_bugtasks = False |
71 | @@ -2074,7 +2074,7 @@ class BugTaskTableRowView(LaunchpadView, BugTaskBugWatchMixin, |
72 | # time. |
73 | expandable=(not self.many_bugtasks and self.canSeeTaskDetails()), |
74 | indent_task=ISeriesBugTarget.providedBy(self.context.target), |
75 | - is_conjoined_slave=self.is_conjoined_slave, |
76 | + is_conjoined_replica=self.is_conjoined_replica, |
77 | task_link=task_link, |
78 | edit_link=edit_link, |
79 | can_edit=can_edit, |
80 | @@ -2112,13 +2112,13 @@ class BugTaskTableRowView(LaunchpadView, BugTaskBugWatchMixin, |
81 | It is independent of whether they can *change* the status; you |
82 | need to expand the details to see any milestone set. |
83 | """ |
84 | - assert self.is_conjoined_slave is not None, ( |
85 | - 'is_conjoined_slave should be set before rendering the page.') |
86 | + assert self.is_conjoined_replica is not None, ( |
87 | + 'is_conjoined_replica should be set before rendering the page.') |
88 | assert self.is_converted_to_question is not None, ( |
89 | 'is_converted_to_question should be set before rendering the' |
90 | ' page.') |
91 | return (self.displayEditForm() and |
92 | - not self.is_conjoined_slave and |
93 | + not self.is_conjoined_replica and |
94 | self.context.bug.duplicateof is None and |
95 | not self.is_converted_to_question) |
96 | |
97 | @@ -2133,9 +2133,9 @@ class BugTaskTableRowView(LaunchpadView, BugTaskBugWatchMixin, |
98 | """Get the series to which this task is targeted.""" |
99 | return self._getSeriesTargetNameHelper(self.context) |
100 | |
101 | - def getConjoinedMasterName(self): |
102 | - """Get the conjoined master's name for displaying.""" |
103 | - return self._getSeriesTargetNameHelper(self.context.conjoined_master) |
104 | + def getConjoinedPrimaryName(self): |
105 | + """Get the conjoined primary's name for displaying.""" |
106 | + return self._getSeriesTargetNameHelper(self.context.conjoined_primary) |
107 | |
108 | @property |
109 | def bugtask_icon(self): |
110 | diff --git a/lib/lp/bugs/configure.zcml b/lib/lp/bugs/configure.zcml |
111 | index b2a54ac..5b46af7 100644 |
112 | --- a/lib/lp/bugs/configure.zcml |
113 | +++ b/lib/lp/bugs/configure.zcml |
114 | @@ -226,10 +226,10 @@ |
115 | getDelta |
116 | pillar |
117 | bugtask_branches |
118 | - conjoined_master |
119 | - conjoined_slave |
120 | + conjoined_primary |
121 | + conjoined_replica |
122 | subscribe |
123 | - getConjoinedMaster |
124 | + getConjoinedPrimary |
125 | findSimilarBugs |
126 | getContributorInfo"/> |
127 | <require |
128 | diff --git a/lib/lp/bugs/doc/bug-set-status.txt b/lib/lp/bugs/doc/bug-set-status.txt |
129 | index 4c4f033..f89dee0 100644 |
130 | --- a/lib/lp/bugs/doc/bug-set-status.txt |
131 | +++ b/lib/lp/bugs/doc/bug-set-status.txt |
132 | @@ -109,14 +109,14 @@ is edited. |
133 | >>> firefox_trunk_bugtask.status.name |
134 | 'INCOMPLETE' |
135 | |
136 | -If the target bugtask has a conjoined master bugtask, the conjoined |
137 | -master will be edited and returned. The conjoined slave is of course |
138 | +If the target bugtask has a conjoined primary bugtask, the conjoined |
139 | +primary will be edited and returned. The conjoined replica is of course |
140 | updated automatically. |
141 | |
142 | - >>> firefox_bugtask = firefox_trunk_bugtask.conjoined_slave |
143 | + >>> firefox_bugtask = firefox_trunk_bugtask.conjoined_replica |
144 | >>> print(firefox_bugtask.target.name) |
145 | firefox |
146 | - >>> firefox_bugtask.conjoined_master is not None |
147 | + >>> firefox_bugtask.conjoined_primary is not None |
148 | True |
149 | >>> firefox_bugtask.status.name |
150 | 'INCOMPLETE' |
151 | diff --git a/lib/lp/bugs/doc/bugtask-expiration.txt b/lib/lp/bugs/doc/bugtask-expiration.txt |
152 | index f34bb17..9478b1c 100644 |
153 | --- a/lib/lp/bugs/doc/bugtask-expiration.txt |
154 | +++ b/lib/lp/bugs/doc/bugtask-expiration.txt |
155 | @@ -91,7 +91,7 @@ that no bug tasks can be expired. |
156 | ... 'test@canonical.com') |
157 | |
158 | # A expirable bugtask. It will be expired because its conjoined |
159 | - # master can be expired. |
160 | + # primary can be expired. |
161 | >>> from lp.bugs.tests.bug import create_old_bug |
162 | >>> ubuntu_bugtask = create_old_bug('expirable_distro', 351, ubuntu) |
163 | >>> ubuntu_bugtask.bug.permits_expiration |
164 | @@ -100,10 +100,10 @@ that no bug tasks can be expired. |
165 | True |
166 | |
167 | # An expirable bugtask, a distroseries. The ubuntu bugtask is its |
168 | - # conjoined slave. |
169 | + # conjoined replica. |
170 | >>> hoary_bugtask = bugtaskset.createTask( |
171 | ... ubuntu_bugtask.bug, sample_person, ubuntu.currentseries) |
172 | - >>> ubuntu_bugtask.conjoined_master == hoary_bugtask |
173 | + >>> ubuntu_bugtask.conjoined_primary == hoary_bugtask |
174 | True |
175 | >>> ubuntu_bugtask.bug.permits_expiration |
176 | True |
177 | @@ -318,13 +318,13 @@ will be expirable. |
178 | ubuntu True 351 Incomplete False False False False |
179 | hoary True 351 Incomplete False False False False |
180 | |
181 | -The ubuntu bugtask is never returned; it is a conjoined slave to the |
182 | -hoary bugtask. Slave bugtasks cannot be directly expired, so they are |
183 | +The ubuntu bugtask is never returned; it is a conjoined replica to the |
184 | +hoary bugtask. Replica bugtasks cannot be directly expired, so they are |
185 | not returned by findExpirableBugTasks(). |
186 | |
187 | >>> ubuntu_bugtask.status.title |
188 | 'Incomplete' |
189 | - >>> ubuntu_bugtask.conjoined_master == hoary_bugtask |
190 | + >>> ubuntu_bugtask.conjoined_primary == hoary_bugtask |
191 | True |
192 | |
193 | Reducing the age to 60 days old, both hoary and jokosher bugtasks |
194 | @@ -531,7 +531,7 @@ After the script has run |
195 | |
196 | There are three Expired bugtasks. Jokosher, hoary and ubuntu were |
197 | expired by the expiration process. Although ubuntu was never returned |
198 | -by findExpirableBugTasks(), it was expired because its master (hoary) |
199 | +by findExpirableBugTasks(), it was expired because its primary (hoary) |
200 | was expired. The remaining bugtasks are unchanged. |
201 | |
202 | >>> summarize_bugtasks(bugtasks) |
203 | @@ -551,7 +551,7 @@ was expired. The remaining bugtasks are unchanged. |
204 | |
205 | The message explaining the reason for the expiration was posted by the |
206 | Launchpad Janitor celebrity. Only one message was created for when the |
207 | -master and slave bugtasks were expired. |
208 | +primary and replica bugtasks were expired. |
209 | |
210 | >>> starting_bug_messages_count |
211 | 2 |
212 | diff --git a/lib/lp/bugs/doc/bugwatch.txt b/lib/lp/bugs/doc/bugwatch.txt |
213 | index 17e6f6a..4070e12 100644 |
214 | --- a/lib/lp/bugs/doc/bugwatch.txt |
215 | +++ b/lib/lp/bugs/doc/bugwatch.txt |
216 | @@ -417,15 +417,15 @@ The Bug Watch Updater can transition a bug to any status or importance: |
217 | ... debian_bugwatch.updateImportance(u'nothing', importance) |
218 | |
219 | |
220 | -BugWatches against BugTasks with conjoined masters |
221 | --------------------------------------------------- |
222 | +BugWatches against BugTasks with conjoined primaries |
223 | +---------------------------------------------------- |
224 | |
225 | -A conjoined bugtask involves a master and slave in in a conjoined |
226 | -relationship. The slave is a generic product or distribution task; the |
227 | -master is a series-specific task. If a BugWatch is linked to a BugTask |
228 | -with a conjoined master, that bug task will not be updated when the |
229 | +A conjoined bugtask involves a primary and replica in a conjoined |
230 | +relationship. The replica is a generic product or distribution task; the |
231 | +primary is a series-specific task. If a BugWatch is linked to a BugTask |
232 | +with a conjoined primary, that bug task will not be updated when the |
233 | BugWatch's status or importance are updated. We can demonstrate this by |
234 | -creating a bug task with a conjoined master. |
235 | +creating a bug task with a conjoined primary. |
236 | |
237 | >>> from zope.component import getUtility |
238 | >>> from lp.services.database.sqlbase import flush_database_updates |
239 | @@ -441,15 +441,15 @@ creating a bug task with a conjoined master. |
240 | >>> firefox = ubuntu.getSourcePackage('mozilla-firefox') |
241 | >>> bug = firefox.createBug(CreateBugParams( |
242 | ... owner=sample_person, title='Yet another test bug', |
243 | - ... comment="A sample bug for conjoined master tests.")) |
244 | + ... comment="A sample bug for conjoined primary tests.")) |
245 | |
246 | >>> targeted_bugtask = getUtility(IBugTaskSet).createTask( |
247 | ... bug, sample_person, firefox.development_version) |
248 | |
249 | - >>> targeted_bugtask.conjoined_master is None |
250 | + >>> targeted_bugtask.conjoined_primary is None |
251 | True |
252 | |
253 | - >>> targeted_bugtask.conjoined_slave == bug.bugtasks[0] |
254 | + >>> targeted_bugtask.conjoined_replica == bug.bugtasks[0] |
255 | True |
256 | |
257 | We use ensureBugTracker() to populate in the parameters that we don't |
258 | @@ -467,8 +467,8 @@ specifiy, such as the bug tracker's name. |
259 | Now that we have our conjoined bug tasks we can use a test |
260 | implementation of the Roundup ExternalBugTracker to try and update |
261 | them. In fact, updating the bug watch will do nothing to the bug task to |
262 | -which it is linked since that bug task is a conjoined slave. Conjoined |
263 | -slaves must be updated through their conjoined master. |
264 | +which it is linked since that bug task is a conjoined replica. Conjoined |
265 | +replicas must be updated through their conjoined primary. |
266 | |
267 | >>> bug.bugtasks[0].status.title |
268 | 'New' |
269 | diff --git a/lib/lp/bugs/interfaces/bug.py b/lib/lp/bugs/interfaces/bug.py |
270 | index 057b9eb..db94b63 100644 |
271 | --- a/lib/lp/bugs/interfaces/bug.py |
272 | +++ b/lib/lp/bugs/interfaces/bug.py |
273 | @@ -578,7 +578,7 @@ class IBugView(Interface): |
274 | """Return a mapping from `ISourcePackageName` to its bug tasks. |
275 | |
276 | This mapping is suitable to pass as the bugtasks_by_package |
277 | - cache to getConjoinedMaster(). |
278 | + cache to getConjoinedPrimary(). |
279 | |
280 | The mapping is from a `ISourcePackageName` to all the bug tasks |
281 | that are targeted to such a package name, no matter which |
282 | @@ -750,7 +750,7 @@ class IBugAppend(Interface): |
283 | to questions. This is also true for bugs that are being developed. |
284 | |
285 | The `IQuestionTarget` is provided by the `IBugTask` that is not |
286 | - Invalid and is not a conjoined slave. Only one question can be |
287 | + Invalid and is not a conjoined replica. Only one question can be |
288 | made from a bug. |
289 | |
290 | An AssertionError is raised if the bug has zero or many BugTasks |
291 | diff --git a/lib/lp/bugs/interfaces/bugtask.py b/lib/lp/bugs/interfaces/bugtask.py |
292 | index 141034f..5d22a40 100644 |
293 | --- a/lib/lp/bugs/interfaces/bugtask.py |
294 | +++ b/lib/lp/bugs/interfaces/bugtask.py |
295 | @@ -575,9 +575,9 @@ class IBugTask(IHasBug, IBugTaskDelete): |
296 | title=_("A list of IPersons subscribed to the bug, whether directly " |
297 | "or indirectly."), readonly=True) |
298 | |
299 | - conjoined_master = Attribute( |
300 | + conjoined_primary = Attribute( |
301 | "The series-specific bugtask in a conjoined relationship") |
302 | - conjoined_slave = Attribute( |
303 | + conjoined_replica = Attribute( |
304 | "The generic bugtask in a conjoined relationship") |
305 | |
306 | is_complete = exported( |
307 | @@ -614,18 +614,18 @@ class IBugTask(IHasBug, IBugTaskDelete): |
308 | calling context does not have access to the person or pillar names. |
309 | """ |
310 | |
311 | - def getConjoinedMaster(bugtasks, bugtasks_by_package=None): |
312 | - """Return the conjoined master in the given bugtasks, if any. |
313 | + def getConjoinedPrimary(bugtasks, bugtasks_by_package=None): |
314 | + """Return the conjoined primary in the given bugtasks, if any. |
315 | |
316 | :param bugtasks: The bugtasks to be considered when looking for |
317 | - the conjoined master. |
318 | + the conjoined primary. |
319 | :param bugtasks_by_package: A cache, mapping a |
320 | `ISourcePackageName` to a list of bug tasks targeted to such |
321 | a package name. Both distribution and distro series tasks |
322 | should be included in this list. |
323 | |
324 | This method exists mainly to allow calculating the conjoined |
325 | - master from a cached list of bug tasks, reducing the number of |
326 | + primary from a cached list of bug tasks, reducing the number of |
327 | db queries needed. |
328 | """ |
329 | |
330 | diff --git a/lib/lp/bugs/model/bug.py b/lib/lp/bugs/model/bug.py |
331 | index 0a3ff8c..f7c588c 100644 |
332 | --- a/lib/lp/bugs/model/bug.py |
333 | +++ b/lib/lp/bugs/model/bug.py |
334 | @@ -1484,18 +1484,18 @@ class Bug(SQLBase, InformationTypeMixin): |
335 | |
336 | The bugtask is selected by these rules: |
337 | 1. It's status is not Invalid. |
338 | - 2. It is not a conjoined slave. |
339 | + 2. It is not a conjoined replica. |
340 | Only one bugtask must meet both conditions to be return. When |
341 | zero or many bugtasks match, None is returned. |
342 | """ |
343 | - # We may want to removed the bugtask.conjoined_master check |
344 | + # We may want to removed the bugtask.conjoined_primary check |
345 | # below. It is used to simplify the task of converting |
346 | - # conjoined bugtasks to question--since slaves cannot be |
347 | + # conjoined bugtasks to question--since replicas cannot be |
348 | # directly updated anyway. |
349 | non_invalid_bugtasks = [ |
350 | bugtask for bugtask in self.bugtasks |
351 | if (bugtask.status != BugTaskStatus.INVALID |
352 | - and bugtask.conjoined_master is None)] |
353 | + and bugtask.conjoined_primary is None)] |
354 | if len(non_invalid_bugtasks) != 1: |
355 | return None |
356 | [valid_bugtask] = non_invalid_bugtasks |
357 | @@ -1755,8 +1755,8 @@ class Bug(SQLBase, InformationTypeMixin): |
358 | if bugtask is None: |
359 | return None |
360 | |
361 | - if bugtask.conjoined_master is not None: |
362 | - bugtask = bugtask.conjoined_master |
363 | + if bugtask.conjoined_primary is not None: |
364 | + bugtask = bugtask.conjoined_primary |
365 | |
366 | if bugtask.status == status: |
367 | return None |
368 | diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py |
369 | index 2cd2b35..7b31d6d 100644 |
370 | --- a/lib/lp/bugs/model/bugtask.py |
371 | +++ b/lib/lp/bugs/model/bugtask.py |
372 | @@ -281,25 +281,25 @@ class PassthroughValue: |
373 | |
374 | @block_implicit_flushes |
375 | def validate_conjoined_attribute(self, attr, value): |
376 | - # If this is a conjoined slave then call setattr on the master. |
377 | - # Effectively this means that making a change to the slave will |
378 | - # actually make the change to the master (which will then be passed |
379 | - # down to the slave, of course). This helps to prevent OOPSes when |
380 | - # people try to update the conjoined slave via the API. |
381 | + # If this is a conjoined replica then call setattr on the primary. |
382 | + # Effectively this means that making a change to the replica will |
383 | + # actually make the change to the primary (which will then be passed |
384 | + # down to the replica, of course). This helps to prevent OOPSes when |
385 | + # people try to update the conjoined replica via the API. |
386 | |
387 | # If the value has been wrapped in a _PassthroughValue instance, |
388 | - # then we are being updated by our conjoined master: pass the |
389 | + # then we are being updated by our conjoined primary: pass the |
390 | # value through without any checking. |
391 | if isinstance(value, PassthroughValue): |
392 | return value.value |
393 | |
394 | - conjoined_master = self.conjoined_master |
395 | - if conjoined_master is not None: |
396 | - setattr(conjoined_master, attr, value) |
397 | + conjoined_primary = self.conjoined_primary |
398 | + if conjoined_primary is not None: |
399 | + setattr(conjoined_primary, attr, value) |
400 | return value |
401 | |
402 | - # If there is a conjoined slave, update that. |
403 | - conjoined_bugtask = self.conjoined_slave |
404 | + # If there is a conjoined replica, update that. |
405 | + conjoined_bugtask = self.conjoined_replica |
406 | if conjoined_bugtask: |
407 | setattr(conjoined_bugtask, attr, PassthroughValue(value)) |
408 | |
409 | @@ -727,26 +727,26 @@ class BugTask(StormBase): |
410 | result['pillar_name'] = self.pillar.displayname |
411 | return result |
412 | |
413 | - def getConjoinedMaster(self, bugtasks, bugtasks_by_package=None): |
414 | + def getConjoinedPrimary(self, bugtasks, bugtasks_by_package=None): |
415 | """See `IBugTask`.""" |
416 | - conjoined_master = None |
417 | + conjoined_primary = None |
418 | if self.distribution: |
419 | if bugtasks_by_package is None: |
420 | bugtasks_by_package = ( |
421 | self.bug.getBugTasksByPackageName(bugtasks)) |
422 | bugtasks = bugtasks_by_package[self.sourcepackagename] |
423 | - possible_masters = [ |
424 | + possible_primaries = [ |
425 | bugtask for bugtask in bugtasks |
426 | if (bugtask.distroseries is not None and |
427 | bugtask.sourcepackagename == self.sourcepackagename)] |
428 | # Return early, so that we don't have to get currentseries, |
429 | # which is expensive. |
430 | - if len(possible_masters) == 0: |
431 | + if len(possible_primaries) == 0: |
432 | return None |
433 | current_series = self.distribution.currentseries |
434 | - for bugtask in possible_masters: |
435 | + for bugtask in possible_primaries: |
436 | if bugtask.distroseries == current_series: |
437 | - conjoined_master = bugtask |
438 | + conjoined_primary = bugtask |
439 | break |
440 | elif self.product: |
441 | assert self.product.development_focusID is not None, ( |
442 | @@ -754,26 +754,26 @@ class BugTask(StormBase): |
443 | devel_focusID = self.product.development_focusID |
444 | for bugtask in bugtasks: |
445 | if bugtask.productseries_id == devel_focusID: |
446 | - conjoined_master = bugtask |
447 | + conjoined_primary = bugtask |
448 | break |
449 | |
450 | - if (conjoined_master is not None and |
451 | - conjoined_master.status in self._NON_CONJOINED_STATUSES): |
452 | - conjoined_master = None |
453 | - return conjoined_master |
454 | + if (conjoined_primary is not None and |
455 | + conjoined_primary.status in self._NON_CONJOINED_STATUSES): |
456 | + conjoined_primary = None |
457 | + return conjoined_primary |
458 | |
459 | def _get_shortlisted_bugtasks(self): |
460 | return shortlist(self.bug.bugtasks, longest_expected=200) |
461 | |
462 | @property |
463 | - def conjoined_master(self): |
464 | + def conjoined_primary(self): |
465 | """See `IBugTask`.""" |
466 | - return self.getConjoinedMaster(self._get_shortlisted_bugtasks()) |
467 | + return self.getConjoinedPrimary(self._get_shortlisted_bugtasks()) |
468 | |
469 | @property |
470 | - def conjoined_slave(self): |
471 | + def conjoined_replica(self): |
472 | """See `IBugTask`.""" |
473 | - conjoined_slave = None |
474 | + conjoined_replica = None |
475 | if self.distroseries: |
476 | distribution = self.distroseries.distribution |
477 | if self.distroseries != distribution.currentseries: |
478 | @@ -782,7 +782,7 @@ class BugTask(StormBase): |
479 | for bugtask in self._get_shortlisted_bugtasks(): |
480 | if (bugtask.distribution == distribution and |
481 | bugtask.sourcepackagename == self.sourcepackagename): |
482 | - conjoined_slave = bugtask |
483 | + conjoined_replica = bugtask |
484 | break |
485 | elif self.productseries: |
486 | product = self.productseries.product |
487 | @@ -791,29 +791,29 @@ class BugTask(StormBase): |
488 | return None |
489 | for bugtask in self._get_shortlisted_bugtasks(): |
490 | if bugtask.product == product: |
491 | - conjoined_slave = bugtask |
492 | + conjoined_replica = bugtask |
493 | break |
494 | |
495 | - if (conjoined_slave is not None and |
496 | + if (conjoined_replica is not None and |
497 | self.status in self._NON_CONJOINED_STATUSES): |
498 | - conjoined_slave = None |
499 | - return conjoined_slave |
500 | + conjoined_replica = None |
501 | + return conjoined_replica |
502 | |
503 | - def _syncFromConjoinedSlave(self): |
504 | - """Ensure the conjoined master is synched from its slave. |
505 | + def _syncFromConjoinedReplica(self): |
506 | + """Ensure the conjoined primary is synched from its replica. |
507 | |
508 | This method should be used only directly after when the |
509 | - conjoined master has been created after the slave, to ensure |
510 | + conjoined primary has been created after the replica, to ensure |
511 | that they are in sync from the beginning. |
512 | """ |
513 | - conjoined_slave = self.conjoined_slave |
514 | + conjoined_replica = self.conjoined_replica |
515 | |
516 | for synched_attr in self._CONJOINED_ATTRIBUTES: |
517 | - slave_attr_value = getattr(conjoined_slave, synched_attr) |
518 | + replica_attr_value = getattr(conjoined_replica, synched_attr) |
519 | # Bypass our checks that prevent setting attributes on |
520 | - # conjoined masters by calling the underlying sqlobject |
521 | + # conjoined primaries by calling the underlying sqlobject |
522 | # setter methods directly. |
523 | - setattr(self, synched_attr, PassthroughValue(slave_attr_value)) |
524 | + setattr(self, synched_attr, PassthroughValue(replica_attr_value)) |
525 | |
526 | def transitionToMilestone(self, new_milestone, user): |
527 | """See `IBugTask`.""" |
528 | @@ -1643,8 +1643,8 @@ class BugTaskSet: |
529 | del get_property_cache(bug).bugtasks |
530 | for bugtask in tasks: |
531 | bugtask.updateTargetNameCache() |
532 | - if bugtask.conjoined_slave: |
533 | - bugtask._syncFromConjoinedSlave() |
534 | + if bugtask.conjoined_replica: |
535 | + bugtask._syncFromConjoinedReplica() |
536 | else: |
537 | # Set date_* properties, if we're not conjoined. |
538 | bugtask._setStatusDateProperties( |
539 | @@ -1739,11 +1739,11 @@ class BugTaskSet: |
540 | Bugtasks cannot transition to Invalid automatically unless they meet |
541 | all the rules stated above. |
542 | |
543 | - This implementation returns the master of the master-slave conjoined |
544 | - pairs of bugtasks. Slave conjoined bugtasks are not included in the |
545 | - list because they can only be expired by calling the master bugtask's |
546 | - transitionToStatus() method. See 'Conjoined Bug Tasks' in |
547 | - c.l.doc/bugtasks.txt. |
548 | + This implementation returns the primary of the primary-replica |
549 | + conjoined pairs of bugtasks. Replica conjoined bugtasks are not |
550 | + included in the list because they can only be expired by calling the |
551 | + primary bugtask's transitionToStatus() method. See |
552 | + lp.bugs.model.tests.test_bugtask.TestConjoinedBugTasks. |
553 | |
554 | Only bugtasks the specified user has permission to view are |
555 | returned. The Janitor celebrity has permission to view all bugs. |
556 | diff --git a/lib/lp/bugs/model/bugtasksearch.py b/lib/lp/bugs/model/bugtasksearch.py |
557 | index 1bf2eed..03b306f 100644 |
558 | --- a/lib/lp/bugs/model/bugtasksearch.py |
559 | +++ b/lib/lp/bugs/model/bugtasksearch.py |
560 | @@ -931,38 +931,38 @@ def _build_status_clause(col, status): |
561 | |
562 | |
563 | def _build_exclude_conjoined_clause(milestone): |
564 | - """Exclude bugtasks with a conjoined master. |
565 | + """Exclude bugtasks with a conjoined primary. |
566 | |
567 | This search option only makes sense when searching for bugtasks |
568 | for a milestone. Only bugtasks for a project or a distribution |
569 | - can have a conjoined master bugtask, which is a bugtask on the |
570 | + can have a conjoined primary bugtask, which is a bugtask on the |
571 | project's development focus series or the distribution's |
572 | currentseries. The project bugtask or the distribution bugtask |
573 | - will always have the same milestone set as its conjoined master |
574 | + will always have the same milestone set as its conjoined primary |
575 | bugtask, if it exists on the bug. Therefore, this prevents a lot |
576 | of bugs having two bugtasks listed in the results. However, it |
577 | is ok if a bug has multiple bugtasks in the results as long as |
578 | those other bugtasks are on other series. |
579 | """ |
580 | # XXX: EdwinGrubbs 2010-12-15 bug=682989 |
581 | - # (ConjoinedMaster.bug == X) produces the wrong sql, but |
582 | - # (ConjoinedMaster.bugID == X) works right. This bug applies to |
583 | + # (ConjoinedPrimary.bug == X) produces the wrong sql, but |
584 | + # (ConjoinedPrimary.bugID == X) works right. This bug applies to |
585 | # all foreign keys on the ClassAlias. |
586 | |
587 | - # Perform a LEFT JOIN to the conjoined master bugtask. If the |
588 | - # conjoined master is not null, it gets filtered out. |
589 | - ConjoinedMaster = ClassAlias(BugTask, 'ConjoinedMaster') |
590 | - extra_clauses = [ConjoinedMaster.id == None] |
591 | + # Perform a LEFT JOIN to the conjoined primary bugtask. If the |
592 | + # conjoined primary is not null, it gets filtered out. |
593 | + ConjoinedPrimary = ClassAlias(BugTask, 'ConjoinedPrimary') |
594 | + extra_clauses = [ConjoinedPrimary.id == None] |
595 | if milestone.distribution is not None: |
596 | current_series = milestone.distribution.currentseries |
597 | join = LeftJoin( |
598 | - ConjoinedMaster, |
599 | - And(ConjoinedMaster.bug_id == BugTaskFlat.bug_id, |
600 | + ConjoinedPrimary, |
601 | + And(ConjoinedPrimary.bug_id == BugTaskFlat.bug_id, |
602 | BugTaskFlat.distribution_id == milestone.distribution.id, |
603 | - ConjoinedMaster.distroseries_id == current_series.id, |
604 | - Not(ConjoinedMaster._status.is_in( |
605 | + ConjoinedPrimary.distroseries_id == current_series.id, |
606 | + Not(ConjoinedPrimary._status.is_in( |
607 | BugTask._NON_CONJOINED_STATUSES)))) |
608 | - join_tables = [(ConjoinedMaster, join)] |
609 | + join_tables = [(ConjoinedPrimary, join)] |
610 | else: |
611 | if IProjectGroupMilestone.providedBy(milestone): |
612 | # Since an IProjectGroupMilestone could have bugs with |
613 | @@ -973,11 +973,11 @@ def _build_exclude_conjoined_clause(milestone): |
614 | Join(Milestone, BugTaskFlat.milestone_id == Milestone.id), |
615 | LeftJoin(Product, BugTaskFlat.product_id == Product.id), |
616 | LeftJoin( |
617 | - ConjoinedMaster, |
618 | - And(ConjoinedMaster.bug_id == BugTaskFlat.bug_id, |
619 | - ConjoinedMaster.productseries_id |
620 | + ConjoinedPrimary, |
621 | + And(ConjoinedPrimary.bug_id == BugTaskFlat.bug_id, |
622 | + ConjoinedPrimary.productseries_id |
623 | == Product.development_focusID, |
624 | - Not(ConjoinedMaster._status.is_in( |
625 | + Not(ConjoinedPrimary._status.is_in( |
626 | BugTask._NON_CONJOINED_STATUSES)))), |
627 | ] |
628 | # join.right is the table name. |
629 | @@ -986,13 +986,13 @@ def _build_exclude_conjoined_clause(milestone): |
630 | dev_focus_id = ( |
631 | milestone.product.development_focusID) |
632 | join = LeftJoin( |
633 | - ConjoinedMaster, |
634 | - And(ConjoinedMaster.bug_id == BugTaskFlat.bug_id, |
635 | + ConjoinedPrimary, |
636 | + And(ConjoinedPrimary.bug_id == BugTaskFlat.bug_id, |
637 | BugTaskFlat.product_id == milestone.product.id, |
638 | - ConjoinedMaster.productseries_id == dev_focus_id, |
639 | - Not(ConjoinedMaster._status.is_in( |
640 | + ConjoinedPrimary.productseries_id == dev_focus_id, |
641 | + Not(ConjoinedPrimary._status.is_in( |
642 | BugTask._NON_CONJOINED_STATUSES)))) |
643 | - join_tables = [(ConjoinedMaster, join)] |
644 | + join_tables = [(ConjoinedPrimary, join)] |
645 | else: |
646 | raise AssertionError( |
647 | "A milestone must always have either a project, " |
648 | diff --git a/lib/lp/bugs/model/bugwatch.py b/lib/lp/bugs/model/bugwatch.py |
649 | index e9dc359..8b564a3 100644 |
650 | --- a/lib/lp/bugs/model/bugwatch.py |
651 | +++ b/lib/lp/bugs/model/bugwatch.py |
652 | @@ -148,8 +148,8 @@ class BugWatch(SQLBase): |
653 | """Yield the bug tasks that are eligible for update.""" |
654 | for bugtask in self.bugtasks: |
655 | # We don't update conjoined bug tasks; they must be |
656 | - # updated through their conjoined masters. |
657 | - if bugtask.conjoined_master is not None: |
658 | + # updated through their conjoined primaries. |
659 | + if bugtask.conjoined_primary is not None: |
660 | continue |
661 | # We don't update tasks of duplicate bugs. |
662 | if bugtask.bug.duplicateof is not None: |
663 | diff --git a/lib/lp/bugs/model/tests/test_bugtask.py b/lib/lp/bugs/model/tests/test_bugtask.py |
664 | index f50033f..4089d86 100644 |
665 | --- a/lib/lp/bugs/model/tests/test_bugtask.py |
666 | +++ b/lib/lp/bugs/model/tests/test_bugtask.py |
667 | @@ -1685,10 +1685,10 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
668 | return BugData(owner, distro, distro_release, source_package, bug, |
669 | generic_task, series_task) |
670 | |
671 | - def test_editing_generic_status_reflects_upon_conjoined_master(self): |
672 | - # If a change is made to the status of a conjoined slave |
673 | + def test_editing_generic_status_reflects_upon_conjoined_primary(self): |
674 | + # If a change is made to the status of a conjoined replica |
675 | # (generic) task, that change is reflected upon the conjoined |
676 | - # master. |
677 | + # primary. |
678 | data = self._setupBugData() |
679 | with person_logged_in(data.owner): |
680 | # Both the generic task and the series task start off with the |
681 | @@ -1704,10 +1704,10 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
682 | self.assertEqual(BugTaskStatus.CONFIRMED, |
683 | data.series_task.status) |
684 | |
685 | - def test_editing_generic_importance_reflects_upon_conjoined_master(self): |
686 | - # If a change is made to the importance of a conjoined slave |
687 | + def test_editing_generic_importance_reflects_upon_conjoined_primary(self): |
688 | + # If a change is made to the importance of a conjoined replica |
689 | # (generic) task, that change is reflected upon the conjoined |
690 | - # master. |
691 | + # primary. |
692 | data = self._setupBugData() |
693 | with person_logged_in(data.owner): |
694 | data.generic_task.transitionToImportance(BugTaskImportance.HIGH, |
695 | @@ -1715,19 +1715,19 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
696 | self.assertEqual(BugTaskImportance.HIGH, |
697 | data.series_task.importance) |
698 | |
699 | - def test_editing_generic_assignee_reflects_upon_conjoined_master(self): |
700 | - # If a change is made to the assignee of a conjoined slave |
701 | + def test_editing_generic_assignee_reflects_upon_conjoined_primary(self): |
702 | + # If a change is made to the assignee of a conjoined replica |
703 | # (generic) task, that change is reflected upon the conjoined |
704 | - # master. |
705 | + # primary. |
706 | data = self._setupBugData() |
707 | with person_logged_in(data.owner): |
708 | data.generic_task.transitionToAssignee(data.owner) |
709 | self.assertEqual(data.owner, data.series_task.assignee) |
710 | |
711 | - def test_editing_generic_package_reflects_upon_conjoined_master(self): |
712 | - # If a change is made to the source package of a conjoined slave |
713 | + def test_editing_generic_package_reflects_upon_conjoined_primary(self): |
714 | + # If a change is made to the source package of a conjoined replica |
715 | # (generic) task, that change is reflected upon the conjoined |
716 | - # master. |
717 | + # primary. |
718 | data = self._setupBugData() |
719 | source_package_name = self.factory.makeSourcePackageName("ham") |
720 | self.factory.makeSourcePackagePublishingHistory( |
721 | @@ -1777,7 +1777,7 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
722 | self.assertEqual(con_devel_task.milestone.name, 'test') |
723 | |
724 | def test_non_current_dev_lacks_conjoined(self): |
725 | - """Tasks not the current dev focus lacks conjoined masters or slaves. |
726 | + """Tasks not the current dev focus lack conjoined primaries/replicas. |
727 | """ |
728 | # Only owners, experts, or admins can create a series. |
729 | login('foo.bar@canonical.com') |
730 | @@ -1801,8 +1801,8 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
731 | |
732 | stable_netapplet_task = getUtility(IBugTaskSet).createTask( |
733 | ubuntu_netapplet_bug, launchbag.user, alsa_utils_stable) |
734 | - self.assertIsNone(stable_netapplet_task.conjoined_master) |
735 | - self.assertIsNone(stable_netapplet_task.conjoined_slave) |
736 | + self.assertIsNone(stable_netapplet_task.conjoined_primary) |
737 | + self.assertIsNone(stable_netapplet_task.conjoined_replica) |
738 | |
739 | warty = ubuntu.getSeries('warty') |
740 | self.assertNotEqual(warty, ubuntu.currentseries) |
741 | @@ -1811,12 +1811,11 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
742 | ubuntu_netapplet_bug, launchbag.user, |
743 | warty.getSourcePackage(ubuntu_netapplet.sourcepackagename)) |
744 | |
745 | - self.assertIsNone(warty_netapplet_task.conjoined_master) |
746 | - self.assertIsNone(warty_netapplet_task.conjoined_slave) |
747 | + self.assertIsNone(warty_netapplet_task.conjoined_primary) |
748 | + self.assertIsNone(warty_netapplet_task.conjoined_replica) |
749 | |
750 | def test_no_conjoined_without_current_series(self): |
751 | - """Distributions without current series lack a conjoined master/slave. |
752 | - """ |
753 | + """Distros without current series lack a conjoined primary/replica.""" |
754 | login('foo.bar@canonical.com') |
755 | launchbag = getUtility(ILaunchBag) |
756 | ubuntu = getUtility(IDistributionSet).get(1) |
757 | @@ -1832,13 +1831,13 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
758 | gentoo_netapplet_task = getUtility(IBugTaskSet).createTask( |
759 | ubuntu_netapplet_bug, launchbag.user, |
760 | gentoo.getSourcePackage(ubuntu_netapplet.sourcepackagename)) |
761 | - self.assertIsNone(gentoo_netapplet_task.conjoined_master) |
762 | - self.assertIsNone(gentoo_netapplet_task.conjoined_slave) |
763 | + self.assertIsNone(gentoo_netapplet_task.conjoined_primary) |
764 | + self.assertIsNone(gentoo_netapplet_task.conjoined_replica) |
765 | |
766 | def test_conjoined_broken_relationship(self): |
767 | """A conjoined relationship can be broken, though. |
768 | |
769 | - If the development task (i.e the conjoined master) is Won't Fix, it |
770 | + If the development task (i.e the conjoined primary) is Won't Fix, it |
771 | means that the bug is deferred to the next series. In this case the |
772 | development task should be Won't Fix, while the generic task keeps the |
773 | value it had before, allowing it to stay open. |
774 | @@ -1874,8 +1873,8 @@ class TestConjoinedBugTasks(TestCaseWithFactory): |
775 | self.assertIsNotNone(current_series_netapplet_task.date_closed) |
776 | |
777 | # And the bugtasks are no longer conjoined: |
778 | - self.assertIsNone(generic_netapplet_task.conjoined_master) |
779 | - self.assertIsNone(current_series_netapplet_task.conjoined_slave) |
780 | + self.assertIsNone(generic_netapplet_task.conjoined_primary) |
781 | + self.assertIsNone(current_series_netapplet_task.conjoined_replica) |
782 | |
783 | # If the current development release is marked as Invalid, then the |
784 | # bug is invalid for all future series too, and so the general bugtask |
785 | diff --git a/lib/lp/bugs/model/tests/test_bugtasksearch.py b/lib/lp/bugs/model/tests/test_bugtasksearch.py |
786 | index 8c9d81c..a8bd7a7 100644 |
787 | --- a/lib/lp/bugs/model/tests/test_bugtasksearch.py |
788 | +++ b/lib/lp/bugs/model/tests/test_bugtasksearch.py |
789 | @@ -2272,7 +2272,7 @@ class TestBugTaskSearch(TestCaseWithFactory): |
790 | # on the bug that would normally trigger lazy evaluation for security |
791 | # checking. Note that the 'id' attribute does not trigger a check. |
792 | with StormStatementRecorder() as recorder: |
793 | - [task.getConjoinedMaster for task in tasks] |
794 | + [task.getConjoinedPrimary for task in tasks] |
795 | self.assertThat(recorder, has_expected_queries) |
796 | |
797 | def test_omit_targeted_default_is_false(self): |
798 | diff --git a/lib/lp/bugs/scripts/bugexpire.py b/lib/lp/bugs/scripts/bugexpire.py |
799 | index 89d656e..2d4e090 100644 |
800 | --- a/lib/lp/bugs/scripts/bugexpire.py |
801 | +++ b/lib/lp/bugs/scripts/bugexpire.py |
802 | @@ -78,8 +78,8 @@ class BugJanitor: |
803 | self.log.info( |
804 | 'Found %d bugtasks to expire.' % incomplete_bugtasks.count()) |
805 | for bugtask in incomplete_bugtasks: |
806 | - # We don't expire bugtasks with conjoined masters. |
807 | - if bugtask.conjoined_master: |
808 | + # We don't expire bugtasks with conjoined primaries. |
809 | + if bugtask.conjoined_primary: |
810 | continue |
811 | |
812 | with notify_modified(bugtask, ['status'], user=self.janitor): |
813 | diff --git a/lib/lp/bugs/scripts/tests/test_bugimport.py b/lib/lp/bugs/scripts/tests/test_bugimport.py |
814 | index f4f5f7e..35d1196 100644 |
815 | --- a/lib/lp/bugs/scripts/tests/test_bugimport.py |
816 | +++ b/lib/lp/bugs/scripts/tests/test_bugimport.py |
817 | @@ -826,7 +826,7 @@ class TestBugWatch: |
818 | def updateStatus(self, new_remote_status, new_malone_status): |
819 | """See `IBugWatch`.""" |
820 | for bugtask in self.bug.bugtasks: |
821 | - if bugtask.conjoined_master is not None: |
822 | + if bugtask.conjoined_primary is not None: |
823 | continue |
824 | bugtask = removeSecurityProxy(bugtask) |
825 | bugtask._status = new_malone_status |
826 | diff --git a/lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt b/lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt |
827 | index 61e716f..4992385 100644 |
828 | --- a/lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt |
829 | +++ b/lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt |
830 | @@ -12,7 +12,7 @@ |
831 | <td style="padding: 0.3em 0em 0.3em 1.5em" |
832 | tal:condition="data/indent_task"> |
833 | <span class="sprite milestone"></span> |
834 | - <tal:not-conjoined-task condition="not: data/is_conjoined_slave"> |
835 | + <tal:not-conjoined-task condition="not: data/is_conjoined_replica"> |
836 | <a |
837 | tal:attributes="href data/target_link" |
838 | tal:content="view/getSeriesTargetName" |
839 | @@ -46,18 +46,18 @@ |
840 | </span> |
841 | </td> |
842 | |
843 | - <tal:conjoined-task condition="data/is_conjoined_slave"> |
844 | + <tal:conjoined-task condition="data/is_conjoined_replica"> |
845 | <td colspan="5" style="vertical-align: middle"> |
846 | <span class="lesser"> |
847 | Status tracked in |
848 | - <tal:master tal:replace="view/getConjoinedMasterName"> |
849 | + <tal:primary tal:replace="view/getConjoinedPrimaryName"> |
850 | Hoary |
851 | - </tal:master> |
852 | + </tal:primary> |
853 | </span> |
854 | </td> |
855 | </tal:conjoined-task> |
856 | |
857 | - <tal:not-conjoined-task condition="not:data/is_conjoined_slave"> |
858 | + <tal:not-conjoined-task condition="not:data/is_conjoined_replica"> |
859 | <td style="width: 20%; vertical-align: middle"> |
860 | <div class="status-content" |
861 | style="width: 100%; float: left" |
862 | diff --git a/lib/lp/bugs/tests/bugtarget-questiontarget.txt b/lib/lp/bugs/tests/bugtarget-questiontarget.txt |
863 | index 5a7ae5b..4643a0a 100644 |
864 | --- a/lib/lp/bugs/tests/bugtarget-questiontarget.txt |
865 | +++ b/lib/lp/bugs/tests/bugtarget-questiontarget.txt |
866 | @@ -205,7 +205,7 @@ provided |
867 | |
868 | >>> evo_bugtask.transitionToStatus(BugTaskStatus.INVALID, sample_person) |
869 | >>> len([bt for bt in bugtasks |
870 | - ... if bt.status.title == 'New' and bt.conjoined_master is None]) |
871 | + ... if bt.status.title == 'New' and bt.conjoined_primary is None]) |
872 | 1 |
873 | |
874 | >>> big_bug.canBeAQuestion() |
875 | diff --git a/lib/lp/bugs/tests/test_bugsearch_conjoined.py b/lib/lp/bugs/tests/test_bugsearch_conjoined.py |
876 | index 6e28a4a..1407278 100644 |
877 | --- a/lib/lp/bugs/tests/test_bugsearch_conjoined.py |
878 | +++ b/lib/lp/bugs/tests/test_bugsearch_conjoined.py |
879 | @@ -36,7 +36,7 @@ class TestSearchBase(TestCaseWithFactory): |
880 | return bug |
881 | |
882 | |
883 | -class TestProjectExcludeConjoinedMasterSearch(TestSearchBase): |
884 | +class TestProjectExcludeConjoinedPrimarySearch(TestSearchBase): |
885 | """Tests of exclude_conjoined_tasks param for project milestones.""" |
886 | |
887 | layer = DatabaseFunctionalLayer |
888 | @@ -55,7 +55,7 @@ class TestProjectExcludeConjoinedMasterSearch(TestSearchBase): |
889 | user=None, milestone=self.milestone, exclude_conjoined_tasks=True) |
890 | |
891 | def test_search_results_count_simple(self): |
892 | - # Verify number of results with no conjoined masters. |
893 | + # Verify number of results with no conjoined primaries. |
894 | self.assertEqual( |
895 | self.bug_count, |
896 | self.bugtask_set.search(self.params).count()) |
897 | @@ -70,7 +70,7 @@ class TestProjectExcludeConjoinedMasterSearch(TestSearchBase): |
898 | self.assertThat(recorder, HasQueryCount(Equals(4))) |
899 | |
900 | def test_search_results_count_with_other_productseries_tasks(self): |
901 | - # Test with zero conjoined masters and bugtasks targeted to |
902 | + # Test with zero conjoined primaries and bugtasks targeted to |
903 | # productseries that are not the development focus. |
904 | productseries = self.factory.makeProductSeries(product=self.product) |
905 | extra_bugtasks = 0 |
906 | @@ -84,14 +84,14 @@ class TestProjectExcludeConjoinedMasterSearch(TestSearchBase): |
907 | self.bug_count + extra_bugtasks, |
908 | self.bugtask_set.search(self.params).count()) |
909 | |
910 | - def test_search_results_count_with_conjoined_masters(self): |
911 | - # Test with increasing numbers of conjoined masters. |
912 | - # The conjoined masters will exclude the conjoined slaves from |
913 | + def test_search_results_count_with_conjoined_primarys(self): |
914 | + # Test with increasing numbers of conjoined primaries. |
915 | + # The conjoined primaries will exclude the conjoined replicas from |
916 | # the results. |
917 | tasks = list(self.bugtask_set.search(self.params)) |
918 | for bug in self.bugs: |
919 | # The product bugtask is in the results before the conjoined |
920 | - # master is added. |
921 | + # primary is added. |
922 | self.assertIn( |
923 | (bug.id, self.product), |
924 | [(task.bug.id, task.product) for task in tasks]) |
925 | @@ -104,17 +104,17 @@ class TestProjectExcludeConjoinedMasterSearch(TestSearchBase): |
926 | (bug.id, self.product), |
927 | [(task.bug.id, task.product) for task in tasks]) |
928 | |
929 | - def test_search_results_count_with_wontfix_conjoined_masters(self): |
930 | - # Test that conjoined master bugtasks in the WONTFIX status |
931 | + def test_search_results_count_with_wontfix_conjoined_primarys(self): |
932 | + # Test that conjoined primary bugtasks in the WONTFIX status |
933 | # don't cause the bug to be excluded. |
934 | - masters = [ |
935 | + primaries = [ |
936 | self.factory.makeBugTask( |
937 | bug=bug, target=self.product.development_focus) |
938 | for bug in self.bugs] |
939 | tasks = list(self.bugtask_set.search(self.params)) |
940 | - wontfix_masters_count = 0 |
941 | - for bugtask in masters: |
942 | - wontfix_masters_count += 1 |
943 | + wontfix_primaries_count = 0 |
944 | + for bugtask in primaries: |
945 | + wontfix_primaries_count += 1 |
946 | self.assertNotIn( |
947 | (bugtask.bug.id, self.product), |
948 | [(task.bug.id, task.product) for task in tasks]) |
949 | @@ -122,14 +122,14 @@ class TestProjectExcludeConjoinedMasterSearch(TestSearchBase): |
950 | bugtask.transitionToStatus( |
951 | BugTaskStatus.WONTFIX, self.product.owner) |
952 | tasks = list(self.bugtask_set.search(self.params)) |
953 | - self.assertEqual(self.bug_count + wontfix_masters_count, |
954 | + self.assertEqual(self.bug_count + wontfix_primaries_count, |
955 | len(tasks)) |
956 | self.assertIn( |
957 | (bugtask.bug.id, self.product), |
958 | [(task.bug.id, task.product) for task in tasks]) |
959 | |
960 | |
961 | -class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
962 | +class TestProjectGroupExcludeConjoinedPrimarySearch(TestSearchBase): |
963 | """Tests of exclude_conjoined_tasks param for project group milestones.""" |
964 | |
965 | layer = DatabaseFunctionalLayer |
966 | @@ -151,7 +151,7 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
967 | user=None, milestone=self.milestone, exclude_conjoined_tasks=True) |
968 | |
969 | def test_search_results_count_simple(self): |
970 | - # Verify number of results with no conjoined masters. |
971 | + # Verify number of results with no conjoined primaries. |
972 | self.assertEqual( |
973 | self.bug_count, |
974 | self.bugtask_set.search(self.params).count()) |
975 | @@ -166,7 +166,7 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
976 | self.assertThat(recorder, HasQueryCount(Equals(4))) |
977 | |
978 | def test_search_results_count_with_other_productseries_tasks(self): |
979 | - # Test with zero conjoined masters and bugtasks targeted to |
980 | + # Test with zero conjoined primaries and bugtasks targeted to |
981 | # productseries that are not the development focus. |
982 | extra_bugtasks = 0 |
983 | for bug, product in self.bug_products.items(): |
984 | @@ -180,8 +180,8 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
985 | self.bug_count + extra_bugtasks, |
986 | self.bugtask_set.search(self.params).count()) |
987 | |
988 | - def test_search_results_count_with_conjoined_masters(self): |
989 | - # Test with increasing numbers of conjoined masters. |
990 | + def test_search_results_count_with_conjoined_primarys(self): |
991 | + # Test with increasing numbers of conjoined primaries. |
992 | tasks = list(self.bugtask_set.search(self.params)) |
993 | for bug, product in self.bug_products.items(): |
994 | self.assertIn( |
995 | @@ -197,8 +197,8 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
996 | (bug.id, product), |
997 | [(task.bug.id, task.product) for task in tasks]) |
998 | |
999 | - def test_search_results_count_with_irrelevant_conjoined_masters(self): |
1000 | - # Verify that a conjoined master in one project of the project |
1001 | + def test_search_results_count_with_irrelevant_conjoined_primarys(self): |
1002 | + # Verify that a conjoined primary in one project of the project |
1003 | # group doesn't cause a bugtask on another project in the group |
1004 | # to be excluded from the project group milestone's bugs. |
1005 | extra_bugtasks = 0 |
1006 | @@ -216,7 +216,7 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
1007 | with person_logged_in(other_product.owner): |
1008 | other_product_bugtask.transitionToMilestone( |
1009 | other_product_milestone, other_product.owner) |
1010 | - # Add conjoined master for the milestone on the new product. |
1011 | + # Add conjoined primary for the milestone on the new product. |
1012 | self.factory.makeBugTask( |
1013 | bug=bug, target=other_product.development_focus) |
1014 | # The bug count should not change, since we are just adding |
1015 | @@ -225,15 +225,15 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
1016 | self.bug_count + extra_bugtasks, |
1017 | self.bugtask_set.search(self.params).count()) |
1018 | |
1019 | - def test_search_results_count_with_wontfix_conjoined_masters(self): |
1020 | - # Test that conjoined master bugtasks in the WONTFIX status |
1021 | + def test_search_results_count_with_wontfix_conjoined_primarys(self): |
1022 | + # Test that conjoined primary bugtasks in the WONTFIX status |
1023 | # don't cause the bug to be excluded. |
1024 | - masters = [ |
1025 | + primaries = [ |
1026 | self.factory.makeBugTask( |
1027 | bug=bug, target=product.development_focus) |
1028 | for bug, product in self.bug_products.items()] |
1029 | unexcluded_count = 0 |
1030 | - for bugtask in masters: |
1031 | + for bugtask in primaries: |
1032 | unexcluded_count += 1 |
1033 | with person_logged_in(bugtask.target.owner): |
1034 | bugtask.transitionToStatus( |
1035 | @@ -243,7 +243,7 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase): |
1036 | self.bugtask_set.search(self.params).count()) |
1037 | |
1038 | |
1039 | -class TestDistributionExcludeConjoinedMasterSearch(TestSearchBase): |
1040 | +class TestDistributionExcludeConjoinedPrimarySearch(TestSearchBase): |
1041 | """Tests of exclude_conjoined_tasks param for distribution milestones.""" |
1042 | |
1043 | layer = DatabaseFunctionalLayer |
1044 | @@ -262,7 +262,7 @@ class TestDistributionExcludeConjoinedMasterSearch(TestSearchBase): |
1045 | user=None, milestone=self.milestone, exclude_conjoined_tasks=True) |
1046 | |
1047 | def test_search_results_count_simple(self): |
1048 | - # Verify number of results with no conjoined masters. |
1049 | + # Verify number of results with no conjoined primaries. |
1050 | self.assertEqual( |
1051 | self.bug_count, |
1052 | self.bugtask_set.search(self.params).count()) |
1053 | @@ -278,7 +278,7 @@ class TestDistributionExcludeConjoinedMasterSearch(TestSearchBase): |
1054 | self.assertThat(recorder, HasQueryCount(Equals(5))) |
1055 | |
1056 | def test_search_results_count_with_other_productseries_tasks(self): |
1057 | - # Test with zero conjoined masters and bugtasks targeted to |
1058 | + # Test with zero conjoined primaries and bugtasks targeted to |
1059 | # productseries that are not the development focus. |
1060 | distroseries = self.factory.makeDistroSeries( |
1061 | distribution=self.distro, status=SeriesStatus.SUPPORTED) |
1062 | @@ -293,12 +293,12 @@ class TestDistributionExcludeConjoinedMasterSearch(TestSearchBase): |
1063 | self.bug_count + extra_bugtasks, |
1064 | self.bugtask_set.search(self.params).count()) |
1065 | |
1066 | - def test_search_results_count_with_conjoined_masters(self): |
1067 | - # Test with increasing numbers of conjoined masters. |
1068 | + def test_search_results_count_with_conjoined_primarys(self): |
1069 | + # Test with increasing numbers of conjoined primaries. |
1070 | tasks = list(self.bugtask_set.search(self.params)) |
1071 | for bug in self.bugs: |
1072 | # The distro bugtask is in the results before the conjoined |
1073 | - # master is added. |
1074 | + # primary is added. |
1075 | self.assertIn( |
1076 | (bug.id, self.distro), |
1077 | [(task.bug.id, task.distribution) for task in tasks]) |
1078 | @@ -311,19 +311,19 @@ class TestDistributionExcludeConjoinedMasterSearch(TestSearchBase): |
1079 | (bug.id, self.distro), |
1080 | [(task.bug.id, task.distribution) for task in tasks]) |
1081 | |
1082 | - def test_search_results_count_with_wontfix_conjoined_masters(self): |
1083 | - # Test that conjoined master bugtasks in the WONTFIX status |
1084 | + def test_search_results_count_with_wontfix_conjoined_primarys(self): |
1085 | + # Test that conjoined primary bugtasks in the WONTFIX status |
1086 | # don't cause the bug to be excluded. |
1087 | - masters = [ |
1088 | + primaries = [ |
1089 | self.factory.makeBugTask( |
1090 | bug=bug, target=self.distro.currentseries) |
1091 | for bug in self.bugs] |
1092 | - wontfix_masters_count = 0 |
1093 | + wontfix_primaries_count = 0 |
1094 | tasks = list(self.bugtask_set.search(self.params)) |
1095 | - for bugtask in masters: |
1096 | - wontfix_masters_count += 1 |
1097 | + for bugtask in primaries: |
1098 | + wontfix_primaries_count += 1 |
1099 | # The distro bugtask is still excluded by the conjoined |
1100 | - # master. |
1101 | + # primary. |
1102 | self.assertNotIn( |
1103 | (bugtask.bug.id, self.distro), |
1104 | [(task.bug.id, task.distribution) for task in tasks]) |
1105 | @@ -332,10 +332,10 @@ class TestDistributionExcludeConjoinedMasterSearch(TestSearchBase): |
1106 | BugTaskStatus.WONTFIX, self.distro.owner) |
1107 | tasks = list(self.bugtask_set.search(self.params)) |
1108 | self.assertEqual( |
1109 | - self.bug_count + wontfix_masters_count, |
1110 | + self.bug_count + wontfix_primaries_count, |
1111 | self.bugtask_set.search(self.params).count()) |
1112 | # The distro bugtask is no longer excluded by the conjoined |
1113 | - # master, since its status is WONTFIX. |
1114 | + # primary, since its status is WONTFIX. |
1115 | self.assertIn( |
1116 | (bugtask.bug.id, self.distro), |
1117 | [(task.bug.id, task.distribution) for task in tasks]) |
1118 | diff --git a/lib/lp/bugs/tests/test_bugwatch.py b/lib/lp/bugs/tests/test_bugwatch.py |
1119 | index d595d08..402253b 100644 |
1120 | --- a/lib/lp/bugs/tests/test_bugwatch.py |
1121 | +++ b/lib/lp/bugs/tests/test_bugwatch.py |
1122 | @@ -360,7 +360,7 @@ class TestBugWatch(TestCaseWithFactory): |
1123 | [product_task], list( |
1124 | removeSecurityProxy(watch).bugtasks_to_update)) |
1125 | # If we add a task such that the existing task becomes a |
1126 | - # conjoined slave, only thr master task will be eligible for |
1127 | + # conjoined replica, only the primary task will be eligible for |
1128 | # update. |
1129 | product_series_task = self.factory.makeBugTask( |
1130 | bug=bug, target=product.development_focus) |
1131 | diff --git a/lib/lp/registry/browser/__init__.py b/lib/lp/registry/browser/__init__.py |
1132 | index cb372fb..c9b6f86 100644 |
1133 | --- a/lib/lp/registry/browser/__init__.py |
1134 | +++ b/lib/lp/registry/browser/__init__.py |
1135 | @@ -236,8 +236,8 @@ class RegistryDeleteViewMixin: |
1136 | # milestone, since it's still referenced. |
1137 | for bugtask in self._getBugtasks(milestone, ignore_privacy=True): |
1138 | nb = removeSecurityProxy(bugtask) |
1139 | - if nb.conjoined_master is not None: |
1140 | - Store.of(bugtask).remove(nb.conjoined_master) |
1141 | + if nb.conjoined_primary is not None: |
1142 | + Store.of(bugtask).remove(nb.conjoined_primary) |
1143 | else: |
1144 | nb.milestone = None |
1145 | removeSecurityProxy(milestone.all_specifications).set(milestoneID=None) |
1146 | diff --git a/lib/lp/registry/browser/milestone.py b/lib/lp/registry/browser/milestone.py |
1147 | index fb645c2..865b7f9 100644 |
1148 | --- a/lib/lp/registry/browser/milestone.py |
1149 | +++ b/lib/lp/registry/browser/milestone.py |
1150 | @@ -218,22 +218,22 @@ class MilestoneViewMixin: |
1151 | """The list of non-conjoined bugtasks targeted to this milestone.""" |
1152 | # Put the results in a list so that iterating over it multiple |
1153 | # times in this method does not make multiple queries. |
1154 | - non_conjoined_slaves = self.context.bugtasks(self.user) |
1155 | + non_conjoined_replicas = self.context.bugtasks(self.user) |
1156 | # Checking bug permissions is expensive. We know from the query that |
1157 | # the user has at least launchpad.View on the bugtasks and their bugs. |
1158 | # NB: this is in principle unneeded due to injection of permission in |
1159 | # the model layer now. |
1160 | precache_permission_for_objects( |
1161 | - self.request, 'launchpad.View', non_conjoined_slaves) |
1162 | + self.request, 'launchpad.View', non_conjoined_replicas) |
1163 | precache_permission_for_objects( |
1164 | self.request, 'launchpad.View', |
1165 | - [task.bug for task in non_conjoined_slaves]) |
1166 | + [task.bug for task in non_conjoined_replicas]) |
1167 | # We want the assignees loaded as we show them in the milestone home |
1168 | # page. |
1169 | list(getUtility(IPersonSet).getPrecachedPersonsFromIDs( |
1170 | - [bug.assignee_id for bug in non_conjoined_slaves], |
1171 | + [bug.assignee_id for bug in non_conjoined_replicas], |
1172 | need_validity=True)) |
1173 | - return non_conjoined_slaves |
1174 | + return non_conjoined_replicas |
1175 | |
1176 | @cachedproperty |
1177 | def _bug_badge_properties(self): |
1178 | diff --git a/lib/lp/registry/model/milestone.py b/lib/lp/registry/model/milestone.py |
1179 | index ed418c1..c6b5631 100644 |
1180 | --- a/lib/lp/registry/model/milestone.py |
1181 | +++ b/lib/lp/registry/model/milestone.py |
1182 | @@ -203,10 +203,10 @@ class MilestoneData: |
1183 | """The list of non-conjoined bugtasks targeted to this milestone.""" |
1184 | # Put the results in a list so that iterating over it multiple |
1185 | # times in this method does not make multiple queries. |
1186 | - non_conjoined_slaves = list( |
1187 | + non_conjoined_replicas = list( |
1188 | getUtility(IBugTaskSet).getPrecachedNonConjoinedBugTasks( |
1189 | user, self)) |
1190 | - return non_conjoined_slaves |
1191 | + return non_conjoined_replicas |
1192 | |
1193 | |
1194 | @implementer(IHasBugs, IMilestone, IBugSummaryDimension) |
1195 | diff --git a/lib/lp/registry/model/person.py b/lib/lp/registry/model/person.py |
1196 | index 09e1bca..b544ae3 100644 |
1197 | --- a/lib/lp/registry/model/person.py |
1198 | +++ b/lib/lp/registry/model/person.py |
1199 | @@ -1532,11 +1532,11 @@ class Person( |
1200 | bulk.load_related(Milestone, tasks, ['milestone_id']) |
1201 | |
1202 | for task in tasks: |
1203 | - # We skip masters (instead of slaves) from conjoined relationships |
1204 | - # because we can do that without hittind the DB, which would not |
1205 | - # be possible if we wanted to skip the slaves. The simple (but |
1206 | - # expensive) way to skip the slaves would be to skip any tasks |
1207 | - # that have a non-None .conjoined_master. |
1208 | + # We skip primaries (instead of replicas) from conjoined |
1209 | + # relationships because we can do that without hitting the DB, |
1210 | + # which would not be possible if we wanted to skip the replicas. |
1211 | + # The simple (but expensive) way to skip the replicas would be |
1212 | + # to skip any tasks that have a non-None .conjoined_primary. |
1213 | productseries = task.productseries |
1214 | distroseries = task.distroseries |
1215 | if productseries is not None and task.product is None: |
1216 | @@ -1546,10 +1546,11 @@ class Person( |
1217 | continue |
1218 | elif distroseries is not None: |
1219 | candidate = None |
1220 | - for possible_slave in tasks: |
1221 | - sourcepackagename_id = possible_slave.sourcepackagename_id |
1222 | + for possible_replica in tasks: |
1223 | + sourcepackagename_id = ( |
1224 | + possible_replica.sourcepackagename_id) |
1225 | if sourcepackagename_id == task.sourcepackagename_id: |
1226 | - candidate = possible_slave |
1227 | + candidate = possible_replica |
1228 | # Distribution.currentseries is expensive to run for every |
1229 | # bugtask (as it goes through every series of that |
1230 | # distribution), but it's a cached property and there's only |
1231 | @@ -2258,10 +2259,10 @@ class Person( |
1232 | coc.active = False |
1233 | params = BugTaskSearchParams(self, assignee=self) |
1234 | for bug_task in self.searchTasks(params): |
1235 | - # If the bugtask has a conjoined master we don't try to |
1236 | + # If the bugtask has a conjoined primary we don't try to |
1237 | # update it, since we will update it correctly when we |
1238 | - # update its conjoined master (see bug 193983). |
1239 | - if bug_task.conjoined_master is not None: |
1240 | + # update its conjoined primary (see bug 193983). |
1241 | + if bug_task.conjoined_primary is not None: |
1242 | continue |
1243 | |
1244 | # XXX flacoste 2007-11-26 bug=164635 The comparison using id in |
1245 | diff --git a/lib/lp/registry/tests/test_milestonetag.py b/lib/lp/registry/tests/test_milestonetag.py |
1246 | index 10ff914..d946961 100644 |
1247 | --- a/lib/lp/registry/tests/test_milestonetag.py |
1248 | +++ b/lib/lp/registry/tests/test_milestonetag.py |
1249 | @@ -161,7 +161,7 @@ class ProjectGroupMilestoneTagTest(TestCaseWithFactory): |
1250 | target=self.project_group, tags=tags) |
1251 | return items, milestonetag |
1252 | |
1253 | - # Add a test similar to TestProjectExcludeConjoinedMasterSearch in |
1254 | + # Add a test similar to TestProjectExcludeConjoinedPrimarySearch in |
1255 | # lp.bugs.tests.test_bugsearch_conjoined. |
1256 | |
1257 | def test_bugtask_retrieve_single_milestone(self): |
1258 | diff --git a/lib/lp/registry/tests/test_person.py b/lib/lp/registry/tests/test_person.py |
1259 | index 1e9ef75..10d8456 100644 |
1260 | --- a/lib/lp/registry/tests/test_person.py |
1261 | +++ b/lib/lp/registry/tests/test_person.py |
1262 | @@ -1770,7 +1770,7 @@ class Test_getAssignedBugTasksDueBefore(TestCaseWithFactory): |
1263 | |
1264 | self.assertEqual(private_bug2.bugtasks, bugtasks) |
1265 | |
1266 | - def test_skips_distroseries_task_that_is_a_conjoined_master(self): |
1267 | + def test_skips_distroseries_task_that_is_a_conjoined_primary(self): |
1268 | distroseries = self.factory.makeDistroSeries() |
1269 | sourcepackagename = self.factory.makeSourcePackageName() |
1270 | sp = distroseries.getSourcePackage(sourcepackagename.name) |
1271 | @@ -1780,38 +1780,38 @@ class Test_getAssignedBugTasksDueBefore(TestCaseWithFactory): |
1272 | milestone=milestone, target=sp.distribution_sourcepackage) |
1273 | removeSecurityProxy(bug).addTask(bug.owner, sp) |
1274 | self.assertEqual(2, len(bug.bugtasks)) |
1275 | - slave, master = bug.bugtasks |
1276 | - self._assignBugTaskToTeamOwner(master) |
1277 | - self.assertEqual(None, master.conjoined_master) |
1278 | - self.assertEqual(master, slave.conjoined_master) |
1279 | - self.assertEqual(slave.milestone, master.milestone) |
1280 | - self.assertEqual(slave.assignee, master.assignee) |
1281 | + replica, primary = bug.bugtasks |
1282 | + self._assignBugTaskToTeamOwner(primary) |
1283 | + self.assertEqual(None, primary.conjoined_primary) |
1284 | + self.assertEqual(primary, replica.conjoined_primary) |
1285 | + self.assertEqual(replica.milestone, primary.milestone) |
1286 | + self.assertEqual(replica.assignee, primary.assignee) |
1287 | |
1288 | bugtasks = list(self.team.getAssignedBugTasksDueBefore( |
1289 | self.today + timedelta(days=1), user=None)) |
1290 | |
1291 | - self.assertEqual([slave], bugtasks) |
1292 | + self.assertEqual([replica], bugtasks) |
1293 | |
1294 | - def test_skips_productseries_task_that_is_a_conjoined_master(self): |
1295 | + def test_skips_productseries_task_that_is_a_conjoined_primary(self): |
1296 | milestone = self.factory.makeMilestone(dateexpected=self.today) |
1297 | removeSecurityProxy(milestone.product).development_focus = ( |
1298 | milestone.productseries) |
1299 | bug = self.factory.makeBug( |
1300 | series=milestone.productseries, milestone=milestone) |
1301 | self.assertEqual(2, len(bug.bugtasks)) |
1302 | - slave, master = bug.bugtasks |
1303 | + replica, primary = bug.bugtasks |
1304 | |
1305 | # This will cause the assignee to propagate to the other bugtask as |
1306 | # well since they're conjoined. |
1307 | - self._assignBugTaskToTeamOwner(slave) |
1308 | - self.assertEqual(master, slave.conjoined_master) |
1309 | - self.assertEqual(slave.milestone, master.milestone) |
1310 | - self.assertEqual(slave.assignee, master.assignee) |
1311 | + self._assignBugTaskToTeamOwner(replica) |
1312 | + self.assertEqual(primary, replica.conjoined_primary) |
1313 | + self.assertEqual(replica.milestone, primary.milestone) |
1314 | + self.assertEqual(replica.assignee, primary.assignee) |
1315 | |
1316 | bugtasks = list(self.team.getAssignedBugTasksDueBefore( |
1317 | self.today + timedelta(days=1), user=None)) |
1318 | |
1319 | - self.assertEqual([slave], bugtasks) |
1320 | + self.assertEqual([replica], bugtasks) |
1321 | |
1322 | def _assignBugTaskToTeamOwnerAndSetMilestone(self, task, milestone): |
1323 | self._assignBugTaskToTeamOwner(task) |
Conjoined primary and replica sound good to me.