~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: 2016-02-01 19:13:13 UTC
  • mfrom: (6614.2.2 trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20160201191313-wdfvmfff1djde6oq
(vila) Release 2.7.0 (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2016 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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 (
178
180
        # we can't use failUnlessExists on case-insensitive filesystem
179
181
        # so try to check shape of the tree
180
182
        shape = sorted(os.listdir('.'))
181
 
        self.assertEquals(['A', 'B'], shape)
 
183
        self.assertEqual(['A', 'B'], shape)
 
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)
182
193
 
183
194
 
184
195
class TestRandChars(tests.TestCase):
211
222
                         (['src'], SRC_FOO_C),
212
223
                         (['src'], 'src'),
213
224
                         ]:
214
 
            self.assert_(osutils.is_inside_any(dirs, fn))
 
225
            self.assertTrue(osutils.is_inside_any(dirs, fn))
215
226
        for dirs, fn in [(['src'], 'srccontrol'),
216
227
                         (['src'], 'srccontrol/foo')]:
217
228
            self.assertFalse(osutils.is_inside_any(dirs, fn))
223
234
                         (['src/bar.c', 'bla/foo.c'], 'src'),
224
235
                         (['src'], 'src'),
225
236
                         ]:
226
 
            self.assert_(osutils.is_inside_or_parent_of_any(dirs, fn))
 
237
            self.assertTrue(osutils.is_inside_or_parent_of_any(dirs, fn))
227
238
 
228
239
        for dirs, fn in [(['src'], 'srccontrol'),
229
240
                         (['srccontrol/foo.c'], 'src'),
287
298
 
288
299
    def test_file_kind(self):
289
300
        self.build_tree(['file', 'dir/'])
290
 
        self.assertEquals('file', osutils.file_kind('file'))
291
 
        self.assertEquals('directory', osutils.file_kind('dir/'))
 
301
        self.assertEqual('file', osutils.file_kind('file'))
 
302
        self.assertEqual('directory', osutils.file_kind('dir/'))
292
303
        if osutils.has_symlinks():
293
304
            os.symlink('symlink', 'symlink')
294
 
            self.assertEquals('symlink', osutils.file_kind('symlink'))
 
305
            self.assertEqual('symlink', osutils.file_kind('symlink'))
295
306
 
296
307
        # TODO: jam 20060529 Test a block device
297
308
        try:
300
311
            if e.errno not in (errno.ENOENT,):
301
312
                raise
302
313
        else:
303
 
            self.assertEquals('chardev', osutils.file_kind('/dev/null'))
 
314
            self.assertEqual('chardev', osutils.file_kind('/dev/null'))
304
315
 
305
316
        mkfifo = getattr(os, 'mkfifo', None)
306
317
        if mkfifo:
307
318
            mkfifo('fifo')
308
319
            try:
309
 
                self.assertEquals('fifo', osutils.file_kind('fifo'))
 
320
                self.assertEqual('fifo', osutils.file_kind('fifo'))
310
321
            finally:
311
322
                os.remove('fifo')
312
323
 
315
326
            s = socket.socket(AF_UNIX)
316
327
            s.bind('socket')
317
328
            try:
318
 
                self.assertEquals('socket', osutils.file_kind('socket'))
 
329
                self.assertEqual('socket', osutils.file_kind('socket'))
319
330
            finally:
320
331
                os.remove('socket')
321
332
 
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):
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
 
821
914
class TestPosixFuncs(tests.TestCase):
822
915
    """Test that the posix version of normpath returns an appropriate path
823
916
       when used with 2 leading slashes."""
832
925
    """Test that _win32 versions of os utilities return appropriate paths."""
833
926
 
834
927
    def test_abspath(self):
 
928
        self.requireFeature(features.win32_feature)
835
929
        self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
836
930
        self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
837
931
        self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
850
944
                         osutils._win32_pathjoin('path/to', 'C:/foo'))
851
945
        self.assertEqual('path/to/foo',
852
946
                         osutils._win32_pathjoin('path/to/', 'foo'))
853
 
        self.assertEqual('/foo',
 
947
 
 
948
    def test_pathjoin_late_bugfix(self):
 
949
        if sys.version_info < (2, 7, 6):
 
950
            expected = '/foo'
 
951
        else:
 
952
            expected = 'C:/foo'
 
953
        self.assertEqual(expected,
854
954
                         osutils._win32_pathjoin('C:/path/to/', '/foo'))
855
 
        self.assertEqual('/foo',
 
955
        self.assertEqual(expected,
856
956
                         osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
857
957
 
858
958
    def test_normpath(self):
878
978
        self.assertEqual('C:\\foo', osutils._win32_fixdrive('c:\\foo'))
879
979
 
880
980
    def test_win98_abspath(self):
 
981
        self.requireFeature(features.win32_feature)
881
982
        # absolute path
882
983
        self.assertEqual('C:/foo', osutils._win98_abspath('C:\\foo'))
883
984
        self.assertEqual('C:/foo', osutils._win98_abspath('C:/foo'))
1104
1205
        # (It would be ok if it happened earlier but at the moment it
1105
1206
        # doesn't.)
1106
1207
        e = self.assertRaises(OSError, list, osutils._walkdirs_utf8("."))
1107
 
        self.assertEquals('./test-unreadable', e.filename)
1108
 
        self.assertEquals(errno.EACCES, e.errno)
 
1208
        self.assertEqual('./test-unreadable', e.filename)
 
1209
        self.assertEqual(errno.EACCES, e.errno)
1109
1210
        # Ensure the message contains the file name
1110
1211
        self.assertContainsRe(str(e), "\./test-unreadable")
1111
1212
 
1216
1317
        self.requireFeature(UTF8DirReaderFeature)
1217
1318
        self._save_platform_info()
1218
1319
        win32utils.winver = None # Avoid the win32 detection code
1219
 
        osutils._fs_enc = 'UTF-8'
 
1320
        osutils._fs_enc = 'utf-8'
1220
1321
        self.assertDirReaderIs(
1221
1322
            UTF8DirReaderFeature.module.UTF8DirReader)
1222
1323
 
1224
1325
        self.requireFeature(UTF8DirReaderFeature)
1225
1326
        self._save_platform_info()
1226
1327
        win32utils.winver = None # Avoid the win32 detection code
1227
 
        osutils._fs_enc = 'US-ASCII'
1228
 
        self.assertDirReaderIs(
1229
 
            UTF8DirReaderFeature.module.UTF8DirReader)
1230
 
 
1231
 
    def test_force_walkdirs_utf8_fs_ANSI(self):
1232
 
        self.requireFeature(UTF8DirReaderFeature)
1233
 
        self._save_platform_info()
1234
 
        win32utils.winver = None # Avoid the win32 detection code
1235
 
        osutils._fs_enc = 'ANSI_X3.4-1968'
 
1328
        osutils._fs_enc = 'ascii'
1236
1329
        self.assertDirReaderIs(
1237
1330
            UTF8DirReaderFeature.module.UTF8DirReader)
1238
1331
 
1239
1332
    def test_force_walkdirs_utf8_fs_latin1(self):
1240
1333
        self._save_platform_info()
1241
1334
        win32utils.winver = None # Avoid the win32 detection code
1242
 
        osutils._fs_enc = 'latin1'
 
1335
        osutils._fs_enc = 'iso-8859-1'
1243
1336
        self.assertDirReaderIs(osutils.UnicodeDirReader)
1244
1337
 
1245
1338
    def test_force_walkdirs_utf8_nt(self):
1769
1862
    _native_to_unicode = None
1770
1863
 
1771
1864
    def setUp(self):
1772
 
        tests.TestCaseInTempDir.setUp(self)
 
1865
        super(TestDirReader, self).setUp()
1773
1866
        self.overrideAttr(osutils,
1774
1867
                          '_selected_dir_reader', self._dir_reader_class())
1775
1868
 
1910
2003
        os.symlink(self.target, self.link)
1911
2004
 
1912
2005
    def test_os_readlink_link_encoding(self):
1913
 
        self.assertEquals(self.target,  os.readlink(self.link))
 
2006
        self.assertEqual(self.target,  os.readlink(self.link))
1914
2007
 
1915
2008
    def test_os_readlink_link_decoding(self):
1916
 
        self.assertEquals(self.target.encode(osutils._fs_enc),
 
2009
        self.assertEqual(self.target.encode(osutils._fs_enc),
1917
2010
                          os.readlink(self.link.encode(osutils._fs_enc)))
1918
2011
 
1919
2012
 
1939
2032
        self.overrideEnv('BZR_CONCURRENCY', '1')
1940
2033
        self.run_bzr('rocks --concurrency 42')
1941
2034
        # Command line overrides environment variable
1942
 
        self.assertEquals('42', os.environ['BZR_CONCURRENCY'])
1943
 
        self.assertEquals(42, osutils.local_concurrency(use_cache=False))
 
2035
        self.assertEqual('42', os.environ['BZR_CONCURRENCY'])
 
2036
        self.assertEqual(42, osutils.local_concurrency(use_cache=False))
1944
2037
 
1945
2038
 
1946
2039
class TestFailedToLoadExtension(tests.TestCase):
1959
2052
    def test_failure_to_load(self):
1960
2053
        self._try_loading()
1961
2054
        self.assertLength(1, osutils._extension_load_failures)
1962
 
        self.assertEquals(osutils._extension_load_failures[0],
 
2055
        self.assertEqual(osutils._extension_load_failures[0],
1963
2056
            "No module named _fictional_extension_py")
1964
2057
 
1965
2058
    def test_report_extension_load_failures_no_warning(self):
1983
2076
class TestTerminalWidth(tests.TestCase):
1984
2077
 
1985
2078
    def setUp(self):
1986
 
        tests.TestCase.setUp(self)
 
2079
        super(TestTerminalWidth, self).setUp()
1987
2080
        self._orig_terminal_size_state = osutils._terminal_size_state
1988
2081
        self._orig_first_terminal_size = osutils._first_terminal_size
1989
2082
        self.addCleanup(self.restore_osutils_globals)
2070
2163
    _test_needs_features = [features.chown_feature]
2071
2164
 
2072
2165
    def setUp(self):
2073
 
        tests.TestCaseInTempDir.setUp(self)
 
2166
        super(TestCreationOps, self).setUp()
2074
2167
        self.overrideAttr(os, 'chown', self._dummy_chown)
2075
2168
 
2076
2169
        # params set by call to _dummy_chown
2086
2179
        osutils.copy_ownership_from_path('test_file', ownsrc)
2087
2180
 
2088
2181
        s = os.stat(ownsrc)
2089
 
        self.assertEquals(self.path, 'test_file')
2090
 
        self.assertEquals(self.uid, s.st_uid)
2091
 
        self.assertEquals(self.gid, s.st_gid)
 
2182
        self.assertEqual(self.path, 'test_file')
 
2183
        self.assertEqual(self.uid, s.st_uid)
 
2184
        self.assertEqual(self.gid, s.st_gid)
2092
2185
 
2093
2186
    def test_copy_ownership_nonesrc(self):
2094
2187
        """copy_ownership_from_path test with src=None."""
2097
2190
        osutils.copy_ownership_from_path('test_file')
2098
2191
 
2099
2192
        s = os.stat('..')
2100
 
        self.assertEquals(self.path, 'test_file')
2101
 
        self.assertEquals(self.uid, s.st_uid)
2102
 
        self.assertEquals(self.gid, s.st_gid)
 
2193
        self.assertEqual(self.path, 'test_file')
 
2194
        self.assertEqual(self.uid, s.st_uid)
 
2195
        self.assertEqual(self.gid, s.st_gid)
 
2196
 
 
2197
 
 
2198
class TestPathFromEnviron(tests.TestCase):
 
2199
 
 
2200
    def test_is_unicode(self):
 
2201
        self.overrideEnv('BZR_TEST_PATH', './anywhere at all/')
 
2202
        path = osutils.path_from_environ('BZR_TEST_PATH')
 
2203
        self.assertIsInstance(path, unicode)
 
2204
        self.assertEqual(u'./anywhere at all/', path)
 
2205
 
 
2206
    def test_posix_path_env_ascii(self):
 
2207
        self.overrideEnv('BZR_TEST_PATH', '/tmp')
 
2208
        home = osutils._posix_path_from_environ('BZR_TEST_PATH')
 
2209
        self.assertIsInstance(home, unicode)
 
2210
        self.assertEqual(u'/tmp', home)
 
2211
 
 
2212
    def test_posix_path_env_unicode(self):
 
2213
        self.requireFeature(features.ByteStringNamedFilesystem)
 
2214
        self.overrideEnv('BZR_TEST_PATH', '/home/\xa7test')
 
2215
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
 
2216
        self.assertEqual(u'/home/\xa7test',
 
2217
            osutils._posix_path_from_environ('BZR_TEST_PATH'))
 
2218
        osutils._fs_enc = "iso8859-5"
 
2219
        self.assertEqual(u'/home/\u0407test',
 
2220
            osutils._posix_path_from_environ('BZR_TEST_PATH'))
 
2221
        osutils._fs_enc = "utf-8"
 
2222
        self.assertRaises(errors.BadFilenameEncoding,
 
2223
            osutils._posix_path_from_environ, 'BZR_TEST_PATH')
 
2224
 
 
2225
 
 
2226
class TestGetHomeDir(tests.TestCase):
 
2227
 
 
2228
    def test_is_unicode(self):
 
2229
        home = osutils._get_home_dir()
 
2230
        self.assertIsInstance(home, unicode)
 
2231
 
 
2232
    def test_posix_homeless(self):
 
2233
        self.overrideEnv('HOME', None)
 
2234
        home = osutils._get_home_dir()
 
2235
        self.assertIsInstance(home, unicode)
 
2236
 
 
2237
    def test_posix_home_ascii(self):
 
2238
        self.overrideEnv('HOME', '/home/test')
 
2239
        home = osutils._posix_get_home_dir()
 
2240
        self.assertIsInstance(home, unicode)
 
2241
        self.assertEqual(u'/home/test', home)
 
2242
 
 
2243
    def test_posix_home_unicode(self):
 
2244
        self.requireFeature(features.ByteStringNamedFilesystem)
 
2245
        self.overrideEnv('HOME', '/home/\xa7test')
 
2246
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
 
2247
        self.assertEqual(u'/home/\xa7test', osutils._posix_get_home_dir())
 
2248
        osutils._fs_enc = "iso8859-5"
 
2249
        self.assertEqual(u'/home/\u0407test', osutils._posix_get_home_dir())
 
2250
        osutils._fs_enc = "utf-8"
 
2251
        self.assertRaises(errors.BadFilenameEncoding,
 
2252
            osutils._posix_get_home_dir)
2103
2253
 
2104
2254
 
2105
2255
class TestGetuserUnicode(tests.TestCase):
2106
2256
 
 
2257
    def test_is_unicode(self):
 
2258
        user = osutils.getuser_unicode()
 
2259
        self.assertIsInstance(user, unicode)
 
2260
 
 
2261
    def envvar_to_override(self):
 
2262
        if sys.platform == "win32":
 
2263
            # Disable use of platform calls on windows so envvar is used
 
2264
            self.overrideAttr(win32utils, 'has_ctypes', False)
 
2265
            return 'USERNAME' # only variable used on windows
 
2266
        return 'LOGNAME' # first variable checked by getpass.getuser()
 
2267
 
2107
2268
    def test_ascii_user(self):
2108
 
        self.overrideEnv('LOGNAME', 'jrandom')
 
2269
        self.overrideEnv(self.envvar_to_override(), 'jrandom')
2109
2270
        self.assertEqual(u'jrandom', osutils.getuser_unicode())
2110
2271
 
2111
2272
    def test_unicode_user(self):
2117
2278
                % (osutils.get_user_encoding(),))
2118
2279
        uni_username = u'jrandom' + uni_val
2119
2280
        encoded_username = uni_username.encode(ue)
2120
 
        self.overrideEnv('LOGNAME', encoded_username)
 
2281
        self.overrideEnv(self.envvar_to_override(), encoded_username)
2121
2282
        self.assertEqual(uni_username, osutils.getuser_unicode())
2122
 
        self.overrideEnv('LOGNAME', u'jrandom\xb6'.encode(ue))
2123
 
        self.assertEqual(u'jrandom\xb6', osutils.getuser_unicode())
2124
 
 
2125
 
    def test_no_username_bug_660174(self):
2126
 
        self.requireFeature(features.win32_feature)
2127
 
        for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
2128
 
            self.overrideEnv(name, None)
2129
 
        self.assertEqual(u'UNKNOWN', osutils.getuser_unicode())
2130
2283
 
2131
2284
 
2132
2285
class TestBackupNames(tests.TestCase):
2172
2325
        self.assertTrue(
2173
2326
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
2174
2327
        self.assertTrue(osutils.find_executable_on_path('file.txt') is None)
 
2328
        
 
2329
    def test_windows_app_path(self):
 
2330
        if sys.platform != 'win32':
 
2331
            raise tests.TestSkipped('test requires win32')
 
2332
        # Override PATH env var so that exe can only be found on App Path
 
2333
        self.overrideEnv('PATH', '')
 
2334
        # Internt Explorer is always registered in the App Path
 
2335
        self.assertTrue(osutils.find_executable_on_path('iexplore') is not None)
2175
2336
 
2176
2337
    def test_other(self):
2177
2338
        if sys.platform == 'win32':
2179
2340
        self.assertTrue(osutils.find_executable_on_path('sh') is not None)
2180
2341
        self.assertTrue(
2181
2342
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
 
2343
 
 
2344
 
 
2345
class TestEnvironmentErrors(tests.TestCase):
 
2346
    """Test handling of environmental errors"""
 
2347
 
 
2348
    def test_is_oserror(self):
 
2349
        self.assertTrue(osutils.is_environment_error(
 
2350
            OSError(errno.EINVAL, "Invalid parameter")))
 
2351
 
 
2352
    def test_is_ioerror(self):
 
2353
        self.assertTrue(osutils.is_environment_error(
 
2354
            IOError(errno.EINVAL, "Invalid parameter")))
 
2355
 
 
2356
    def test_is_socket_error(self):
 
2357
        self.assertTrue(osutils.is_environment_error(
 
2358
            socket.error(errno.EINVAL, "Invalid parameter")))
 
2359
 
 
2360
    def test_is_select_error(self):
 
2361
        self.assertTrue(osutils.is_environment_error(
 
2362
            select.error(errno.EINVAL, "Invalid parameter")))
 
2363
 
 
2364
    def test_is_pywintypes_error(self):
 
2365
        self.requireFeature(features.pywintypes)
 
2366
        import pywintypes
 
2367
        self.assertTrue(osutils.is_environment_error(
 
2368
            pywintypes.error(errno.EINVAL, "Invalid parameter", "Caller")))