Lib.test.test_os_jy.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
# -*- coding: utf-8 -*-
"""Misc os module tests
Made for Jython.
"""
import os
import sys
import glob
import array
import errno
import struct
import unittest
import subprocess
from test import test_support
from java.io import File
class OSFileTestCase(unittest.TestCase):
def setUp(self):
open(test_support.TESTFN, 'w').close()
def tearDown(self):
if os.path.exists(test_support.TESTFN):
os.remove(test_support.TESTFN)
def test_issue1727(self):
os.stat(*(test_support.TESTFN,))
def test_issue1755(self):
os.remove(test_support.TESTFN)
self.assertRaises(OSError, os.utime, test_support.TESTFN, None)
@unittest.skipUnless(hasattr(os, 'link'), "os.link not available")
def test_issue1824(self):
os.remove(test_support.TESTFN)
self.assertRaises(OSError, os.link,
test_support.TESTFN, test_support.TESTFN)
def test_issue1825(self):
os.remove(test_support.TESTFN)
testfnu = unicode(test_support.TESTFN)
try:
os.open(testfnu, os.O_RDONLY)
except OSError, e:
self.assertTrue(isinstance(e.filename, unicode))
self.assertEqual(e.filename, testfnu)
else:
self.assertTrue(False)
# XXX: currently fail
#for fn in os.chdir, os.listdir, os.rmdir:
for fn in (os.rmdir,):
try:
fn(testfnu)
except OSError, e:
self.assertTrue(isinstance(e.filename, unicode))
self.assertEqual(e.filename, testfnu)
else:
self.assertTrue(False)
def test_issue2068(self):
os.remove(test_support.TESTFN)
for i in range(2):
fd = os.open(test_support.TESTFN, os.O_RDWR | os.O_CREAT | os.O_APPEND)
try:
os.write(fd, bytes('one'))
os.write(fd, bytes('two'))
os.write(fd, bytes('three'))
finally:
fd.close()
with open(test_support.TESTFN, 'rb') as f:
content = f.read()
self.assertEqual(content, 2 * b'onetwothree')
def test_issue1793(self):
# prepare the input file containing 256 bytes of sorted byte-sized numbers
fd = file(test_support.TESTFN, 'wb')
try:
for x in range(256):
fd.write(chr(x))
finally:
fd.close()
# reopen in read/append mode
fd = file(test_support.TESTFN, 'rb+')
try:
# read forward from the beginning
for x in range(256):
pos = fd.tell()
self.assertEqual(pos, x,
'[forward] before read: pos should be %d but is %d' % (x, pos))
# read just one byte
c = struct.unpack('B', fd.read(1))[0]
pos = fd.tell()
self.assertEqual(pos, x + 1,
'[forward] after read: pos should be %d but is %d' % (x + 1, pos))
self.assertEqual(c, x)
# read backward from the end
fd.seek(-1, os.SEEK_END)
for x in range(255, -1, -1):
pos = fd.tell()
self.assertEqual(pos, x,
'[backward] before read: pos should be %d but is %d' % (x, pos))
# read just one byte
c = ord(fd.read(1))
pos = fd.tell()
self.assertEqual(pos, x + 1,
'[backward] after read: pos should be %d but is %d' % (x + 1, pos))
self.assertEqual(c, x)
if x > 0:
fd.seek(-2, os.SEEK_CUR)
finally:
fd.close()
class OSDirTestCase(unittest.TestCase):
def setUp(self):
self.base = test_support.TESTFN
self.path = os.path.join(self.base, 'dir1', 'dir2', 'dir3')
os.makedirs(self.path)
def test_rmdir(self):
# Remove end directory
os.rmdir(self.path)
# Fail to remove a chain of directories
self.assertRaises(OSError, os.rmdir, self.base)
def test_issue2083(self):
# Should fail to remove/unlink directory
self.assertRaises(OSError, os.remove, self.path)
self.assertRaises(OSError, os.unlink, self.path)
def tearDown(self):
# Some dirs may have been deleted. Find the longest that exists.
p = self.path
while not os.path.exists(p) and p != self.base:
p = os.path.dirname(p)
os.removedirs(p)
class OSStatTestCase(unittest.TestCase):
def setUp(self):
open(test_support.TESTFN, 'w').close()
def tearDown(self):
if os.path.exists(test_support.TESTFN):
os.remove(test_support.TESTFN)
def test_stat_with_trailing_slash(self):
self.assertRaises(OSError, os.stat, test_support.TESTFN + os.path.sep)
self.assertRaises(OSError, os.lstat, test_support.TESTFN + os.path.sep)
class OSWriteTestCase(unittest.TestCase):
def setUp(self):
self.fd = os.open(test_support.TESTFN, os.O_WRONLY | os.O_CREAT)
def tearDown(self):
if self.fd :
os.close(self.fd)
if os.path.exists(test_support.TESTFN):
os.remove(test_support.TESTFN)
def do_write(self, b, nx=None):
if nx is None : nx = len(b)
n = os.write(self.fd, b)
self.assertEqual(n, nx, "os.write length error: " + repr(b))
def test_write_buffer(self): # Issue 2062
s = b"Big Red Book"
for type2test in (str, buffer, bytearray, (lambda x : array.array('b',x))) :
self.do_write(type2test(s))
with memoryview(s) as m :
self.do_write(m)
# not contiguous:
self.assertRaises(BufferError, self.do_write, m[1::2])
# lacks buffer api:
self.assertRaises(TypeError, self.do_write, 1.5, 4)
class UnicodeTestCase(unittest.TestCase):
def test_env(self):
with test_support.temp_cwd(name=u"tempcwd-中文"):
# os.environ is constructed with FS-encoded values (as in CPython),
# but it will accept unicode additions.
newenv = os.environ.copy()
newenv["TEST_HOME"] = expected = u"首页"
# Environment passed as UTF-16 String[] by Java, arrives FS-encoded.
for encoding in ('utf-8', 'gbk'):
# Emit the value of TEST_HOME explicitly encoded.
p = subprocess.Popen(
[sys.executable, "-c",
'import sys, os;' \
'sys.stdout.write(os.getenv("TEST_HOME")' \
'.decode(sys.getfilesystemencoding())' \
'.encode("%s"))' \
% encoding],
stdout=subprocess.PIPE,
env=newenv)
# Decode with chosen encoding
self.assertEqual(p.stdout.read().decode(encoding), u"首页")
def test_env_naively(self):
with test_support.temp_cwd(name=u"tempcwd-中文"):
# os.environ is constructed with FS-encoded values (as in CPython),
# but it will accept unicode additions.
newenv = os.environ.copy()
newenv["TEST_HOME"] = expected = u"首页"
# Environment passed as UTF-16 String[] by Java, arrives FS-encoded.
# However, emit TEST_HOME without thinking about the encoding.
p = subprocess.Popen(
[sys.executable, "-c",
'import sys, os;' \
'sys.stdout.write(os.getenv("TEST_HOME"))'],
stdout=subprocess.PIPE,
env=newenv)
# Decode with FS encoding used by subprocess communication
self.assertEqual(p.stdout.read().decode('utf-8'), expected)
def test_getcwd(self):
with test_support.temp_cwd(name=u"tempcwd-中文") as temp_cwd:
# os.getcwd reports the working directory as an FS-encoded str,
# which is also the encoding used in subprocess communication.
p = subprocess.Popen([
sys.executable, "-c",
'import sys,os;' \
'sys.stdout.write(os.getcwd())'],
stdout=subprocess.PIPE)
self.assertEqual(p.stdout.read(), temp_cwd)
def test_getcwdu(self):
with test_support.temp_cwd(name=u"tempcwd-中文") as temp_cwd:
# os.getcwdu reports the working directory as unicode,
# which must be encoded for subprocess communication.
p = subprocess.Popen([
sys.executable, "-c",
'import sys,os;' \
'sys.stdout.write(os.getcwdu().encode(sys.getfilesystemencoding()))'],
stdout=subprocess.PIPE)
self.assertEqual(p.stdout.read(), temp_cwd)
def test_listdir(self):
# It is hard to avoid Unicode paths on systems like OS X. Use relative
# paths from a temp CWD to work around this. But when you don't,
# it behaves like this ...
with test_support.temp_cwd() as new_cwd:
basedir = os.path.join(".", "unicode")
self.assertIs(type(basedir), bytes)
chinese_path = os.path.join(basedir, u"中文")
self.assertIs(type(chinese_path), unicode)
home_path = os.path.join(chinese_path, u"首页")
os.makedirs(home_path)
FS = sys.getfilesystemencoding()
with open(os.path.join(home_path, "test.txt"), "w") as test_file:
test_file.write("42\n")
# listdir(bytes) includes encoded form of 中文
entries = os.listdir(basedir)
self.assertIn(u"中文".encode(FS), entries)
for entry in entries:
self.assertIs(type(entry), bytes)
# listdir(unicode) includes unicode form of 首页
entries = os.listdir(chinese_path)
self.assertIn(u"首页", entries)
for entry in entries:
self.assertIs(type(entry), unicode)
# glob.glob builds on os.listdir; note that we don't use
# Unicode paths in the arg to glob so the result is bytes
self.assertEqual(
glob.glob(os.path.join("unicode", "*")),
[os.path.join(u"unicode", u"中文").encode(FS)])
self.assertEqual(
glob.glob(os.path.join("unicode", "*", "*")),
[os.path.join(u"unicode", u"中文", u"首页").encode(FS)])
self.assertEqual(
glob.glob(os.path.join("unicode", "*", "*", "*")),
[os.path.join(u"unicode", u"中文", u"首页", "test.txt").encode(FS)])
# Now use a Unicode path as well as in the glob arg
self.assertEqual(
glob.glob(os.path.join(u"unicode", "*")),
[os.path.join(u"unicode", u"中文")])
self.assertEqual(
glob.glob(os.path.join(u"unicode", "*", "*")),
[os.path.join(u"unicode", u"中文", u"首页")])
self.assertEqual(
glob.glob(os.path.join(u"unicode", "*", "*", "*")),
[os.path.join(u"unicode", u"中文", u"首页", "test.txt")])
# Verify Java integration. But we will need to construct
# an absolute path since chdir doesn't work with Java
# (except for subprocesses, like below in test_env)
for entry in entries: # list(unicode)
# new_cwd is bytes while chinese_path is unicode.
# But new_cwd is not guaranteed to be just ascii, so decode it.
new_cwd = new_cwd.decode(FS)
entry_path = os.path.join(new_cwd, chinese_path, entry)
f = File(entry_path)
self.assertTrue(f.exists(),
"File %r (%r) should be testable for existence" %
(f, entry_path))
def test_uname(self):
# Test that os.uname returns a tuple of (arbitrary) strings.
# uname failed on on a Chinese localised system (see
# https://bugs.jython.org/issue2726). This test really needs to
# run in that environment or it passes too easily.
result = os.uname()
# (sysname, nodename, release, version, machine)
self.assertEqual(type(result), tuple)
self.assertEqual(len(result), 5)
for s in result: self.assertEqual(type(s), str)
class LocaleTestCase(unittest.TestCase):
def get_installed_locales(self, codes, msg=None):
def normalize(code):
# OS X and Ubuntu (at the very least) differ slightly in locale code formatting
return code.strip().replace("-", "").lower()
try:
installed_codes = dict(((normalize(code), code) for
code in subprocess.check_output(["locale", "-a"]).split()))
except (subprocess.CalledProcessError, OSError):
raise unittest.SkipTest("locale command not available, cannot test")
if msg is None:
msg = "One of %s tested locales is not installed" % (codes,)
available_codes = []
for code in codes:
if normalize(code) in installed_codes:
available_codes.append(installed_codes[normalize(code)])
unittest.skipUnless(available_codes, msg)
return available_codes
# must be on posix and turkish locale supported
@unittest.skipIf(not test_support.is_jython_posix, "Not posix")
def test_turkish_locale_posix_module(self):
# Verifies fix of http://bugs.jython.org/issue1874
self.get_installed_locales(["tr_TR.UTF-8"], "Turkish locale not installed, cannot test")
newenv = os.environ.copy()
newenv["LC_ALL"] = "tr_TR.UTF-8" # set to Turkish locale
self.assertEqual(
subprocess.check_output(
[sys.executable, "-c",
"import sys; assert 'posix' in sys.builtin_module_names"],
env=newenv),
"")
def test_turkish_locale_string_lower_upper(self):
# Verifies fix of http://bugs.jython.org/issue1874
self.get_installed_locales(["tr_TR.UTF-8"], "Turkish locale not installed, cannot test")
newenv = os.environ.copy()
newenv["LC_ALL"] = "tr_TR.UTF-8" # set to Turkish locale
self.assertIn(
subprocess.check_output(
[sys.executable, "-c",
'print repr(["I".lower(), u"I".lower(), "i".upper(), u"i".upper()])'],
env=newenv),
# Should not convert str for 'i'/'I', but should convert
# unicode if in Turkish locale; this behavior intentionally is
# different than CPython; see also http://bugs.python.org/issue17252
#
# Note that JVMs seem to have some latitude here however, so support
# either for now.
["['i', u'\\u0131', 'I', u'\\u0130']" + os.linesep,
"['i', u'i', 'I', u'I']" + os.linesep])
def test_strptime_locale(self):
# Verifies fix of http://bugs.jython.org/issue2261
newenv = os.environ.copy()
codes = [
"cs_CZ.UTF-8", "pl_PL.UTF-8", "ru_RU.UTF-8",
"sk_SK.UTF-8", "uk_UA.UTF-8", "zh_CN.UTF-8"]
for code in self.get_installed_locales(codes):
newenv["LC_ALL"] = code
self.assertEqual(
subprocess.check_output(
[sys.executable, "-c",
'import datetime; print(datetime.datetime.strptime("2015-01-22", "%Y-%m-%d"))'],
env=newenv),
"2015-01-22 00:00:00" + os.linesep)
def test_strftime_japanese_locale(self):
# Verifies fix of http://bugs.jython.org/issue2301 - produces
# UTF-8 encoded output per what CPython does, rather than Unicode.
# We will revisit in Jython 3.x!
self.get_installed_locales("ja_JP.UTF-8")
if test_support.get_java_version() < (10,):
expected = "'\\xe6\\x97\\xa5 3 29 14:55:13 2015'"
else:
# From Java 10 onwards, Japanese formatting more correctly includes
# 月, the kanji character for month
expected = "'\\xe6\\x97\\xa5 3\\xe6\\x9c\\x88 29 14:55:13 2015'"
self.assertEqual(
subprocess.check_output(
[sys.executable,
"-J-Duser.country=JP", "-J-Duser.language=ja",
"-c",
"import time; print repr(time.strftime('%c', (2015, 3, 29, 14, 55, 13, 6, 88, 0)))"]),
expected + os.linesep)
class SystemTestCase(unittest.TestCase):
def test_system_no_site_import(self):
# If not importing site (-S), importing traceback previously
# would fail with an import error due to creating a circular
# import chain. This root cause is because the os module
# imports the subprocess module for the system function; but
# the subprocess module imports from os. Verifies that this is
# managed by making the import late; also verify the
# monkeypatching optimization is successful by calling
# os.system twice.
with test_support.temp_cwd() as temp_cwd:
self.assertEqual(
subprocess.check_output(
[sys.executable, "-S", "-c",
"import traceback; import os; os.system('echo 42'); os.system('echo 47')"])\
.replace("\r", ""), # in case of running on Windows
"42\n47\n")
def test_system_uses_os_environ(self):
"""Writing to os.environ is made available as env vars in os.system subprocesses"""
# This test likely requires additional customization for
# environments like AS/400, but I do not have current access.
# Verifies fix for http://bugs.jython.org/issue2416
if os._name == "nt":
echo_command = 'echo %TEST_ENVVAR%'
else:
echo_command = 'echo $TEST_ENVVAR'
with test_support.temp_cwd() as temp_cwd:
self.assertEqual(
subprocess.check_output(
[sys.executable, "-c",
"import os; os.environ['TEST_ENVVAR'] = 'works on 2.7.1+'; os.system('%s')" % echo_command])\
.replace("\r", ""), # in case of running on Windows
"works on 2.7.1+\n")
@unittest.skipUnless(hasattr(os, 'link'), "os.link not available")
class LinkTestCase(unittest.TestCase):
def test_bad_link(self):
with test_support.temp_cwd() as new_cwd:
target = os.path.join(new_cwd, "target")
with open(target, "w") as f:
f.write("TARGET")
source = os.path.join(new_cwd, "source")
with self.assertRaises(OSError) as cm:
os.link(target, target)
self.assertEqual(cm.exception.errno, errno.EEXIST)
with self.assertRaises(OSError) as cm:
os.link("nonexistent-file", source)
self.assertEqual(cm.exception.errno, errno.ENOENT)
def test_link(self):
with test_support.temp_cwd() as new_cwd:
target = os.path.join(new_cwd, "target")
with open(target, "w") as f:
f.write("TARGET")
source = os.path.join(new_cwd, "source")
os.link(target, source)
with open(source, "r") as f:
self.assertEqual(f.read(), "TARGET")
@unittest.skipUnless(hasattr(os, 'symlink'), "symbolic link support not available")
class SymbolicLinkTestCase(unittest.TestCase):
def test_bad_symlink(self):
with test_support.temp_cwd() as new_cwd:
target = os.path.join(new_cwd, "target")
with open(target, "w") as f:
f.write("TARGET")
source = os.path.join(new_cwd, "source")
with self.assertRaises(OSError) as cm:
os.symlink(source, target) # reversed args!
self.assertEqual(cm.exception.errno, errno.EEXIST)
def test_readlink(self):
with test_support.temp_cwd() as new_cwd:
target = os.path.join(new_cwd, "target")
with open(target, "w") as f:
f.write("TARGET")
source = os.path.join(new_cwd, "source")
os.symlink(target, source)
self.assertEqual(os.readlink(source), target)
self.assertEqual(os.readlink(unicode(source)), unicode(target))
self.assertIsInstance(os.readlink(unicode(source)), unicode)
def test_readlink_non_symlink(self):
"""os.readlink of a non symbolic link should raise an error"""
# test for http://bugs.jython.org/issue2292
with test_support.temp_cwd() as new_cwd:
target = os.path.join(new_cwd, "target")
with open(target, "w") as f:
f.write("TARGET")
with self.assertRaises(OSError) as cm:
os.readlink(target)
self.assertEqual(cm.exception.errno, errno.EINVAL)
self.assertEqual(cm.exception.filename, target)
def test_readlink_nonexistent(self):
with test_support.temp_cwd() as new_cwd:
nonexistent_file = os.path.join(new_cwd, "nonexistent-file")
with self.assertRaises(OSError) as cm:
os.readlink(nonexistent_file)
self.assertEqual(cm.exception.errno, errno.ENOENT)
self.assertEqual(cm.exception.filename, nonexistent_file)
def test_main():
test_support.run_unittest(
OSFileTestCase,
OSDirTestCase,
OSStatTestCase,
OSWriteTestCase,
UnicodeTestCase,
LocaleTestCase,
SystemTestCase,
LinkTestCase,
SymbolicLinkTestCase,
)
if __name__ == '__main__':
test_main()