/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3948.2.6 by Martin Pool
ProgressBarStack is deprecated
1
# Copyright (C) 2005, 2008, 2009 Canonical Ltd
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
16
17
"""Tests for the bzrlib ui
18
"""
19
20
import os
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
21
from StringIO import StringIO
1704.2.9 by Martin Pool
Make text_factory test not depend on 80-col terminal
22
import re
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
23
import sys
4017.1.1 by John Arbash Meinel
Get a pb.tick() to work after calling pb.update()
24
import time
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
25
1681.1.2 by Robert Collins
* bzrlib.ui.text.TextUIFactory now accepts a bar_type parameter which
26
import bzrlib
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
27
import bzrlib.errors as errors
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
28
from bzrlib.progress import (
29
    ProgressTask,
30
    )
3948.2.6 by Martin Pool
ProgressBarStack is deprecated
31
from bzrlib.symbol_versioning import (
32
    deprecated_in,
33
    )
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
34
from bzrlib.tests import (
2363.4.10 by Vincent Ladeuil
Complete tests.
35
    TestCase,
2294.4.4 by Vincent Ladeuil
Provide a better implementation for testing passwords.
36
    TestUIFactory,
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
37
    StringIOWrapper,
38
    )
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
39
from bzrlib.tests.test_progress import (
40
    _NonTTYStringIO,
41
    _TTYStringIO,
42
    )
2363.4.10 by Vincent Ladeuil
Complete tests.
43
from bzrlib.ui import (
44
    CLIUIFactory,
45
    SilentUIFactory,
46
    )
4110.2.15 by Martin Pool
Fix bug in showing task progress and add a test
47
from bzrlib.ui.text import (
4449.2.4 by Martin Pool
Add tests for BZR_PROGRESS_BAR
48
    NullProgressView,
4110.2.15 by Martin Pool
Fix bug in showing task progress and add a test
49
    TextProgressView,
50
    TextUIFactory,
51
    )
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
52
1681.1.2 by Robert Collins
* bzrlib.ui.text.TextUIFactory now accepts a bar_type parameter which
53
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
54
class UITests(TestCase):
55
56
    def test_silent_factory(self):
57
        ui = SilentUIFactory()
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
58
        stdout = StringIO()
59
        self.assertEqual(None,
60
                         self.apply_redirected(None, stdout, stdout,
61
                                               ui.get_password))
62
        self.assertEqual('', stdout.getvalue())
63
        self.assertEqual(None,
64
                         self.apply_redirected(None, stdout, stdout,
65
                                               ui.get_password,
66
                                               u'Hello\u1234 %(user)s',
67
                                               user=u'some\u1234'))
68
        self.assertEqual('', stdout.getvalue())
69
70
    def test_text_factory_ascii_password(self):
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
71
        ui = TestUIFactory(stdin='secret\n', stdout=StringIOWrapper(),
72
                           stderr=StringIOWrapper())
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
73
        pb = ui.nested_progress_bar()
74
        try:
75
            self.assertEqual('secret',
76
                             self.apply_redirected(ui.stdin, ui.stdout,
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
77
                                                   ui.stderr,
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
78
                                                   ui.get_password))
79
            # ': ' is appended to prompt
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
80
            self.assertEqual(': ', ui.stderr.getvalue())
81
            self.assertEqual('', ui.stdout.readline())
2363.4.3 by Vincent Ladeuil
Tidy-up tests.
82
            # stdin should be empty
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
83
            self.assertEqual('', ui.stdin.readline())
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
84
        finally:
85
            pb.finished()
86
87
    def test_text_factory_utf8_password(self):
88
        """Test an utf8 password.
89
90
        We can't predict what encoding users will have for stdin, so we force
91
        it to utf8 to test that we transport the password correctly.
92
        """
2294.4.4 by Vincent Ladeuil
Provide a better implementation for testing passwords.
93
        ui = TestUIFactory(stdin=u'baz\u1234'.encode('utf8'),
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
94
                           stdout=StringIOWrapper(),
95
                           stderr=StringIOWrapper())
96
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = 'utf8'
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
97
        pb = ui.nested_progress_bar()
98
        try:
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
99
            password = self.apply_redirected(ui.stdin, ui.stdout, ui.stderr,
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
100
                                             ui.get_password,
101
                                             u'Hello \u1234 %(user)s',
102
                                             user=u'some\u1234')
103
            # We use StringIO objects, we need to decode them
104
            self.assertEqual(u'baz\u1234', password.decode('utf8'))
105
            self.assertEqual(u'Hello \u1234 some\u1234: ',
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
106
                             ui.stderr.getvalue().decode('utf8'))
107
            # stdin and stdout should be empty
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
108
            self.assertEqual('', ui.stdin.readline())
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
109
            self.assertEqual('', ui.stdout.readline())
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
110
        finally:
111
            pb.finished()
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
112
4449.2.4 by Martin Pool
Add tests for BZR_PROGRESS_BAR
113
    def test_progress_construction(self):
114
        """TextUIFactory constructs the right progress view.
115
        """
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
116
        err = _TTYStringIO()
117
        os.environ['TERM'] = 'xterm'
4449.2.4 by Martin Pool
Add tests for BZR_PROGRESS_BAR
118
        os.environ['BZR_PROGRESS_BAR'] = 'none'
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
119
        self.assertIsInstance(TextUIFactory(stderr=err)._progress_view,
4449.2.4 by Martin Pool
Add tests for BZR_PROGRESS_BAR
120
            NullProgressView)
121
122
        os.environ['BZR_PROGRESS_BAR'] = 'text'
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
123
        self.assertIsInstance(TextUIFactory(stderr=err)._progress_view,
4449.2.4 by Martin Pool
Add tests for BZR_PROGRESS_BAR
124
            TextProgressView)
125
126
        os.environ['BZR_PROGRESS_BAR'] = 'text'
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
127
        self.assertIsInstance(TextUIFactory(stderr=err)._progress_view,
4449.2.4 by Martin Pool
Add tests for BZR_PROGRESS_BAR
128
            TextProgressView)
129
130
        del os.environ['BZR_PROGRESS_BAR']
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
131
        self.assertIsInstance(TextUIFactory(stderr=err)._progress_view,
4449.2.4 by Martin Pool
Add tests for BZR_PROGRESS_BAR
132
            TextProgressView)
133
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
134
        # if not a tty, no progress bars
135
        self.assertIsInstance(
136
            TextUIFactory(stderr=_NonTTYStringIO())._progress_view,
137
            NullProgressView)
138
139
        # if a tty but dumb, no progress bars
140
        os.environ['TERM'] = 'dumb'
141
        self.assertIsInstance(
142
            TextUIFactory(stderr=_TTYStringIO())._progress_view,
143
            NullProgressView)
144
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
145
    def test_progress_note(self):
146
        stderr = StringIO()
147
        stdout = StringIO()
3882.8.11 by Martin Pool
Choose the UIFactory class depending on the terminal capabilities
148
        ui_factory = TextUIFactory(stdin=StringIO(''),
149
            stderr=stderr,
150
            stdout=stdout)
1558.8.5 by Aaron Bentley
Pass note up the stack instead of using bzrlib.ui_factory
151
        pb = ui_factory.nested_progress_bar()
1558.8.4 by Aaron Bentley
Fixed test case for pb.note
152
        try:
153
            result = pb.note('t')
154
            self.assertEqual(None, result)
155
            self.assertEqual("t\n", stdout.getvalue())
1843.3.2 by John Arbash Meinel
Fix a ui test that depended on clearing
156
            # Since there was no update() call, there should be no clear() call
2363.4.4 by Vincent Ladeuil
More tidying-up.
157
            self.failIf(re.search(r'^\r {10,}\r$',
158
                                  stderr.getvalue()) is not None,
1843.3.2 by John Arbash Meinel
Fix a ui test that depended on clearing
159
                        'We cleared the stderr without anything to put there')
160
        finally:
161
            pb.finished()
162
163
    def test_progress_note_clears(self):
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
164
        stderr = _TTYStringIO()
165
        stdout = _TTYStringIO()
166
        # so that we get a TextProgressBar
167
        os.environ['TERM'] = 'xterm'
3882.8.8 by Martin Pool
Progress and UI test cleanups
168
        ui_factory = TextUIFactory(
3882.8.11 by Martin Pool
Choose the UIFactory class depending on the terminal capabilities
169
            stdin=StringIO(''),
3882.8.4 by Martin Pool
All UI factories should support note()
170
            stdout=stdout, stderr=stderr)
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
171
        self.assertIsInstance(ui_factory._progress_view,
172
            TextProgressView)
1843.3.2 by John Arbash Meinel
Fix a ui test that depended on clearing
173
        pb = ui_factory.nested_progress_bar()
174
        try:
175
            # Create a progress update that isn't throttled
176
            pb.update('x', 1, 1)
177
            result = pb.note('t')
178
            self.assertEqual(None, result)
179
            self.assertEqual("t\n", stdout.getvalue())
1558.8.4 by Aaron Bentley
Fixed test case for pb.note
180
            # the exact contents will depend on the terminal width and we don't
181
            # care about that right now - but you're probably running it on at
182
            # least a 10-character wide terminal :)
1843.3.2 by John Arbash Meinel
Fix a ui test that depended on clearing
183
            self.assertContainsRe(stderr.getvalue(), r'\r {10,}\r$')
1558.8.4 by Aaron Bentley
Fixed test case for pb.note
184
        finally:
1558.8.5 by Aaron Bentley
Pass note up the stack instead of using bzrlib.ui_factory
185
            pb.finished()
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
186
187
    def test_progress_nested(self):
188
        # test factory based nested and popping.
3882.8.11 by Martin Pool
Choose the UIFactory class depending on the terminal capabilities
189
        ui = TextUIFactory(None, None, None)
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
190
        pb1 = ui.nested_progress_bar()
191
        pb2 = ui.nested_progress_bar()
3948.2.2 by Martin Pool
Corrections to finishing progress bars
192
        # You do get a warning if the outermost progress bar wasn't finished
193
        # first - it's not clear if this is really useful or if it should just
194
        # become orphaned -- mbp 20090120
3882.8.12 by Martin Pool
Give a warning, not an error, if a progress bar is not finished in order
195
        warnings, _ = self.callCatchWarnings(pb1.finished)
3948.2.2 by Martin Pool
Corrections to finishing progress bars
196
        if len(warnings) != 1:
197
            self.fail("unexpected warnings: %r" % (warnings,))
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
198
        pb2.finished()
199
        pb1.finished()
200
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
201
    def assert_get_bool_acceptance_of_user_input(self, factory):
2363.4.4 by Vincent Ladeuil
More tidying-up.
202
        factory.stdin = StringIO("y\nyes with garbage\n"
203
                                 "yes\nn\nnot an answer\n"
204
                                 "no\nfoo\n")
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
205
        factory.stdout = StringIO()
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
206
        factory.stderr = StringIO()
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
207
        # there is no output from the base factory
208
        self.assertEqual(True, factory.get_boolean(""))
209
        self.assertEqual(True, factory.get_boolean(""))
210
        self.assertEqual(False, factory.get_boolean(""))
211
        self.assertEqual(False, factory.get_boolean(""))
212
        self.assertEqual("foo\n", factory.stdin.read())
2363.4.4 by Vincent Ladeuil
More tidying-up.
213
        # stdin should be empty
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
214
        self.assertEqual('', factory.stdin.readline())
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
215
216
    def test_silent_ui_getbool(self):
2363.4.10 by Vincent Ladeuil
Complete tests.
217
        factory = SilentUIFactory()
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
218
        self.assert_get_bool_acceptance_of_user_input(factory)
219
220
    def test_silent_factory_prompts_silently(self):
2363.4.10 by Vincent Ladeuil
Complete tests.
221
        factory = SilentUIFactory()
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
222
        stdout = StringIO()
223
        factory.stdin = StringIO("y\n")
2363.4.4 by Vincent Ladeuil
More tidying-up.
224
        self.assertEqual(True,
225
                         self.apply_redirected(None, stdout, stdout,
226
                                               factory.get_boolean, "foo"))
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
227
        self.assertEqual("", stdout.getvalue())
2363.4.4 by Vincent Ladeuil
More tidying-up.
228
        # stdin should be empty
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
229
        self.assertEqual('', factory.stdin.readline())
2363.4.4 by Vincent Ladeuil
More tidying-up.
230
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
231
    def test_text_ui_getbool(self):
3882.8.11 by Martin Pool
Choose the UIFactory class depending on the terminal capabilities
232
        factory = TextUIFactory(None, None, None)
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
233
        self.assert_get_bool_acceptance_of_user_input(factory)
234
4300.3.1 by Martin Pool
Fix string expansion in TextUIFactory.prompt
235
    def test_text_factory_prompt(self):
236
        # see <https://launchpad.net/bugs/365891>
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
237
        factory = TextUIFactory(None, StringIO(), StringIO(), StringIO())
4300.3.1 by Martin Pool
Fix string expansion in TextUIFactory.prompt
238
        factory.prompt('foo %2e')
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
239
        self.assertEqual('', factory.stdout.getvalue())
240
        self.assertEqual('foo %2e', factory.stderr.getvalue())
4300.3.1 by Martin Pool
Fix string expansion in TextUIFactory.prompt
241
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
242
    def test_text_factory_prompts_and_clears(self):
243
        # a get_boolean call should clear the pb before prompting
3882.8.10 by Martin Pool
Fix up test_ui for new progress bars
244
        out = _TTYStringIO()
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
245
        os.environ['TERM'] = 'xterm'
3882.8.11 by Martin Pool
Choose the UIFactory class depending on the terminal capabilities
246
        factory = TextUIFactory(stdin=StringIO("yada\ny\n"), stdout=out, stderr=out)
3882.8.10 by Martin Pool
Fix up test_ui for new progress bars
247
        pb = factory.nested_progress_bar()
248
        pb.show_bar = False
249
        pb.show_spinner = False
250
        pb.show_count = False
251
        pb.update("foo", 0, 1)
2363.4.4 by Vincent Ladeuil
More tidying-up.
252
        self.assertEqual(True,
253
                         self.apply_redirected(None, factory.stdout,
254
                                               factory.stdout,
255
                                               factory.get_boolean,
256
                                               "what do you want"))
3882.8.10 by Martin Pool
Fix up test_ui for new progress bars
257
        output = out.getvalue()
258
        self.assertContainsRe(factory.stdout.getvalue(),
259
            "foo *\r\r  *\r*")
260
        self.assertContainsRe(factory.stdout.getvalue(),
261
            r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
262
        # stdin should have been totally consumed
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
263
        self.assertEqual('', factory.stdin.readline())
4017.1.1 by John Arbash Meinel
Get a pb.tick() to work after calling pb.update()
264
265
    def test_text_tick_after_update(self):
266
        ui_factory = TextUIFactory(stdout=StringIO(), stderr=StringIO())
267
        pb = ui_factory.nested_progress_bar()
268
        try:
269
            pb.update('task', 0, 3)
270
            # Reset the clock, so that it actually tries to repaint itself
271
            ui_factory._progress_view._last_repaint = time.time() - 1.0
272
            pb.tick()
273
        finally:
274
            pb.finished()
4110.2.15 by Martin Pool
Fix bug in showing task progress and add a test
275
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
276
    def test_silent_ui_getusername(self):
277
        factory = SilentUIFactory()
278
        factory.stdin = StringIO("someuser\n\n")
279
        factory.stdout = StringIO()
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
280
        factory.stderr = StringIO()
281
        self.assertEquals(None,
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
282
            factory.get_username(u'Hello\u1234 %(host)s', host=u'some\u1234'))
283
        self.assertEquals("", factory.stdout.getvalue())
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
284
        self.assertEquals("", factory.stderr.getvalue())
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
285
        self.assertEquals("someuser\n\n", factory.stdin.getvalue())
286
287
    def test_text_ui_getusername(self):
288
        factory = TextUIFactory(None, None, None)
289
        factory.stdin = StringIO("someuser\n\n")
290
        factory.stdout = StringIO()
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
291
        factory.stderr = StringIO()
4222.2.6 by Jelmer Vernooij
Remove use of NotATerminal.
292
        factory.stdout.encoding = "utf8"
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
293
        # there is no output from the base factory
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
294
        self.assertEqual("someuser",
295
                         factory.get_username('Hello %(host)s', host='some'))
296
        self.assertEquals("Hello some: ", factory.stderr.getvalue())
297
        self.assertEquals('', factory.stdout.getvalue())
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
298
        self.assertEqual("", factory.get_username("Gebruiker"))
299
        # stdin should be empty
300
        self.assertEqual('', factory.stdin.readline())
301
4222.2.2 by Jelmer Vernooij
Review from vila: Deal with UTF8 strings in prompts, fix typo.
302
    def test_text_ui_getusername_utf8(self):
4222.2.3 by Jelmer Vernooij
Also check for unicode usernames.
303
        ui = TestUIFactory(stdin=u'someuser\u1234'.encode('utf8'),
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
304
                           stdout=StringIOWrapper(), stderr=StringIOWrapper())
305
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = "utf8"
4222.2.3 by Jelmer Vernooij
Also check for unicode usernames.
306
        pb = ui.nested_progress_bar()
307
        try:
308
            # there is no output from the base factory
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
309
            username = self.apply_redirected(ui.stdin, ui.stdout, ui.stderr,
4222.2.12 by Jelmer Vernooij
Redirect to fix utf8 test with LC_ALL=C.
310
                ui.get_username, u'Hello\u1234 %(host)s', host=u'some\u1234')
4222.2.8 by Jelmer Vernooij
Fix copy-n-paste error.
311
            self.assertEquals(u"someuser\u1234", username.decode('utf8'))
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
312
            self.assertEquals(u"Hello\u1234 some\u1234: ",
313
                              ui.stderr.getvalue().decode("utf8"))
314
            self.assertEquals('', ui.stdout.getvalue())
4222.2.3 by Jelmer Vernooij
Also check for unicode usernames.
315
        finally:
316
            pb.finished()
4222.2.2 by Jelmer Vernooij
Review from vila: Deal with UTF8 strings in prompts, fix typo.
317
4110.2.15 by Martin Pool
Fix bug in showing task progress and add a test
318