~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/buildmaster/testing.py

[r=allenap, bac, gmb, julian-edwards, wallyworld][bug=905853, 905855,
 906079] In buildmaster,
 always shift into a read-write database transaction access mode before
 updating PackageBuild statuses. Shift into read-write transactions in
 appropriate places in TranslationTemplatesBuildBehavior. Ensure that all
 lp.buildmaster tests to which it is relevant are running with
 BuilddManagerTestFixture.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2011 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
"""Testing helpers for buildmaster code."""
 
5
 
 
6
__metaclass__ = type
 
7
__all__ = [
 
8
    "BuilddManagerTestFixture",
 
9
    ]
 
10
 
 
11
from contextlib import contextmanager
 
12
from functools import wraps
 
13
 
 
14
import fixtures
 
15
import transaction
 
16
 
 
17
from lp.services.database.transaction_policy import DatabaseTransactionPolicy
 
18
 
 
19
 
 
20
class BuilddManagerTestFixture(fixtures.Fixture):
 
21
    """Helps provide an environment more like `BuilddManager` provides.
 
22
 
 
23
    This mimics the default transaction access policy of `BuilddManager`,
 
24
    though it can be configured with a different policy by passing in `store`
 
25
    and/or `read_only`. See `BuilddManager.enterReadOnlyDatabasePolicy`.
 
26
 
 
27
    Because this will shift into a read-only database transaction access mode,
 
28
    individual tests that need to do more setup can use the `extraSetUp()`
 
29
    context manager to temporarily shift back to a read-write mode.
 
30
    """
 
31
 
 
32
    def __init__(self, store=None, read_only=True):
 
33
        super(BuilddManagerTestFixture, self).__init__()
 
34
        self.policy = DatabaseTransactionPolicy(
 
35
            store=store, read_only=read_only)
 
36
 
 
37
    def setUp(self):
 
38
        # Commit everything done so far then shift into a read-only
 
39
        # transaction access mode by default.
 
40
        super(BuilddManagerTestFixture, self).setUp()
 
41
        transaction.commit()
 
42
        self.policy.__enter__()
 
43
        self.addCleanup(self.policy.__exit__, None, None, None)
 
44
 
 
45
    @staticmethod
 
46
    def extraSetUp(func=None):
 
47
        """Temporarily enter a read-write transaction to do extra setup.
 
48
 
 
49
        For example:
 
50
 
 
51
          with BuilddManagerTestFixture.extraSetUp():
 
52
              removeSecurityProxy(self.build).date_finished = None
 
53
 
 
54
        On exit it will commit the changes and restore the previous
 
55
        transaction access mode.
 
56
 
 
57
        Alternatively it can be used as a decorator:
 
58
 
 
59
          @BuilddManagerTestFixture.extraSetUp
 
60
          def makeSomethingOrOther(self):
 
61
              return ...
 
62
 
 
63
        Like with the context manager, on return it will commit the changes
 
64
        and restore the previous transaction access mode.
 
65
        """
 
66
        if func is None:
 
67
            @contextmanager
 
68
            def context():
 
69
                with DatabaseTransactionPolicy(read_only=False):
 
70
                    yield
 
71
                    transaction.commit()
 
72
            return context()
 
73
        else:
 
74
            @wraps(func)
 
75
            def wrapper(*args, **kwargs):
 
76
                with DatabaseTransactionPolicy(read_only=False):
 
77
                    result = func(*args, **kwargs)
 
78
                    transaction.commit()
 
79
                    return result
 
80
            return wrapper