/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk

« back to all changes in this revision

Viewing changes to loggerhead/tests/test_simple.py

  • Committer: Ubuntu One Auto Copilot
  • Author(s): Jelmer Vernooij
  • Date: 2022-08-30 10:28:23 UTC
  • mfrom: (533.1.1 trunk)
  • Revision ID: otto-copilot@canonical.com-20220830102823-u3w6efosxw5s086s
Cope with moved errors NoSuchFile and FileExists in newer versions of Breezy.

Merged from https://code.launchpad.net/~jelmer/loggerhead/moved-errors/+merge/429073

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import cgi
2
 
import unittest
3
 
import os
4
 
import tempfile
5
 
import shutil
 
1
# Copyright (C) 2007, 2008, 2009, 2011 Canonical Ltd.
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
#
 
17
 
 
18
from __future__ import absolute_import
 
19
 
 
20
from html import escape
 
21
import json
6
22
import logging
 
23
import re
 
24
from io import BytesIO
7
25
 
8
 
import bzrlib.bzrdir
9
 
import bzrlib.osutils
 
26
from breezy.tests import TestCaseWithTransport
10
27
from configobj import ConfigObj
 
28
from breezy import config
11
29
 
12
 
from loggerhead.history import History
13
 
from loggerhead.apps.branch import BranchWSGIApp
 
30
from ..apps.branch import BranchWSGIApp
 
31
from ..apps.http_head import HeadMiddleware
14
32
from paste.fixture import TestApp
15
 
 
16
 
 
17
 
def test_config_root():
18
 
    from loggerhead.apps.config import Root
19
 
    config = ConfigObj()
20
 
    app = TestApp(Root(config))
21
 
    res = app.get('/')
22
 
    res.mustcontain('loggerhead branches')
23
 
 
24
 
 
25
 
class BasicTests(object):
26
 
 
27
 
    # setup_method and teardown_method are so i can run the tests with
28
 
    # py.test and take advantage of the error reporting.
29
 
    def setup_method(self, meth):
30
 
        self.setUp()
31
 
 
32
 
    def teardown_method(self, meth):
33
 
        self.tearDown()
 
33
from paste.httpexceptions import HTTPExceptionHandler, HTTPMovedPermanently
 
34
 
 
35
from .fixtures import (
 
36
    SampleBranch,
 
37
    )
 
38
 
 
39
 
 
40
class BasicTests(TestCaseWithTransport):
34
41
 
35
42
    def setUp(self):
36
 
        logging.basicConfig(level=logging.DEBUG)
37
 
        self.bzrbranch = None
38
 
        self.old_bzrhome = None
 
43
        TestCaseWithTransport.setUp(self)
 
44
        logging.basicConfig(level=logging.ERROR)
 
45
        logging.getLogger('bzr').setLevel(logging.CRITICAL)
39
46
 
40
47
    def createBranch(self):
41
 
        self.old_bzrhome = bzrlib.osutils.set_or_unset_env('BZR_HOME', '')
42
 
        self.bzrbranch = tempfile.mkdtemp()
43
 
        self.branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
44
 
            self.bzrbranch, force_new_tree=True)
45
 
        self.tree = self.branch.bzrdir.open_workingtree()
46
 
 
47
 
    config_template = """
48
 
    [project]
49
 
        [[branch]]
50
 
            branch_name = 'branch'
51
 
            folder = '%(branch)s'
52
 
    """
53
 
 
54
 
    def setUpLoggerhead(self):
55
 
        app = TestApp(BranchWSGIApp(self.branch).app)
56
 
        return app
57
 
 
58
 
    def tearDown(self):
59
 
        if self.bzrbranch is not None:
60
 
            shutil.rmtree(self.bzrbranch)
61
 
        bzrlib.osutils.set_or_unset_env('BZR_HOME', self.old_bzrhome)
 
48
        self.tree = self.make_branch_and_tree('.')
 
49
 
 
50
    def setUpLoggerhead(self, **kw):
 
51
        branch_app = BranchWSGIApp(self.tree.branch, '', **kw).app
 
52
        return TestApp(HTTPExceptionHandler(branch_app))
 
53
 
 
54
    def assertOkJsonResponse(self, app, env):
 
55
        start, content = consume_app(app, env)
 
56
        self.assertEqual('200 OK', start[0])
 
57
        self.assertEqual('application/json', dict(start[1])['Content-Type'])
 
58
        self.assertEqual(None, start[2])
 
59
        json.loads(content.decode('UTF-8'))
 
60
 
 
61
    def make_branch_app(self, branch, **kw):
 
62
        branch_app = BranchWSGIApp(branch, friendly_name='friendly-name', **kw)
 
63
        branch_app._environ = {
 
64
            'wsgi.url_scheme':'',
 
65
            'SERVER_NAME':'',
 
66
            'SERVER_PORT':'80',
 
67
            }
 
68
        branch_app._url_base = ''
 
69
        return branch_app
62
70
 
63
71
 
64
72
class TestWithSimpleTree(BasicTests):
65
73
 
66
74
    def setUp(self):
67
75
        BasicTests.setUp(self)
68
 
        self.createBranch()
69
 
 
70
 
        f = open(os.path.join(self.bzrbranch, 'myfilename'), 'w')
71
 
        self.filecontents = ('some\nmultiline\ndata\n'
72
 
                             'with<htmlspecialchars\n')
73
 
        try:
74
 
            f.write(self.filecontents)
75
 
        finally:
76
 
            f.close()
77
 
        self.tree.add('myfilename')
78
 
        self.fileid = self.tree.path2id('myfilename')
79
 
        self.msg = 'a very exciting commit message <'
80
 
        self.revid = self.tree.commit(message=self.msg)
81
 
 
 
76
        self.sample_branch_fixture = SampleBranch(self)
 
77
 
 
78
        # XXX: This could be cleaned up more... -- mbp 2011-11-25
 
79
        self.useFixture(self.sample_branch_fixture)
 
80
        self.tree = self.sample_branch_fixture.tree
 
81
        self.path = self.sample_branch_fixture.path
 
82
        self.filecontents = self.sample_branch_fixture.filecontents
 
83
        self.msg = self.sample_branch_fixture.msg
 
84
 
 
85
    def test_public_private(self):
 
86
        app = self.make_branch_app(self.tree.branch, private=True)
 
87
        self.assertEqual(app.public_private_css(), 'private')
 
88
        app = self.make_branch_app(self.tree.branch)
 
89
        self.assertEqual(app.public_private_css(), 'public')
82
90
 
83
91
    def test_changes(self):
84
92
        app = self.setUpLoggerhead()
85
93
        res = app.get('/changes')
86
 
        res.mustcontain(cgi.escape(self.msg))
 
94
        res.mustcontain(escape(self.msg))
 
95
 
 
96
    def test_changes_for_file(self):
 
97
        app = self.setUpLoggerhead()
 
98
        res = app.get('/changes?filter_path=%s' % self.path)
 
99
        res.mustcontain(escape(self.msg))
 
100
 
 
101
    def test_changes_branch_from(self):
 
102
        app = self.setUpLoggerhead(served_url="lp:loggerhead")
 
103
        res = app.get('/changes')
 
104
        self.failUnless("To get this branch, use:" in res)
 
105
        self.failUnless("lp:loggerhead" in res)
87
106
 
88
107
    def test_changes_search(self):
89
108
        app = self.setUpLoggerhead()
92
111
 
93
112
    def test_annotate(self):
94
113
        app = self.setUpLoggerhead()
95
 
        res = app.get('/annotate', params={'file_id':self.fileid})
 
114
        res = app.get('/annotate/1/%s' % self.path, params={})
 
115
        # If pygments is installed, it inserts <span class="pyg" content into
 
116
        # the output, to trigger highlighting. And it specifically highlights
 
117
        # the &lt; that we are interested in seeing in the output.
 
118
        # Without pygments we have a simple: 'with&lt;htmlspecialchars'
 
119
        # With it, we have
 
120
        # '<span class='pyg-n'>with</span><span class='pyg-o'>&lt;</span>'
 
121
        # '<span class='pyg-n'>htmlspecialchars</span>
 
122
        # So we pre-filter the body, to make sure remove spans of that type.
 
123
        body_no_span = re.sub(b'<span class="pyg-.">', b'', res.body)
 
124
        body_no_span = body_no_span.replace(b'</span>', b'')
96
125
        for line in self.filecontents.splitlines():
97
 
            res.mustcontain(cgi.escape(line))
 
126
            escaped = escape(line).encode('utf-8')
 
127
            self.assertTrue(escaped in body_no_span,
 
128
                            "did not find %r in %r" % (escaped, body_no_span))
98
129
 
99
130
    def test_inventory(self):
100
131
        app = self.setUpLoggerhead()
101
132
        res = app.get('/files')
102
133
        res.mustcontain('myfilename')
 
134
        res = app.get('/files/')
 
135
        res.mustcontain('myfilename')
 
136
        res = app.get('/files/1')
 
137
        res.mustcontain('myfilename')
 
138
        res = app.get('/files/1/')
 
139
        res.mustcontain('myfilename')
 
140
 
 
141
    def test_inventory_bad_rev_404(self):
 
142
        app = self.setUpLoggerhead()
 
143
        res = app.get('/files/200', status=404)
 
144
        res = app.get('/files/invalid-revid', status=404)
 
145
 
 
146
    def test_inventory_bad_path_404(self):
 
147
        app = self.setUpLoggerhead()
 
148
        res = app.get('/files/1/hooha', status=404)
103
149
 
104
150
    def test_revision(self):
105
151
        app = self.setUpLoggerhead()
106
152
        res = app.get('/revision/1')
 
153
        res.mustcontain(no=['anotherfile<'])
 
154
        res.mustcontain('anotherfile&lt;')
107
155
        res.mustcontain('myfilename')
108
156
 
109
157
 
110
158
class TestEmptyBranch(BasicTests):
 
159
    """Test that an empty branch doesn't break"""
111
160
 
112
161
    def setUp(self):
113
162
        BasicTests.setUp(self)
118
167
        res = app.get('/changes')
119
168
        res.mustcontain('No revisions!')
120
169
 
 
170
    def test_inventory(self):
 
171
        app = self.setUpLoggerhead()
 
172
        res = app.get('/files')
 
173
        res.mustcontain('No revisions!')
 
174
 
 
175
 
 
176
class TestHiddenBranch(BasicTests):
 
177
    """
 
178
    Test that hidden branches aren't shown
 
179
    FIXME: not tested that it doesn't show up on listings
 
180
    """
 
181
 
 
182
    def setUp(self):
 
183
        BasicTests.setUp(self)
 
184
        self.createBranch()
 
185
        try:
 
186
            locations = config.locations_config_filename()
 
187
        except AttributeError:
 
188
            from breezy import bedding
 
189
            locations = bedding.locations_config_path()
 
190
            ensure_config_dir_exists = bedding.ensure_config_dir_exists
 
191
        else:
 
192
            ensure_config_dir_exists = config.ensure_config_dir_exists
 
193
        ensure_config_dir_exists()
 
194
        with open(locations, 'w') as f:
 
195
            f.write('[%s]\nhttp_serve = False' % (
 
196
                self.tree.branch.base,))
 
197
 
 
198
    def test_no_access(self):
 
199
        app = self.setUpLoggerhead()
 
200
        res = app.get('/changes', status=404)
 
201
 
 
202
 
 
203
class TestControllerRedirects(BasicTests):
 
204
    """
 
205
    Test that a file under /files redirects to /view,
 
206
    and a directory under /view redirects to /files.
 
207
    """
 
208
 
 
209
    def setUp(self):
 
210
        BasicTests.setUp(self)
 
211
        self.createBranch()
 
212
        self.build_tree(('file', 'folder/', 'folder/file'))
 
213
        self.tree.smart_add([])
 
214
        self.tree.commit('')
 
215
 
 
216
    def test_view_folder(self):
 
217
        app = TestApp(BranchWSGIApp(self.tree.branch, '').app)
 
218
 
 
219
        e = self.assertRaises(HTTPMovedPermanently, app.get, '/view/head:/folder')
 
220
        self.assertEqual(e.location(), '/files/head:/folder')
 
221
 
 
222
    def test_files_file(self):
 
223
        app = TestApp(BranchWSGIApp(self.tree.branch, '').app)
 
224
 
 
225
        e = self.assertRaises(HTTPMovedPermanently, app.get, '/files/head:/folder/file')
 
226
        self.assertEqual(e.location(), '/view/head:/folder/file')
 
227
        e = self.assertRaises(HTTPMovedPermanently, app.get, '/files/head:/file')
 
228
        self.assertEqual(e.location(), '/view/head:/file')
 
229
 
 
230
 
 
231
class TestHeadMiddleware(BasicTests):
 
232
 
 
233
    def setUp(self):
 
234
        BasicTests.setUp(self)
 
235
        self.createBranch()
 
236
        self.msg = 'trivial commit message'
 
237
        self.revid = self.tree.commit(message=self.msg)
 
238
 
 
239
    def setUpLoggerhead(self, **kw):
 
240
        branch_app = BranchWSGIApp(self.tree.branch, '', **kw).app
 
241
        return TestApp(HTTPExceptionHandler(HeadMiddleware(branch_app)))
 
242
 
 
243
    def test_get(self):
 
244
        app = self.setUpLoggerhead()
 
245
        res = app.get('/changes')
 
246
        res.mustcontain(self.msg)
 
247
        self.assertEqual('text/html', res.header('Content-Type'))
 
248
 
 
249
    def test_head(self):
 
250
        app = self.setUpLoggerhead()
 
251
        res = app.get('/changes', extra_environ={'REQUEST_METHOD': 'HEAD'})
 
252
        self.assertEqual('text/html', res.header('Content-Type'))
 
253
        self.assertEqualDiff(b'', res.body)
 
254
 
 
255
 
 
256
def consume_app(app, env):
 
257
    body = BytesIO()
 
258
    start = []
 
259
    def start_response(status, headers, exc_info=None):
 
260
        start.append((status, headers, exc_info))
 
261
        return body.write
 
262
    extra_content = list(app(env, start_response))
 
263
    body.writelines(extra_content)
 
264
    return start[0], body.getvalue()
 
265
 
 
266
 
 
267
 
 
268
#class TestGlobalConfig(BasicTests):
 
269
#    """
 
270
#    Test that global config settings are respected
 
271
#    """
 
272
 
 
273
#    def setUp(self):
 
274
#        BasicTests.setUp(self)
 
275
#        self.createBranch()
 
276
#        config.GlobalConfig().set_user_option('http_version', 'True')
 
277
 
 
278
#    def test_setting_respected(self):
 
279
        #FIXME: Figure out how to test this properly
 
280
#        app = self.setUpLoggerhead()
 
281
#        res = app.get('/changes', status=200)