summaryrefslogtreecommitdiff
path: root/bzrlib/tests/blackbox/test_exceptions.py
blob: 9124662bae04a003a1a5ebc387e0cdf8440f60e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# Copyright (C) 2006, 2007, 2009, 2010, 2011 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""Tests for display of exceptions."""

import os
import re

from bzrlib import (
    bzrdir,
    config,
    controldir,
    errors,
    osutils,
    repository,
    tests,
    )
from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a


class TestExceptionReporting(tests.TestCaseInTempDir):

    def test_exception_exitcode(self):
        # we must use a subprocess, because the normal in-memory mechanism
        # allows errors to propagate up through the test suite
        out, err = self.run_bzr_subprocess(['assert-fail'],
            universal_newlines=True,
            retcode=errors.EXIT_INTERNAL_ERROR)
        self.assertEqual(4, errors.EXIT_INTERNAL_ERROR)
        self.assertContainsRe(err,
                r'exceptions\.AssertionError: always fails\n')
        self.assertContainsRe(err, r'Bazaar has encountered an internal error')

    def test_undecodable_argv(self):
        """A user error must be reported if argv is not in the locale encoding

        A subprocess with an environment ascii-only setting is used so the test
        can run without worrying about the locale the test suite is using.
        """
        if os.name != "posix":
            raise tests.TestNotApplicable("Needs system beholden to C locales")
        out, err = self.run_bzr_subprocess(["\xa0"],
            env_changes={"LANG": "C", "LC_ALL": "C"},
            universal_newlines=True,
            retcode=errors.EXIT_ERROR)
        self.assertContainsRe(err, r"^bzr: ERROR: .*'\\xa0'.* unsupported",
            flags=re.MULTILINE)
        self.assertEquals(out, "")

    def test_utf8_default_fs_enc(self):
        """In the C locale bzr treats a posix filesystem as UTF-8 encoded"""
        if os.name != "posix":
            raise tests.TestNotApplicable("Needs system beholden to C locales")
        out, err = self.run_bzr_subprocess(["init", "file:%C2%A7"],
            env_changes={"LANG": "C", "LC_ALL": "C"})
        self.assertContainsRe(out, "^Created a standalone tree .*$")


class TestOptParseBugHandling(tests.TestCase):
    "Test that we handle http://bugs.python.org/issue2931"

    def test_nonascii_optparse(self):
        """Reasonable error raised when non-ascii in option name"""
        error_re = 'Only ASCII permitted in option names'
        out = self.run_bzr_error([error_re], ['st',u'-\xe4'])


class TestObsoleteRepoFormat(RepositoryFormat2a):

    @classmethod
    def get_format_string(cls):
        return "Test Obsolete Repository Format"

    def is_deprecated(self):
        return True


class TestDeprecationWarning(tests.TestCaseWithTransport):
    """The deprecation warning is controlled via a global variable:
    repository._deprecation_warning_done. As such, it can be emitted only once
    during a bzr invocation, no matter how many repositories are involved.

    It would be better if it was a repo attribute instead but that's far more
    work than I want to do right now -- vila 20091215.
    """

    def setUp(self):
        super(TestDeprecationWarning, self).setUp()
        self.addCleanup(repository.format_registry.remove,
            TestObsoleteRepoFormat)
        repository.format_registry.register(TestObsoleteRepoFormat)
        self.addCleanup(controldir.format_registry.remove, "testobsolete")
        bzrdir.register_metadir(controldir.format_registry, "testobsolete",
            "bzrlib.tests.blackbox.test_exceptions.TestObsoleteRepoFormat",
            branch_format='bzrlib.branch.BzrBranchFormat7',
            tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
            deprecated=True,
            help='Same as 2a, but with an obsolete repo format.')
        self.disable_deprecation_warning()

    def enable_deprecation_warning(self, repo=None):
        """repo is not used yet since _deprecation_warning_done is a global"""
        repository._deprecation_warning_done = False

    def disable_deprecation_warning(self, repo=None):
        """repo is not used yet since _deprecation_warning_done is a global"""
        repository._deprecation_warning_done = True

    def make_obsolete_repo(self, path):
        # We don't want the deprecation raising during the repo creation
        format = controldir.format_registry.make_bzrdir("testobsolete")
        tree = self.make_branch_and_tree(path, format=format)
        return tree

    def check_warning(self, present):
        if present:
            check = self.assertContainsRe
        else:
            check = self.assertNotContainsRe
        check(self.get_log(), 'WARNING.*bzr upgrade')

    def test_repository_deprecation_warning(self):
        """Old formats give a warning"""
        self.make_obsolete_repo('foo')
        self.enable_deprecation_warning()
        out, err = self.run_bzr('status', working_dir='foo')
        self.check_warning(True)

    def test_repository_deprecation_warning_suppressed_global(self):
        """Old formats give a warning"""
        conf = config.GlobalStack()
        conf.set('suppress_warnings', 'format_deprecation')
        self.make_obsolete_repo('foo')
        self.enable_deprecation_warning()
        out, err = self.run_bzr('status', working_dir='foo')
        self.check_warning(False)

    def test_repository_deprecation_warning_suppressed_locations(self):
        """Old formats give a warning"""
        self.make_obsolete_repo('foo')
        conf = config.LocationStack(osutils.pathjoin(self.test_dir, 'foo'))
        conf.set('suppress_warnings', 'format_deprecation')
        self.enable_deprecation_warning()
        out, err = self.run_bzr('status', working_dir='foo')
        self.check_warning(False)

    def test_repository_deprecation_warning_suppressed_branch(self):
        """Old formats give a warning"""
        tree = self.make_obsolete_repo('foo')
        conf = tree.branch.get_config_stack()
        conf.set('suppress_warnings', 'format_deprecation')
        self.enable_deprecation_warning()
        out, err = self.run_bzr('status', working_dir='foo')
        self.check_warning(False)