Merge lp:~abentley/launchpad/fix-592319 into lp:launchpad

Proposed by Aaron Bentley
Status: Merged
Approved by: Māris Fogels
Approved revision: no longer in the source branch.
Merged at revision: 11012
Proposed branch: lp:~abentley/launchpad/fix-592319
Merge into: lp:launchpad
Diff against target: 71 lines (+16/-7)
2 files modified
lib/lp/soyuz/tests/test_archive.py (+1/-1)
lib/lp/testing/factory.py (+15/-6)
To merge this branch: bzr merge lp:~abentley/launchpad/fix-592319
Reviewer Review Type Date Requested Status
Māris Fogels (community) Approve
Review via email: mp+27552@code.launchpad.net

Commit message

Use a random starting integer instead of a UUID.

Description of the change

= Summary =
Fix bug #592319: test_match_exact_branch_name fails spuriously

== Proposed fix ==
Append an integer, rather than a UUID, to the base of generic strings. This
allows us to retain our assertions that generic strings do not contain specific
non-numeric strings. However, while the integer will increment normally,
the starting point of the integer is random, so that multiple runs can be done
against the same database without conflicts.

== Pre-implementation notes ==
Discussed parameters of a solution with BjornT

== Implementation details ==
Used thread-local storage so that this approach is thread-safe. Each thread
will use its own random starting point.

Used a range between 0 and 1,000,000 for the starting point, because using
maxint/2 exceeded maximum database values.

== Tests ==
bin/test -v

== Demo and Q/A ==
None. This is a fix for a transient failure, so you can never be sure that it
*would* have failed.

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/testing/factory.py

To post a comment you must log in.
Revision history for this message
Māris Fogels (mars) wrote :

Hi Aaron,

This looks good. Brilliant use of Python builtins. r=mars

Maris

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/soyuz/tests/test_archive.py'
2--- lib/lp/soyuz/tests/test_archive.py 2010-05-19 15:39:52 +0000
3+++ lib/lp/soyuz/tests/test_archive.py 2010-06-15 13:34:40 +0000
4@@ -239,7 +239,7 @@
5 ubuntu_test = breezy_autotest.distribution
6 self.series = [breezy_autotest]
7 self.series.append(self.factory.makeDistroRelease(
8- distribution=ubuntu_test, name="foo-series"))
9+ distribution=ubuntu_test, name="foo-series", version='1.0'))
10
11 self.sources = []
12 gedit_src_hist = self.publisher.getPubSource(
13
14=== modified file 'lib/lp/testing/factory.py'
15--- lib/lp/testing/factory.py 2010-06-13 05:56:31 +0000
16+++ lib/lp/testing/factory.py 2010-06-15 13:34:40 +0000
17@@ -22,8 +22,10 @@
18 from email.mime.text import MIMEText
19 from email.mime.multipart import MIMEMultipart
20 from itertools import count
21+import os.path
22+from random import randint
23 from StringIO import StringIO
24-import os.path
25+from threading import local
26
27 import pytz
28
29@@ -56,7 +58,6 @@
30 from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy
31 from canonical.launchpad.webapp.interfaces import (
32 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
33-from canonical.uuid import generate_uuid
34
35 from lp.blueprints.interfaces.specification import (
36 ISpecificationSet, SpecificationDefinitionStatus)
37@@ -213,14 +214,22 @@
38
39 def __init__(self):
40 # Initialise the unique identifier.
41- self._integer = count(1)
42+ self._local = local()
43
44 def getUniqueEmailAddress(self):
45 return "%s@example.com" % self.getUniqueString('email')
46
47 def getUniqueInteger(self):
48- """Return an integer unique to this factory instance."""
49- return self._integer.next()
50+ """Return an integer unique to this factory instance.
51+
52+ For each thread, this will be a series of increasing numbers, but the
53+ starting point will be unique per thread.
54+ """
55+ counter = getattr(self._local, 'integer', None)
56+ if counter is None:
57+ counter = count(randint(0, 1000000))
58+ self._local.integer = counter
59+ return counter.next()
60
61 def getUniqueHexString(self, digits=None):
62 """Return a unique hexadecimal string.
63@@ -245,7 +254,7 @@
64 """
65 if prefix is None:
66 prefix = "generic-string"
67- string = "%s%s" % (prefix, generate_uuid())
68+ string = "%s%s" % (prefix, self.getUniqueInteger())
69 return string.replace('_', '-').lower()
70
71 def getUniqueUnicode(self):