Fix Python3 issue with sbang checking; add tests. (#4017)
This commit is contained in:
parent
58567a2182
commit
2d9dac9af0
@ -38,9 +38,12 @@
|
|||||||
|
|
||||||
def shebang_too_long(path):
|
def shebang_too_long(path):
|
||||||
"""Detects whether a file has a shebang line that is too long."""
|
"""Detects whether a file has a shebang line that is too long."""
|
||||||
with open(path, 'r') as script:
|
if not os.path.isfile(path):
|
||||||
|
return False
|
||||||
|
|
||||||
|
with open(path, 'rb') as script:
|
||||||
bytes = script.read(2)
|
bytes = script.read(2)
|
||||||
if bytes != '#!':
|
if bytes != b'#!':
|
||||||
return False
|
return False
|
||||||
|
|
||||||
line = bytes + script.readline()
|
line = bytes + script.readline()
|
||||||
|
@ -27,13 +27,16 @@
|
|||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import stat
|
import stat
|
||||||
import unittest
|
import pytest
|
||||||
import tempfile
|
import tempfile
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from llnl.util.filesystem import *
|
from llnl.util.filesystem import *
|
||||||
from spack.hooks.sbang import filter_shebangs_in_directory
|
|
||||||
import spack
|
import spack
|
||||||
|
from spack.hooks.sbang import *
|
||||||
|
from spack.util.executable import which
|
||||||
|
|
||||||
|
|
||||||
short_line = "#!/this/is/short/bin/bash\n"
|
short_line = "#!/this/is/short/bin/bash\n"
|
||||||
long_line = "#!/this/" + ('x' * 200) + "/is/long\n"
|
long_line = "#!/this/" + ('x' * 200) + "/is/long\n"
|
||||||
@ -43,14 +46,13 @@
|
|||||||
last_line = "last!\n"
|
last_line = "last!\n"
|
||||||
|
|
||||||
|
|
||||||
class SbangTest(unittest.TestCase):
|
class ScriptDirectory(object):
|
||||||
|
"""Directory full of test scripts to run sbang instrumentation on."""
|
||||||
def setUp(self):
|
def __init__(self):
|
||||||
self.tempdir = tempfile.mkdtemp()
|
self.tempdir = tempfile.mkdtemp()
|
||||||
|
|
||||||
# make sure we can ignore non-files
|
self.directory = os.path.join(self.tempdir, 'dir')
|
||||||
directory = os.path.join(self.tempdir, 'dir')
|
mkdirp(self.directory)
|
||||||
mkdirp(directory)
|
|
||||||
|
|
||||||
# Script with short shebang
|
# Script with short shebang
|
||||||
self.short_shebang = os.path.join(self.tempdir, 'short')
|
self.short_shebang = os.path.join(self.tempdir, 'short')
|
||||||
@ -71,48 +73,70 @@ def setUp(self):
|
|||||||
f.write(last_line)
|
f.write(last_line)
|
||||||
|
|
||||||
# Script already using sbang.
|
# Script already using sbang.
|
||||||
self.has_shebang = os.path.join(self.tempdir, 'shebang')
|
self.has_sbang = os.path.join(self.tempdir, 'shebang')
|
||||||
with open(self.has_shebang, 'w') as f:
|
with open(self.has_sbang, 'w') as f:
|
||||||
f.write(sbang_line)
|
f.write(sbang_line)
|
||||||
f.write(long_line)
|
f.write(long_line)
|
||||||
f.write(last_line)
|
f.write(last_line)
|
||||||
|
|
||||||
def tearDown(self):
|
# Fake binary file.
|
||||||
|
self.binary = os.path.join(self.tempdir, 'binary')
|
||||||
|
tar = which('tar', required=True)
|
||||||
|
tar('czf', self.binary, self.has_sbang)
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
shutil.rmtree(self.tempdir, ignore_errors=True)
|
shutil.rmtree(self.tempdir, ignore_errors=True)
|
||||||
|
|
||||||
def test_shebang_handling(self):
|
|
||||||
filter_shebangs_in_directory(self.tempdir)
|
|
||||||
|
|
||||||
# Make sure this is untouched
|
@pytest.fixture
|
||||||
with open(self.short_shebang, 'r') as f:
|
def script_dir():
|
||||||
self.assertEqual(f.readline(), short_line)
|
sdir = ScriptDirectory()
|
||||||
self.assertEqual(f.readline(), last_line)
|
yield sdir
|
||||||
|
sdir.destroy()
|
||||||
|
|
||||||
# Make sure this got patched.
|
|
||||||
with open(self.long_shebang, 'r') as f:
|
|
||||||
self.assertEqual(f.readline(), sbang_line)
|
|
||||||
self.assertEqual(f.readline(), long_line)
|
|
||||||
self.assertEqual(f.readline(), last_line)
|
|
||||||
|
|
||||||
# Make sure this got patched.
|
def test_shebang_handling(script_dir):
|
||||||
with open(self.lua_shebang, 'r') as f:
|
assert shebang_too_long(script_dir.lua_shebang)
|
||||||
self.assertEqual(f.readline(), sbang_line)
|
assert shebang_too_long(script_dir.long_shebang)
|
||||||
self.assertEqual(f.readline(), lua_line_patched)
|
|
||||||
self.assertEqual(f.readline(), last_line)
|
|
||||||
|
|
||||||
# Make sure this is untouched
|
assert not shebang_too_long(script_dir.short_shebang)
|
||||||
with open(self.has_shebang, 'r') as f:
|
assert not shebang_too_long(script_dir.has_sbang)
|
||||||
self.assertEqual(f.readline(), sbang_line)
|
assert not shebang_too_long(script_dir.binary)
|
||||||
self.assertEqual(f.readline(), long_line)
|
assert not shebang_too_long(script_dir.directory)
|
||||||
self.assertEqual(f.readline(), last_line)
|
|
||||||
|
|
||||||
def test_shebang_handles_non_writable_files(self):
|
filter_shebangs_in_directory(script_dir.tempdir)
|
||||||
# make a file non-writable
|
|
||||||
st = os.stat(self.long_shebang)
|
|
||||||
not_writable_mode = st.st_mode & ~stat.S_IWRITE
|
|
||||||
os.chmod(self.long_shebang, not_writable_mode)
|
|
||||||
|
|
||||||
self.test_shebang_handling()
|
# Make sure this is untouched
|
||||||
|
with open(script_dir.short_shebang, 'r') as f:
|
||||||
|
assert f.readline() == short_line
|
||||||
|
assert f.readline() == last_line
|
||||||
|
|
||||||
st = os.stat(self.long_shebang)
|
# Make sure this got patched.
|
||||||
self.assertEqual(oct(not_writable_mode), oct(st.st_mode))
|
with open(script_dir.long_shebang, 'r') as f:
|
||||||
|
assert f.readline() == sbang_line
|
||||||
|
assert f.readline() == long_line
|
||||||
|
assert f.readline() == last_line
|
||||||
|
|
||||||
|
# Make sure this got patched.
|
||||||
|
with open(script_dir.lua_shebang, 'r') as f:
|
||||||
|
assert f.readline() == sbang_line
|
||||||
|
assert f.readline() == lua_line_patched
|
||||||
|
assert f.readline() == last_line
|
||||||
|
|
||||||
|
# Make sure this is untouched
|
||||||
|
with open(script_dir.has_sbang, 'r') as f:
|
||||||
|
assert f.readline() == sbang_line
|
||||||
|
assert f.readline() == long_line
|
||||||
|
assert f.readline() == last_line
|
||||||
|
|
||||||
|
|
||||||
|
def test_shebang_handles_non_writable_files(script_dir):
|
||||||
|
# make a file non-writable
|
||||||
|
st = os.stat(script_dir.long_shebang)
|
||||||
|
not_writable_mode = st.st_mode & ~stat.S_IWRITE
|
||||||
|
os.chmod(script_dir.long_shebang, not_writable_mode)
|
||||||
|
|
||||||
|
test_shebang_handling(script_dir)
|
||||||
|
|
||||||
|
st = os.stat(script_dir.long_shebang)
|
||||||
|
assert oct(not_writable_mode) == oct(st.st_mode)
|
||||||
|
Loading…
Reference in New Issue
Block a user