~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_osutils.py

  • Committer: Patch Queue Manager
  • Date: 2014-09-22 19:42:30 UTC
  • mfrom: (6597.2.1 bzr)
  • Revision ID: pqm@pqm.ubuntu.com-20140922194230-y32j0sq621bxhp7c
(richard-wilbur) Split diff format option parser into a separate function,
 update to include all format options for GNU diff v3.2,
 and test parser.  Fixes lp:1370435 (Richard Wilbur)

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import errno
21
21
import os
22
22
import re
 
23
import select
23
24
import socket
24
25
import sys
 
26
import tempfile
25
27
import time
26
28
 
27
29
from bzrlib import (
41
43
from bzrlib.tests.scenarios import load_tests_apply_scenarios
42
44
 
43
45
 
44
 
class _UTF8DirReaderFeature(tests.Feature):
 
46
class _UTF8DirReaderFeature(features.Feature):
45
47
 
46
48
    def _probe(self):
47
49
        try:
54
56
    def feature_name(self):
55
57
        return 'bzrlib._readdir_pyx'
56
58
 
57
 
UTF8DirReaderFeature = _UTF8DirReaderFeature()
 
59
UTF8DirReaderFeature = features.ModuleAvailableFeature('bzrlib._readdir_pyx')
58
60
 
59
 
term_ios_feature = tests.ModuleAvailableFeature('termios')
 
61
term_ios_feature = features.ModuleAvailableFeature('termios')
60
62
 
61
63
 
62
64
def _already_unicode(s):
180
182
        shape = sorted(os.listdir('.'))
181
183
        self.assertEquals(['A', 'B'], shape)
182
184
 
 
185
    def test_rename_exception(self):
 
186
        try:
 
187
            osutils.rename('nonexistent_path', 'different_nonexistent_path')
 
188
        except OSError, e:
 
189
            self.assertEqual(e.old_filename, 'nonexistent_path')
 
190
            self.assertEqual(e.new_filename, 'different_nonexistent_path')
 
191
            self.assertTrue('nonexistent_path' in e.strerror)
 
192
            self.assertTrue('different_nonexistent_path' in e.strerror)
 
193
 
183
194
 
184
195
class TestRandChars(tests.TestCase):
185
196
 
426
437
        self.assertTrue(-eighteen_hours < offset < eighteen_hours)
427
438
 
428
439
 
 
440
class TestFdatasync(tests.TestCaseInTempDir):
 
441
 
 
442
    def do_fdatasync(self):
 
443
        f = tempfile.NamedTemporaryFile()
 
444
        osutils.fdatasync(f.fileno())
 
445
        f.close()
 
446
 
 
447
    @staticmethod
 
448
    def raise_eopnotsupp(*args, **kwargs):
 
449
        raise IOError(errno.EOPNOTSUPP, os.strerror(errno.EOPNOTSUPP))
 
450
 
 
451
    @staticmethod
 
452
    def raise_enotsup(*args, **kwargs):
 
453
        raise IOError(errno.ENOTSUP, os.strerror(errno.ENOTSUP))
 
454
 
 
455
    def test_fdatasync_handles_system_function(self):
 
456
        self.overrideAttr(os, "fdatasync")
 
457
        self.do_fdatasync()
 
458
 
 
459
    def test_fdatasync_handles_no_fdatasync_no_fsync(self):
 
460
        self.overrideAttr(os, "fdatasync")
 
461
        self.overrideAttr(os, "fsync")
 
462
        self.do_fdatasync()
 
463
 
 
464
    def test_fdatasync_handles_no_EOPNOTSUPP(self):
 
465
        self.overrideAttr(errno, "EOPNOTSUPP")
 
466
        self.do_fdatasync()
 
467
 
 
468
    def test_fdatasync_catches_ENOTSUP(self):
 
469
        enotsup = getattr(errno, "ENOTSUP", None)
 
470
        if enotsup is None:
 
471
            raise tests.TestNotApplicable("No ENOTSUP on this platform")
 
472
        self.overrideAttr(os, "fdatasync", self.raise_enotsup)
 
473
        self.do_fdatasync()
 
474
 
 
475
    def test_fdatasync_catches_EOPNOTSUPP(self):
 
476
        enotsup = getattr(errno, "EOPNOTSUPP", None)
 
477
        if enotsup is None:
 
478
            raise tests.TestNotApplicable("No EOPNOTSUPP on this platform")
 
479
        self.overrideAttr(os, "fdatasync", self.raise_eopnotsupp)
 
480
        self.do_fdatasync()
 
481
 
 
482
 
429
483
class TestLinks(tests.TestCaseInTempDir):
430
484
 
431
485
    def test_dereference_path(self):
432
 
        self.requireFeature(tests.SymlinkFeature)
 
486
        self.requireFeature(features.SymlinkFeature)
433
487
        cwd = osutils.realpath('.')
434
488
        os.mkdir('bar')
435
489
        bar_path = osutils.pathjoin(cwd, 'bar')
482
536
 
483
537
class TestCanonicalRelPath(tests.TestCaseInTempDir):
484
538
 
485
 
    _test_needs_features = [tests.CaseInsCasePresFilenameFeature]
 
539
    _test_needs_features = [features.CaseInsCasePresFilenameFeature]
486
540
 
487
541
    def test_canonical_relpath_simple(self):
488
542
        f = file('MixedCaseName', 'w')
544
598
    """Test pumpfile method."""
545
599
 
546
600
    def setUp(self):
547
 
        tests.TestCase.setUp(self)
 
601
        super(TestPumpFile, self).setUp()
548
602
        # create a test datablock
549
603
        self.block_size = 512
550
604
        pattern = '0123456789ABCDEF'
818
872
        self.assertEqual(None, osutils.safe_file_id(None))
819
873
 
820
874
 
 
875
class TestSendAll(tests.TestCase):
 
876
 
 
877
    def test_send_with_disconnected_socket(self):
 
878
        class DisconnectedSocket(object):
 
879
            def __init__(self, err):
 
880
                self.err = err
 
881
            def send(self, content):
 
882
                raise self.err
 
883
            def close(self):
 
884
                pass
 
885
        # All of these should be treated as ConnectionReset
 
886
        errs = []
 
887
        for err_cls in (IOError, socket.error):
 
888
            for errnum in osutils._end_of_stream_errors:
 
889
                errs.append(err_cls(errnum))
 
890
        for err in errs:
 
891
            sock = DisconnectedSocket(err)
 
892
            self.assertRaises(errors.ConnectionReset,
 
893
                osutils.send_all, sock, 'some more content')
 
894
 
 
895
    def test_send_with_no_progress(self):
 
896
        # See https://bugs.launchpad.net/bzr/+bug/1047309
 
897
        # It seems that paramiko can get into a state where it doesn't error,
 
898
        # but it returns 0 bytes sent for requests over and over again.
 
899
        class NoSendingSocket(object):
 
900
            def __init__(self):
 
901
                self.call_count = 0
 
902
            def send(self, bytes):
 
903
                self.call_count += 1
 
904
                if self.call_count > 100:
 
905
                    # Prevent the test suite from hanging
 
906
                    raise RuntimeError('too many calls')
 
907
                return 0
 
908
        sock = NoSendingSocket()
 
909
        self.assertRaises(errors.ConnectionReset,
 
910
                          osutils.send_all, sock, 'content')
 
911
        self.assertEqual(1, sock.call_count)
 
912
 
 
913
 
 
914
class TestPosixFuncs(tests.TestCase):
 
915
    """Test that the posix version of normpath returns an appropriate path
 
916
       when used with 2 leading slashes."""
 
917
 
 
918
    def test_normpath(self):
 
919
        self.assertEqual('/etc/shadow', osutils._posix_normpath('/etc/shadow'))
 
920
        self.assertEqual('/etc/shadow', osutils._posix_normpath('//etc/shadow'))
 
921
        self.assertEqual('/etc/shadow', osutils._posix_normpath('///etc/shadow'))
 
922
 
 
923
 
821
924
class TestWin32Funcs(tests.TestCase):
822
925
    """Test that _win32 versions of os utilities return appropriate paths."""
823
926
 
840
943
                         osutils._win32_pathjoin('path/to', 'C:/foo'))
841
944
        self.assertEqual('path/to/foo',
842
945
                         osutils._win32_pathjoin('path/to/', 'foo'))
843
 
        self.assertEqual('/foo',
 
946
 
 
947
    def test_pathjoin_late_bugfix(self):
 
948
        if sys.version_info < (2, 7, 6):
 
949
            expected = '/foo'
 
950
        else:
 
951
            expected = 'C:/foo'
 
952
        self.assertEqual(expected,
844
953
                         osutils._win32_pathjoin('C:/path/to/', '/foo'))
845
 
        self.assertEqual('/foo',
 
954
        self.assertEqual(expected,
846
955
                         osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
847
956
 
848
957
    def test_normpath(self):
888
997
    """Test win32 functions that create files."""
889
998
 
890
999
    def test_getcwd(self):
891
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1000
        self.requireFeature(features.UnicodeFilenameFeature)
892
1001
        os.mkdir(u'mu-\xb5')
893
1002
        os.chdir(u'mu-\xb5')
894
1003
        # TODO: jam 20060427 This will probably fail on Mac OSX because
984
1093
    """Test mac special functions that require directories."""
985
1094
 
986
1095
    def test_getcwd(self):
987
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1096
        self.requireFeature(features.UnicodeFilenameFeature)
988
1097
        os.mkdir(u'B\xe5gfors')
989
1098
        os.chdir(u'B\xe5gfors')
990
1099
        self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
991
1100
 
992
1101
    def test_getcwd_nonnorm(self):
993
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1102
        self.requireFeature(features.UnicodeFilenameFeature)
994
1103
        # Test that _mac_getcwd() will normalize this path
995
1104
        os.mkdir(u'Ba\u030agfors')
996
1105
        os.chdir(u'Ba\u030agfors')
1106
1215
        # are not using the filesystem's encoding
1107
1216
 
1108
1217
        # require a bytestring based filesystem
1109
 
        self.requireFeature(tests.ByteStringNamedFilesystem)
 
1218
        self.requireFeature(features.ByteStringNamedFilesystem)
1110
1219
 
1111
1220
        tree = [
1112
1221
            '.bzr',
1206
1315
        self.requireFeature(UTF8DirReaderFeature)
1207
1316
        self._save_platform_info()
1208
1317
        win32utils.winver = None # Avoid the win32 detection code
1209
 
        osutils._fs_enc = 'UTF-8'
1210
 
        self.assertDirReaderIs(UTF8DirReaderFeature.reader)
 
1318
        osutils._fs_enc = 'utf-8'
 
1319
        self.assertDirReaderIs(
 
1320
            UTF8DirReaderFeature.module.UTF8DirReader)
1211
1321
 
1212
1322
    def test_force_walkdirs_utf8_fs_ascii(self):
1213
1323
        self.requireFeature(UTF8DirReaderFeature)
1214
1324
        self._save_platform_info()
1215
1325
        win32utils.winver = None # Avoid the win32 detection code
1216
 
        osutils._fs_enc = 'US-ASCII'
1217
 
        self.assertDirReaderIs(UTF8DirReaderFeature.reader)
1218
 
 
1219
 
    def test_force_walkdirs_utf8_fs_ANSI(self):
1220
 
        self.requireFeature(UTF8DirReaderFeature)
1221
 
        self._save_platform_info()
1222
 
        win32utils.winver = None # Avoid the win32 detection code
1223
 
        osutils._fs_enc = 'ANSI_X3.4-1968'
1224
 
        self.assertDirReaderIs(UTF8DirReaderFeature.reader)
 
1326
        osutils._fs_enc = 'ascii'
 
1327
        self.assertDirReaderIs(
 
1328
            UTF8DirReaderFeature.module.UTF8DirReader)
1225
1329
 
1226
1330
    def test_force_walkdirs_utf8_fs_latin1(self):
1227
1331
        self._save_platform_info()
1228
1332
        win32utils.winver = None # Avoid the win32 detection code
1229
 
        osutils._fs_enc = 'latin1'
 
1333
        osutils._fs_enc = 'iso-8859-1'
1230
1334
        self.assertDirReaderIs(osutils.UnicodeDirReader)
1231
1335
 
1232
1336
    def test_force_walkdirs_utf8_nt(self):
1245
1349
 
1246
1350
    def test_unicode_walkdirs(self):
1247
1351
        """Walkdirs should always return unicode paths."""
1248
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1352
        self.requireFeature(features.UnicodeFilenameFeature)
1249
1353
        name0 = u'0file-\xb6'
1250
1354
        name1 = u'1dir-\u062c\u0648'
1251
1355
        name2 = u'2file-\u0633'
1288
1392
 
1289
1393
        The abspath portion might be in unicode or utf-8
1290
1394
        """
1291
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1395
        self.requireFeature(features.UnicodeFilenameFeature)
1292
1396
        name0 = u'0file-\xb6'
1293
1397
        name1 = u'1dir-\u062c\u0648'
1294
1398
        name2 = u'2file-\u0633'
1349
1453
 
1350
1454
        The abspath portion should be in unicode
1351
1455
        """
1352
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1456
        self.requireFeature(features.UnicodeFilenameFeature)
1353
1457
        # Use the unicode reader. TODO: split into driver-and-driven unit
1354
1458
        # tests.
1355
1459
        self._save_platform_info()
1396
1500
 
1397
1501
    def test__walkdirs_utf8_win32readdir(self):
1398
1502
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
1399
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1503
        self.requireFeature(features.UnicodeFilenameFeature)
1400
1504
        from bzrlib._walkdirs_win32 import Win32ReadDir
1401
1505
        self._save_platform_info()
1402
1506
        osutils._selected_dir_reader = Win32ReadDir()
1453
1557
    def test__walkdirs_utf_win32_find_file_stat_file(self):
1454
1558
        """make sure our Stat values are valid"""
1455
1559
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
1456
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1560
        self.requireFeature(features.UnicodeFilenameFeature)
1457
1561
        from bzrlib._walkdirs_win32 import Win32ReadDir
1458
1562
        name0u = u'0file-\xb6'
1459
1563
        name0 = name0u.encode('utf8')
1477
1581
    def test__walkdirs_utf_win32_find_file_stat_directory(self):
1478
1582
        """make sure our Stat values are valid"""
1479
1583
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
1480
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1584
        self.requireFeature(features.UnicodeFilenameFeature)
1481
1585
        from bzrlib._walkdirs_win32 import Win32ReadDir
1482
1586
        name0u = u'0dir-\u062c\u0648'
1483
1587
        name0 = name0u.encode('utf8')
1583
1687
        self.assertEqual(['c'], os.listdir('target/b'))
1584
1688
 
1585
1689
    def test_copy_tree_symlinks(self):
1586
 
        self.requireFeature(tests.SymlinkFeature)
 
1690
        self.requireFeature(features.SymlinkFeature)
1587
1691
        self.build_tree(['source/'])
1588
1692
        os.symlink('a/generic/path', 'source/lnk')
1589
1693
        osutils.copy_tree('source', 'target')
1756
1860
    _native_to_unicode = None
1757
1861
 
1758
1862
    def setUp(self):
1759
 
        tests.TestCaseInTempDir.setUp(self)
 
1863
        super(TestDirReader, self).setUp()
1760
1864
        self.overrideAttr(osutils,
1761
1865
                          '_selected_dir_reader', self._dir_reader_class())
1762
1866
 
1856
1960
        return filtered_dirblocks
1857
1961
 
1858
1962
    def test_walk_unicode_tree(self):
1859
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1963
        self.requireFeature(features.UnicodeFilenameFeature)
1860
1964
        tree, expected_dirblocks = self._get_unicode_tree()
1861
1965
        self.build_tree(tree)
1862
1966
        result = list(osutils._walkdirs_utf8('.'))
1863
1967
        self.assertEqual(expected_dirblocks, self._filter_out(result))
1864
1968
 
1865
1969
    def test_symlink(self):
1866
 
        self.requireFeature(tests.SymlinkFeature)
1867
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1970
        self.requireFeature(features.SymlinkFeature)
 
1971
        self.requireFeature(features.UnicodeFilenameFeature)
1868
1972
        target = u'target\N{Euro Sign}'
1869
1973
        link_name = u'l\N{Euro Sign}nk'
1870
1974
        os.symlink(target, link_name)
1888
1992
    But prior python versions failed to properly encode the passed unicode
1889
1993
    string.
1890
1994
    """
1891
 
    _test_needs_features = [tests.SymlinkFeature, tests.UnicodeFilenameFeature]
 
1995
    _test_needs_features = [features.SymlinkFeature, features.UnicodeFilenameFeature]
1892
1996
 
1893
1997
    def setUp(self):
1894
1998
        super(tests.TestCaseInTempDir, self).setUp()
1970
2074
class TestTerminalWidth(tests.TestCase):
1971
2075
 
1972
2076
    def setUp(self):
1973
 
        tests.TestCase.setUp(self)
 
2077
        super(TestTerminalWidth, self).setUp()
1974
2078
        self._orig_terminal_size_state = osutils._terminal_size_state
1975
2079
        self._orig_first_terminal_size = osutils._first_terminal_size
1976
2080
        self.addCleanup(self.restore_osutils_globals)
2057
2161
    _test_needs_features = [features.chown_feature]
2058
2162
 
2059
2163
    def setUp(self):
2060
 
        tests.TestCaseInTempDir.setUp(self)
 
2164
        super(TestCreationOps, self).setUp()
2061
2165
        self.overrideAttr(os, 'chown', self._dummy_chown)
2062
2166
 
2063
2167
        # params set by call to _dummy_chown
2089
2193
        self.assertEquals(self.gid, s.st_gid)
2090
2194
 
2091
2195
 
 
2196
class TestPathFromEnviron(tests.TestCase):
 
2197
 
 
2198
    def test_is_unicode(self):
 
2199
        self.overrideEnv('BZR_TEST_PATH', './anywhere at all/')
 
2200
        path = osutils.path_from_environ('BZR_TEST_PATH')
 
2201
        self.assertIsInstance(path, unicode)
 
2202
        self.assertEqual(u'./anywhere at all/', path)
 
2203
 
 
2204
    def test_posix_path_env_ascii(self):
 
2205
        self.overrideEnv('BZR_TEST_PATH', '/tmp')
 
2206
        home = osutils._posix_path_from_environ('BZR_TEST_PATH')
 
2207
        self.assertIsInstance(home, unicode)
 
2208
        self.assertEqual(u'/tmp', home)
 
2209
 
 
2210
    def test_posix_path_env_unicode(self):
 
2211
        self.requireFeature(features.ByteStringNamedFilesystem)
 
2212
        self.overrideEnv('BZR_TEST_PATH', '/home/\xa7test')
 
2213
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
 
2214
        self.assertEqual(u'/home/\xa7test',
 
2215
            osutils._posix_path_from_environ('BZR_TEST_PATH'))
 
2216
        osutils._fs_enc = "iso8859-5"
 
2217
        self.assertEqual(u'/home/\u0407test',
 
2218
            osutils._posix_path_from_environ('BZR_TEST_PATH'))
 
2219
        osutils._fs_enc = "utf-8"
 
2220
        self.assertRaises(errors.BadFilenameEncoding,
 
2221
            osutils._posix_path_from_environ, 'BZR_TEST_PATH')
 
2222
 
 
2223
 
 
2224
class TestGetHomeDir(tests.TestCase):
 
2225
 
 
2226
    def test_is_unicode(self):
 
2227
        home = osutils._get_home_dir()
 
2228
        self.assertIsInstance(home, unicode)
 
2229
 
 
2230
    def test_posix_homeless(self):
 
2231
        self.overrideEnv('HOME', None)
 
2232
        home = osutils._get_home_dir()
 
2233
        self.assertIsInstance(home, unicode)
 
2234
 
 
2235
    def test_posix_home_ascii(self):
 
2236
        self.overrideEnv('HOME', '/home/test')
 
2237
        home = osutils._posix_get_home_dir()
 
2238
        self.assertIsInstance(home, unicode)
 
2239
        self.assertEqual(u'/home/test', home)
 
2240
 
 
2241
    def test_posix_home_unicode(self):
 
2242
        self.requireFeature(features.ByteStringNamedFilesystem)
 
2243
        self.overrideEnv('HOME', '/home/\xa7test')
 
2244
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
 
2245
        self.assertEqual(u'/home/\xa7test', osutils._posix_get_home_dir())
 
2246
        osutils._fs_enc = "iso8859-5"
 
2247
        self.assertEqual(u'/home/\u0407test', osutils._posix_get_home_dir())
 
2248
        osutils._fs_enc = "utf-8"
 
2249
        self.assertRaises(errors.BadFilenameEncoding,
 
2250
            osutils._posix_get_home_dir)
 
2251
 
 
2252
 
2092
2253
class TestGetuserUnicode(tests.TestCase):
2093
2254
 
 
2255
    def test_is_unicode(self):
 
2256
        user = osutils.getuser_unicode()
 
2257
        self.assertIsInstance(user, unicode)
 
2258
 
 
2259
    def envvar_to_override(self):
 
2260
        if sys.platform == "win32":
 
2261
            # Disable use of platform calls on windows so envvar is used
 
2262
            self.overrideAttr(win32utils, 'has_ctypes', False)
 
2263
            return 'USERNAME' # only variable used on windows
 
2264
        return 'LOGNAME' # first variable checked by getpass.getuser()
 
2265
 
2094
2266
    def test_ascii_user(self):
2095
 
        self.overrideEnv('LOGNAME', 'jrandom')
 
2267
        self.overrideEnv(self.envvar_to_override(), 'jrandom')
2096
2268
        self.assertEqual(u'jrandom', osutils.getuser_unicode())
2097
2269
 
2098
2270
    def test_unicode_user(self):
2104
2276
                % (osutils.get_user_encoding(),))
2105
2277
        uni_username = u'jrandom' + uni_val
2106
2278
        encoded_username = uni_username.encode(ue)
2107
 
        self.overrideEnv('LOGNAME', encoded_username)
 
2279
        self.overrideEnv(self.envvar_to_override(), encoded_username)
2108
2280
        self.assertEqual(uni_username, osutils.getuser_unicode())
2109
 
        self.overrideEnv('LOGNAME', u'jrandom\xb6'.encode(ue))
2110
 
        self.assertEqual(u'jrandom\xb6', osutils.getuser_unicode())
2111
 
 
2112
 
    def test_no_username_bug_660174(self):
2113
 
        self.requireFeature(features.win32_feature)
2114
 
        for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
2115
 
            self.overrideEnv(name, None)
2116
 
        self.assertEqual(u'UNKNOWN', osutils.getuser_unicode())
2117
2281
 
2118
2282
 
2119
2283
class TestBackupNames(tests.TestCase):
2159
2323
        self.assertTrue(
2160
2324
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
2161
2325
        self.assertTrue(osutils.find_executable_on_path('file.txt') is None)
 
2326
        
 
2327
    def test_windows_app_path(self):
 
2328
        if sys.platform != 'win32':
 
2329
            raise tests.TestSkipped('test requires win32')
 
2330
        # Override PATH env var so that exe can only be found on App Path
 
2331
        self.overrideEnv('PATH', '')
 
2332
        # Internt Explorer is always registered in the App Path
 
2333
        self.assertTrue(osutils.find_executable_on_path('iexplore') is not None)
2162
2334
 
2163
2335
    def test_other(self):
2164
2336
        if sys.platform == 'win32':
2166
2338
        self.assertTrue(osutils.find_executable_on_path('sh') is not None)
2167
2339
        self.assertTrue(
2168
2340
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
 
2341
 
 
2342
 
 
2343
class TestEnvironmentErrors(tests.TestCase):
 
2344
    """Test handling of environmental errors"""
 
2345
 
 
2346
    def test_is_oserror(self):
 
2347
        self.assertTrue(osutils.is_environment_error(
 
2348
            OSError(errno.EINVAL, "Invalid parameter")))
 
2349
 
 
2350
    def test_is_ioerror(self):
 
2351
        self.assertTrue(osutils.is_environment_error(
 
2352
            IOError(errno.EINVAL, "Invalid parameter")))
 
2353
 
 
2354
    def test_is_socket_error(self):
 
2355
        self.assertTrue(osutils.is_environment_error(
 
2356
            socket.error(errno.EINVAL, "Invalid parameter")))
 
2357
 
 
2358
    def test_is_select_error(self):
 
2359
        self.assertTrue(osutils.is_environment_error(
 
2360
            select.error(errno.EINVAL, "Invalid parameter")))
 
2361
 
 
2362
    def test_is_pywintypes_error(self):
 
2363
        self.requireFeature(features.pywintypes)
 
2364
        import pywintypes
 
2365
        self.assertTrue(osutils.is_environment_error(
 
2366
            pywintypes.error(errno.EINVAL, "Invalid parameter", "Caller")))