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 Show documentation
Show all versions of jython 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()