Merge lp:~cjwatson/launchpad/testrunner-uuid into lp:launchpad

Proposed by Colin Watson on 2015-09-30
Status: Merged
Merged at revision: 17808
Proposed branch: lp:~cjwatson/launchpad/testrunner-uuid
Merge into: lp:launchpad
Diff against target: 89 lines (+20/-8)
3 files modified
lib/lp/testing/layers.py (+4/-2)
lib/lp/testing/tests/test_layers_functional.py (+7/-4)
lib/lp/testing/tests/test_pgsql.py (+9/-2)
To merge this branch: bzr merge lp:~cjwatson/launchpad/testrunner-uuid
Reviewer Review Type Date Requested Status
William Grant code 2015-09-30 Approve on 2015-10-08
Review via email: mp+272942@code.launchpad.net

Commit Message

Generate LP_TEST_INSTANCE based on a UUID as well as the process ID.

Description of the Change

When running tests in parallel, it's possible (and in some setups quite probable) for various LXC containers to end up with the same process IDs for bin/test. To avoid problems caused by this, generate LP_TEST_INSTANCE based on a UUID (replacing "-" with "_" so that it can form part of a valid database name) as well as the process ID.

To post a comment you must log in.
William Grant (wgrant) wrote :

I'd like to see the PID included before the UUID, so it's easy enough to go from test process to DB.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/testing/layers.py'
2--- lib/lp/testing/layers.py 2015-10-05 13:46:23 +0000
3+++ lib/lp/testing/layers.py 2015-10-08 11:35:52 +0000
4@@ -1,4 +1,4 @@
5-# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
6+# Copyright 2009-2015 Canonical Ltd. This software is licensed under the
7 # GNU Affero General Public License version 3 (see the file LICENSE).
8
9 """Layers used by Launchpad tests.
10@@ -70,6 +70,7 @@
11 TestResult,
12 )
13 from urllib import urlopen
14+import uuid
15
16 from fixtures import (
17 Fixture,
18@@ -329,7 +330,8 @@
19 # We can only do unique test allocation and parallelisation if
20 # LP_PERSISTENT_TEST_SERVICES is off.
21 if not BaseLayer.persist_test_services:
22- test_instance = str(os.getpid())
23+ test_instance = '%d_%s' % (
24+ os.getpid(), str(uuid.uuid1()).replace('-', '_'))
25 os.environ['LP_TEST_INSTANCE'] = test_instance
26 cls.fixture.addCleanup(os.environ.pop, 'LP_TEST_INSTANCE', '')
27 # Kill any Memcached or Librarian left running from a previous
28
29=== modified file 'lib/lp/testing/tests/test_layers_functional.py'
30--- lib/lp/testing/tests/test_layers_functional.py 2013-06-21 01:55:44 +0000
31+++ lib/lp/testing/tests/test_layers_functional.py 2015-10-08 11:35:52 +0000
32@@ -1,4 +1,4 @@
33-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
34+# Copyright 2009-2015 Canonical Ltd. This software is licensed under the
35 # GNU Affero General Public License version 3 (see the file LICENSE).
36
37 from __future__ import with_statement
38@@ -17,6 +17,7 @@
39 import signal
40 import smtplib
41 from urllib import urlopen
42+import uuid
43
44 from amqplib import client_0_8 as amqp
45 from fixtures import (
46@@ -113,9 +114,11 @@
47 def test_allocates_LP_TEST_INSTANCE(self):
48 self.useFixture(BaseLayerIsolator())
49 with LayerFixture(BaseLayer):
50- self.assertEqual(
51- str(os.getpid()),
52- os.environ.get('LP_TEST_INSTANCE'))
53+ pid, raw_uuid = os.environ['LP_TEST_INSTANCE'].split('_', 1)
54+ self.assertEqual(str(os.getpid()), pid)
55+ instance_uuid = uuid.UUID(raw_uuid.replace('_', '-'))
56+ self.assertEqual(uuid.RFC_4122, instance_uuid.variant)
57+ self.assertEqual(1, instance_uuid.version)
58 self.assertEqual(None, os.environ.get('LP_TEST_INSTANCE'))
59
60 def test_persist_test_services_disables_LP_TEST_INSTANCE(self):
61
62=== modified file 'lib/lp/testing/tests/test_pgsql.py'
63--- lib/lp/testing/tests/test_pgsql.py 2015-10-05 09:51:25 +0000
64+++ lib/lp/testing/tests/test_pgsql.py 2015-10-08 11:35:52 +0000
65@@ -1,7 +1,8 @@
66-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
67+# Copyright 2009-2015 Canonical Ltd. This software is licensed under the
68 # GNU Affero General Public License version 3 (see the file LICENSE).
69
70 import os
71+import uuid
72
73 from fixtures import (
74 EnvironmentVariableFixture,
75@@ -36,7 +37,13 @@
76 BaseLayer.setUp()
77 self.addCleanup(BaseLayer.tearDown)
78 fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
79- expected_name = "%s_%d" % (PgTestSetup.dbname, os.getpid())
80+ raw_uuid = os.environ['LP_TEST_INSTANCE'].split('_', 1)[1]
81+ instance_uuid = uuid.UUID(raw_uuid.replace('_', '-'))
82+ self.assertEqual(uuid.RFC_4122, instance_uuid.variant)
83+ self.assertEqual(1, instance_uuid.version)
84+ expected_name = "%s_%d_%s" % (
85+ PgTestSetup.dbname, os.getpid(),
86+ str(instance_uuid).replace('-', '_'))
87 self.assertDBName(expected_name, fixture)
88
89 def test_db_naming_without_LP_TEST_INSTANCE_is_static(self):