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
=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py 2010-05-19 15:39:52 +0000
+++ lib/lp/soyuz/tests/test_archive.py 2010-06-15 13:34:40 +0000
@@ -239,7 +239,7 @@
239 ubuntu_test = breezy_autotest.distribution239 ubuntu_test = breezy_autotest.distribution
240 self.series = [breezy_autotest]240 self.series = [breezy_autotest]
241 self.series.append(self.factory.makeDistroRelease(241 self.series.append(self.factory.makeDistroRelease(
242 distribution=ubuntu_test, name="foo-series"))242 distribution=ubuntu_test, name="foo-series", version='1.0'))
243243
244 self.sources = []244 self.sources = []
245 gedit_src_hist = self.publisher.getPubSource(245 gedit_src_hist = self.publisher.getPubSource(
246246
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-06-13 05:56:31 +0000
+++ lib/lp/testing/factory.py 2010-06-15 13:34:40 +0000
@@ -22,8 +22,10 @@
22from email.mime.text import MIMEText22from email.mime.text import MIMEText
23from email.mime.multipart import MIMEMultipart23from email.mime.multipart import MIMEMultipart
24from itertools import count24from itertools import count
25import os.path
26from random import randint
25from StringIO import StringIO27from StringIO import StringIO
26import os.path28from threading import local
2729
28import pytz30import pytz
2931
@@ -56,7 +58,6 @@
56from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy58from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy
57from canonical.launchpad.webapp.interfaces import (59from canonical.launchpad.webapp.interfaces import (
58 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)60 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
59from canonical.uuid import generate_uuid
6061
61from lp.blueprints.interfaces.specification import (62from lp.blueprints.interfaces.specification import (
62 ISpecificationSet, SpecificationDefinitionStatus)63 ISpecificationSet, SpecificationDefinitionStatus)
@@ -213,14 +214,22 @@
213214
214 def __init__(self):215 def __init__(self):
215 # Initialise the unique identifier.216 # Initialise the unique identifier.
216 self._integer = count(1)217 self._local = local()
217218
218 def getUniqueEmailAddress(self):219 def getUniqueEmailAddress(self):
219 return "%s@example.com" % self.getUniqueString('email')220 return "%s@example.com" % self.getUniqueString('email')
220221
221 def getUniqueInteger(self):222 def getUniqueInteger(self):
222 """Return an integer unique to this factory instance."""223 """Return an integer unique to this factory instance.
223 return self._integer.next()224
225 For each thread, this will be a series of increasing numbers, but the
226 starting point will be unique per thread.
227 """
228 counter = getattr(self._local, 'integer', None)
229 if counter is None:
230 counter = count(randint(0, 1000000))
231 self._local.integer = counter
232 return counter.next()
224233
225 def getUniqueHexString(self, digits=None):234 def getUniqueHexString(self, digits=None):
226 """Return a unique hexadecimal string.235 """Return a unique hexadecimal string.
@@ -245,7 +254,7 @@
245 """254 """
246 if prefix is None:255 if prefix is None:
247 prefix = "generic-string"256 prefix = "generic-string"
248 string = "%s%s" % (prefix, generate_uuid())257 string = "%s%s" % (prefix, self.getUniqueInteger())
249 return string.replace('_', '-').lower()258 return string.replace('_', '-').lower()
250259
251 def getUniqueUnicode(self):260 def getUniqueUnicode(self):