~launchpad-pqm/launchpad/devel

7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
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
"""Provides a context manager to run parts of a test as a different dbuser."""
5
14022.3.10 by William Grant
Fix lp.testing.dbuser to not try to import lp.testing.storm.database.
6
from __future__ import absolute_import
7
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
8
__metaclass__ = type
9
__all__ = [
10
    'dbuser',
11
    'lp_dbuser',
14022.3.5 by William Grant
LZL.switchDbUser is now a wrapper around a new lp.testing.dbuser.switch_dbuser.
12
    'switch_dbuser',
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
13
    ]
14
15
from contextlib import contextmanager
16
14022.3.10 by William Grant
Fix lp.testing.dbuser to not try to import lp.testing.storm.database.
17
from storm.database import (
18
    STATE_CONNECTED,
19
    STATE_DISCONNECTED,
20
    )
14022.3.9 by William Grant
Move update_store_connections into lp.testing.dbuser, its only callsite.
21
from storm.zope.interfaces import IZStorm
13970.10.11 by William Grant
Fix tests.
22
import transaction
14022.3.9 by William Grant
Move update_store_connections into lp.testing.dbuser, its only callsite.
23
from zope.component import getUtility
13970.10.11 by William Grant
Fix tests.
24
14605.1.1 by Curtis Hovey
Moved canonical.config to lp.services.
25
from lp.services.config import dbconfig
14022.3.9 by William Grant
Move update_store_connections into lp.testing.dbuser, its only callsite.
26
27
28
def update_store_connections():
29
    """Update the connection settings for all active stores.
30
31
    This is required for connection setting changes to be made visible.
32
33
    Unlike disconnect_stores and reconnect_stores, this changes the
34
    underlying connection of *existing* stores, leaving existing objects
35
    functional.
36
    """
37
    for name, store in getUtility(IZStorm).iterstores():
38
        connection = store._connection
14022.3.10 by William Grant
Fix lp.testing.dbuser to not try to import lp.testing.storm.database.
39
        if connection._state == STATE_CONNECTED:
14022.3.9 by William Grant
Move update_store_connections into lp.testing.dbuser, its only callsite.
40
            if connection._raw_connection is not None:
41
                connection._raw_connection.close()
42
43
            # This method assumes that calling transaction.abort() will
44
            # call rollback() on the store, but this is no longer the
45
            # case as of jamesh's fix for bug 230977; Stores are not
46
            # registered with the transaction manager until they are
47
            # used. While storm doesn't provide an API which does what
48
            # we want, we'll go under the covers and emit the
49
            # register-transaction event ourselves. This method is
50
            # only called by the test suite to kill the existing
51
            # connections so the Store's reconnect with updated
52
            # connection settings.
53
            store._event.emit('register-transaction')
54
55
            connection._raw_connection = None
14022.3.10 by William Grant
Fix lp.testing.dbuser to not try to import lp.testing.storm.database.
56
            connection._state = STATE_DISCONNECTED
14022.3.9 by William Grant
Move update_store_connections into lp.testing.dbuser, its only callsite.
57
    transaction.abort()
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
58
13970.10.11 by William Grant
Fix tests.
59
14022.3.5 by William Grant
LZL.switchDbUser is now a wrapper around a new lp.testing.dbuser.switch_dbuser.
60
def switch_dbuser(new_name):
61
    """Change the current database user.
62
63
    If new_name is None, the default will be restored.
64
    """
65
    transaction.commit()
66
    dbconfig.override(dbuser=new_name)
67
    update_store_connections()
68
69
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
70
@contextmanager
7675.1039.8 by Gary Poster
make the helper a bit leaner
71
def dbuser(temporary_name):
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
72
    """A context manager that temporarily changes the dbuser.
13970.10.11 by William Grant
Fix tests.
73
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
74
    Use with the LaunchpadZopelessLayer layer and subclasses.
13970.10.11 by William Grant
Fix tests.
75
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
76
    temporary_name is the name of the dbuser that should be in place for the
7675.1039.8 by Gary Poster
make the helper a bit leaner
77
    code in the "with" block.
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
78
    """
14022.3.3 by William Grant
lp.testing.dbuser now uses dbconfig.override directly. Still uses ZTM._reset_stores.
79
    old_name = getattr(dbconfig.overrides, 'dbuser', None)
14022.3.5 by William Grant
LZL.switchDbUser is now a wrapper around a new lp.testing.dbuser.switch_dbuser.
80
    switch_dbuser(temporary_name)
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
81
    yield
14022.3.5 by William Grant
LZL.switchDbUser is now a wrapper around a new lp.testing.dbuser.switch_dbuser.
82
    switch_dbuser(old_name)
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
83
13970.10.11 by William Grant
Fix tests.
84
7675.1039.8 by Gary Poster
make the helper a bit leaner
85
def lp_dbuser():
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
86
    """A context manager that temporarily changes to the launchpad dbuser.
13970.10.11 by William Grant
Fix tests.
87
7675.1039.7 by Gary Poster
make tests pass, by switching to the launchpad dbuser when building test fixtures as necessary. add a convenience function for this.
88
    Use with the LaunchpadZopelessLayer layer and subclasses.
89
    """
7675.1039.8 by Gary Poster
make the helper a bit leaner
90
    return dbuser('launchpad')