~launchpad-pqm/launchpad/devel

14575.1.1 by Jeroen Vermeulen
Lint.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.22 by Karl Fogel
Add the copyright header block to the remaining .py files.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
3
4
"""Tests for IBranchCloud provider."""
5
6
__metaclass__ = type
7
14550.1.1 by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad
8
from datetime import (
9
    datetime,
10
    timedelta,
11
    )
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
12
13
import pytz
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
14
from storm.locals import Store
14550.1.1 by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad
15
import transaction
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
16
from zope.component import getUtility
17
18
from canonical.testing.layers import DatabaseFunctionalLayer
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
19
from lp.code.interfaces.branch import IBranchCloud
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
20
from lp.code.model.revision import RevisionCache
14562.1.3 by William Grant
Merge databasehelpers into code
21
from lp.code.tests.helpers import (
22
    make_project_branch_with_revisions,
23
    remove_all_sample_data_branches,
24
    )
14550.1.1 by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad
25
from lp.testing import (
26
    TestCaseWithFactory,
27
    time_counter,
28
    )
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
29
30
31
class TestBranchCloud(TestCaseWithFactory):
32
33
    layer = DatabaseFunctionalLayer
34
35
    def setUp(self):
36
        TestCaseWithFactory.setUp(self)
37
        remove_all_sample_data_branches()
38
        self._branch_cloud = getUtility(IBranchCloud)
39
40
    def getProductsWithInfo(self, num_products=None):
41
        """Get product cloud information."""
11435.5.4 by Tim Penhey
Always use the slave store, even in the tests.
42
        # Since we use the slave store to get the information, we need to
43
        # commit the transaction to make the information visible to the slave.
44
        transaction.commit()
45
        cloud_info = self._branch_cloud.getProductsWithInfo(num_products)
14575.1.1 by Jeroen Vermeulen
Lint.
46
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
47
        def add_utc(value):
14575.1.1 by Jeroen Vermeulen
Lint.
48
            # Since Storm's Max function does not take into account the
49
            # type that it is aggregating, the last commit time is not
50
            # timezone-aware.  Whack the UTC timezone on it here for
51
            # easier comparing in the tests.
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
52
            return value.replace(tzinfo=pytz.UTC)
14575.1.1 by Jeroen Vermeulen
Lint.
53
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
54
        return [
55
            (name, commits, authors, add_utc(last_commit))
56
            for name, commits, authors, last_commit in cloud_info]
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
57
11435.5.3 by Tim Penhey
Make the view work better.
58
    def makeBranch(self, product=None, last_commit_date=None, private=False,
59
                   revision_count=None):
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
60
        """Make a product branch with a particular last commit date"""
11435.5.4 by Tim Penhey
Always use the slave store, even in the tests.
61
        if revision_count is None:
62
            revision_count = 5
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
63
        delta = timedelta(days=1)
64
        if last_commit_date is None:
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
65
            # By default we create revisions that are within the last 30 days.
66
            date_generator = time_counter(
67
                datetime.now(pytz.UTC) - timedelta(days=25), delta)
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
68
        else:
69
            start_date = last_commit_date - delta * (revision_count - 1)
70
            date_generator = time_counter(start_date, delta)
11435.5.3 by Tim Penhey
Make the view work better.
71
        branch = make_project_branch_with_revisions(
72
            self.factory, date_generator, product, private, revision_count)
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
73
        return branch
74
75
    def test_empty_with_no_branches(self):
76
        # getProductsWithInfo returns an empty result set if there are no
77
        # branches in the database.
11435.5.2 by Tim Penhey
Fix the remainder tests.
78
        self.assertEqual([], self.getProductsWithInfo())
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
79
80
    def test_empty_products_not_counted(self):
81
        # getProductsWithInfo doesn't include products that don't have any
82
        # branches.
83
        #
84
        # Note that this is tested implicitly by test_empty_with_no_branches,
85
        # since there are such products in the sample data.
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
86
        self.factory.makeProduct()
11435.5.2 by Tim Penhey
Fix the remainder tests.
87
        self.assertEqual([], self.getProductsWithInfo())
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
88
89
    def test_empty_branches_not_counted(self):
90
        # getProductsWithInfo doesn't consider branches that lack revision
91
        # data, 'empty branches', to contribute to the count of branches on a
92
        # product.
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
93
        self.factory.makeProductBranch()
11435.5.2 by Tim Penhey
Fix the remainder tests.
94
        self.assertEqual([], self.getProductsWithInfo())
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
95
7767.2.1 by Jonathan Lange
Don't show private branches.
96
    def test_private_branches_not_counted(self):
97
        # getProductsWithInfo doesn't count private branches.
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
98
        self.makeBranch(private=True)
11435.5.2 by Tim Penhey
Fix the remainder tests.
99
        self.assertEqual([], self.getProductsWithInfo())
7767.2.1 by Jonathan Lange
Don't show private branches.
100
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
101
    def test_revisions_counted(self):
102
        # getProductsWithInfo includes products that public revisions.
103
        last_commit_date = datetime.now(pytz.UTC) - timedelta(days=5)
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
104
        product = self.factory.makeProduct()
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
105
        self.makeBranch(product=product, last_commit_date=last_commit_date)
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
106
        self.assertEqual(
11435.5.2 by Tim Penhey
Fix the remainder tests.
107
            [(product.name, 5, 1, last_commit_date)],
108
            self.getProductsWithInfo())
11435.5.1 by Tim Penhey
Extract the branch cloud into its own module.
109
110
    def test_only_recent_revisions_counted(self):
111
        # If the revision cache has revisions for the project, but they are
112
        # over 30 days old, we don't count them.
113
        product = self.factory.makeProduct()
114
        date_generator = time_counter(
115
            datetime.now(pytz.UTC) - timedelta(days=33),
116
            delta=timedelta(days=2))
117
        store = Store.of(product)
118
        for i in range(4):
119
            revision = self.factory.makeRevision(
120
                revision_date=date_generator.next())
121
            cache = RevisionCache(revision)
122
            cache.product = product
123
            store.add(cache)
11435.5.2 by Tim Penhey
Fix the remainder tests.
124
        self.assertEqual(
125
            [(product.name, 2, 2, revision.revision_date)],
126
            self.getProductsWithInfo())
127
128
    def test_sorted_by_commit_count(self):
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
129
        # getProductsWithInfo returns a result set sorted so that the products
11435.5.2 by Tim Penhey
Fix the remainder tests.
130
        # with the most commits come first.
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
131
        product1 = self.factory.makeProduct()
132
        for i in range(3):
133
            self.makeBranch(product=product1)
134
        product2 = self.factory.makeProduct()
135
        for i in range(5):
136
            self.makeBranch(product=product2)
137
        self.assertEqual(
8225.2.3 by Tim Penhey
Fix the test cases I was missing.
138
            [product2.name, product1.name],
11435.5.2 by Tim Penhey
Fix the remainder tests.
139
            [name for name, commits, count, last_commit
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
140
             in self.getProductsWithInfo()])
141
142
    def test_limit(self):
143
        # If num_products is passed to getProductsWithInfo, it limits the
144
        # number of products in the result set. The products with the fewest
145
        # branches are discarded first.
146
        product1 = self.factory.makeProduct()
147
        for i in range(3):
148
            self.makeBranch(product=product1)
149
        product2 = self.factory.makeProduct()
150
        for i in range(5):
151
            self.makeBranch(product=product2)
7703.6.14 by Jonathan Lange
Added another comment, and extended the limit test to test limiting to
152
        product3 = self.factory.makeProduct()
153
        for i in range(7):
154
            self.makeBranch(product=product3)
7703.6.12 by Jonathan Lange
Lots of unit tests for getProductsWithInfo.
155
        self.assertEqual(
8225.2.3 by Tim Penhey
Fix the test cases I was missing.
156
            [product3.name, product2.name],
11435.5.2 by Tim Penhey
Fix the remainder tests.
157
            [name for name, commits, count, last_commit
7703.6.14 by Jonathan Lange
Added another comment, and extended the limit test to test limiting to
158
             in self.getProductsWithInfo(num_products=2)])