~launchpad-pqm/launchpad/devel

9372.1.2 by Tim Penhey
Add a statement counter to the base test class.
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
"""Tests relating to the Launchpad TestCase classes here."""
5
6
__metaclass__ = type
7
11132.2.1 by James Westby
Attach any oopses to the test results.
8
from StringIO import StringIO
9
import sys
10
13686.2.5 by Robert Collins
Update to oops 0.0.4.
11
import oops_datedir_repo.serializer_rfc822
9372.1.2 by Tim Penhey
Add a statement counter to the base test class.
12
from storm.store import Store
13
from zope.component import getUtility
14
11132.2.1 by James Westby
Attach any oopses to the test results.
15
from canonical.launchpad.webapp import errorlog
16
from canonical.testing.layers import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
17
    DatabaseFunctionalLayer,
18
    FunctionalLayer,
19
    )
9372.1.2 by Tim Penhey
Add a statement counter to the base test class.
20
from lp.code.interfaces.branch import IBranchSet
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
21
from lp.testing import (
22
    record_statements,
23
    TestCaseWithFactory,
24
    )
9372.1.3 by Tim Penhey
Reworked statement counting.
25
26
27
class TestRecordStatements(TestCaseWithFactory):
28
    """Test the statement recorder."""
9372.1.2 by Tim Penhey
Add a statement counter to the base test class.
29
30
    layer = DatabaseFunctionalLayer
31
32
    def test_counter_positive(self):
33
        # The base TestCase setUp adds a statement counter.
9372.1.3 by Tim Penhey
Reworked statement counting.
34
        branch, statements = record_statements(self.factory.makeBranch)
35
        self.assertTrue(len(statements) > 0)
9372.1.2 by Tim Penhey
Add a statement counter to the base test class.
36
37
    def test_store_invalidation_counts(self):
38
        # When creating objects with the factory, they stay in the storm
39
        # cache, sometimes we want to confirm that no more queries are
40
        # happening, so we need to clear the cache to avoid getting cached
41
        # objects where there would normally be queries.
42
        branch = self.factory.makeBranch()
43
        store = Store.of(branch)
9372.1.3 by Tim Penhey
Reworked statement counting.
44
9372.1.2 by Tim Penhey
Add a statement counter to the base test class.
45
        # Make sure everything is in the database.
46
        store.flush()
47
        # Reset the store to clear the cache (not just invalidate).
48
        store.reset()
49
        branch = getUtility(IBranchSet).getByUniqueName(branch.unique_name)
9372.1.3 by Tim Penhey
Reworked statement counting.
50
        self.assertStatementCount(1, getattr, branch, "owner")
9372.1.2 by Tim Penhey
Add a statement counter to the base test class.
51
52
11132.2.1 by James Westby
Attach any oopses to the test results.
53
class TestCaptureOops(TestCaseWithFactory):
14104.6.25 by Robert Collins
Give CaptureOops a better home and a focused test.
54
    # Note that this tests the testcase specific functionality; see
55
    # test_fixture for tests of the CaptureOops fixture.
11132.2.1 by James Westby
Attach any oopses to the test results.
56
57
    layer = FunctionalLayer
58
59
    def trigger_oops(self):
60
        try:
61
            raise AssertionError("Exception to get a traceback.")
62
        except AssertionError:
63
            errorlog.globalErrorUtility.raising(sys.exc_info())
64
65
    def test_no_oops_gives_no_details(self):
66
        self.assertEqual(0, len(self.oopses))
67
        self.attachOopses()
68
        self.assertEqual(
69
            0, len([a for a in self.getDetails() if "oops" in a]))
70
71
    def test_one_oops_gives_one_detail(self):
72
        self.assertEqual(0, len(self.oopses))
73
        self.trigger_oops()
74
        self.attachOopses()
75
        self.assertEqual(
76
            ["oops-0"], [a for a in self.getDetails() if "oops" in a])
77
78
    def test_two_oops_gives_two_details(self):
79
        self.assertEqual(0, len(self.oopses))
80
        self.trigger_oops()
81
        self.trigger_oops()
82
        self.attachOopses()
83
        self.assertEqual(
84
            ["oops-0", "oops-1"],
85
            sorted([a for a in self.getDetails() if "oops" in a]))
86
87
    def test_oops_content(self):
88
        self.assertEqual(0, len(self.oopses))
89
        self.trigger_oops()
90
        self.attachOopses()
91
        content = StringIO()
11502.1.5 by Robert Collins
OOPS were generating unicode chunks which upcasts automatically; tweak the module to be more robust.
92
        content.writelines(self.getDetails()['oops-0'].iter_bytes())
11132.2.1 by James Westby
Attach any oopses to the test results.
93
        content.seek(0)
11502.1.5 by Robert Collins
OOPS were generating unicode chunks which upcasts automatically; tweak the module to be more robust.
94
        # Safety net: ensure that no autocasts have occured even on Python 2.6
95
        # which is slightly better.
14104.6.36 by Robert Collins
Cleanup some lint.
96
        self.assertIsInstance(content.getvalue(), str)
14104.6.14 by Robert Collins
Fix test_testcase to not use getLastOops.
97
        # In tests it should be rfc822 for easy reading.
13686.2.5 by Robert Collins
Update to oops 0.0.4.
98
        from_details = oops_datedir_repo.serializer_rfc822.read(content)
14104.6.14 by Robert Collins
Fix test_testcase to not use getLastOops.
99
        # Compare with the in-memory model (but only a select key, because the
100
        # rfc822 serializer is lossy).
101
        oops_report = self.oopses[0]
102
        self.assertEqual(from_details['id'], oops_report['id'])