Skip to content

Commit 4432ed9

Browse files
Merge pull request #191 from opensciencegrid/el8
EL8/Python 3 support
2 parents e51d6a3 + 7f82e29 commit 4432ed9

12 files changed

+79
-31
lines changed

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ VERSION := 3.0.0
1313
# Other configuration: May need to change for a release
1414
# ------------------------------------------------------------------------------
1515

16+
PYTHON = python
17+
1618
SBIN_FILES := osg-test osg-test-log-viewer
1719
INSTALL_SBIN_DIR := usr/sbin
1820

@@ -50,7 +52,7 @@ TARBALL_DIR := $(PACKAGE)-$(VERSION)
5052
TARBALL_NAME := $(PACKAGE)-$(VERSION).tar.gz
5153
UPSTREAM := /p/vdt/public/html/upstream
5254
UPSTREAM_DIR := $(UPSTREAM)/$(PACKAGE)/$(VERSION)
53-
INSTALL_PYTHON_DIR := $(shell python -c 'from distutils.sysconfig import get_python_lib; print get_python_lib()')
55+
INSTALL_PYTHON_DIR := $(shell $(PYTHON) -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())')
5456

5557

5658
# ------------------------------------------------------------------------------

osg-test

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
#!/usr/bin/python
1+
#!/usr/bin/env python
22

33
from __future__ import print_function
44
from distutils.sysconfig import get_python_lib
55
from optparse import OptionParser
6-
import ConfigParser
6+
try:
7+
import ConfigParser
8+
except ImportError:
9+
import configparser as ConfigParser
710
import os
811
import re
912
import signal

osg-test-log-viewer

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/python
1+
#!/usr/bin/env python
22
"""View the output from osg-test in a structured way"""
33
from __future__ import print_function
44

osgtest/library/core.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
import traceback
2121
import socket
2222
import signal
23+
try:
24+
from shlex import quote as shell_quote
25+
except ImportError:
26+
from pipes import quote as shell_quote
2327

2428
from osgtest.library import osgunittest
2529

@@ -496,10 +500,8 @@ def __format_command(command):
496500
return result
497501

498502

499-
def __prepare_shell_argument(argument):
500-
if re.search(r'\W', argument) or argument == '':
501-
return "'" + re.sub(r"'", r"'\''", argument) + "'"
502-
return argument
503+
_devnull = open(os.devnull, "r+b")
504+
503505

504506
def __run_command(command, use_test_user, a_input, a_stdout, a_stderr, log_output=True, shell=False, timeout=None, timeout_signal='TERM'):
505507
global _last_log_had_output
@@ -514,10 +516,10 @@ def __run_command(command, use_test_user, a_input, a_stdout, a_stderr, log_outpu
514516
except TypeError:
515517
print('Need list or tuple, got %s' % type(command))
516518
if use_test_user:
517-
command = ['runuser', options.username, '-c', ' '.join(map(__prepare_shell_argument, command))]
519+
command = ['runuser', options.username, '-c', ' '.join(map(shell_quote, command))]
518520

519521
# Figure out stdin
520-
stdin = None
522+
stdin = _devnull
521523
if a_input is not None:
522524
stdin = subprocess.PIPE
523525

@@ -555,7 +557,8 @@ def __run_command(command, use_test_user, a_input, a_stdout, a_stderr, log_outpu
555557
os.killpg(p.pid, timeout_signal)
556558
os._exit(0)
557559

558-
(stdout, stderr) = p.communicate(a_input)
560+
stdout, stderr = p.communicate(to_bytes(a_input))
561+
stdout, stderr = to_str(stdout), to_str(stderr)
559562

560563
if timeout is not None:
561564
if p.returncode >= 0:
@@ -783,11 +786,23 @@ def run_fn_if_el_release_ok(*args, **kwargs):
783786
return el_release_decorator
784787

785788

786-
try:
787-
unicode
788-
except NameError: # python 3
789-
unicode = str
789+
def to_str(strlike, encoding="latin-1", errors="backslashreplace"):
790+
"""Turns a bytes into a str (Python 3) or a unicode to a str (Python 2)"""
791+
if strlike is None:
792+
return
793+
if not isinstance(strlike, str):
794+
if str is bytes:
795+
return strlike.encode(encoding, errors)
796+
else:
797+
return strlike.decode(encoding, errors)
798+
else:
799+
return strlike
790800

791801

792-
def is_string(var):
793-
return isinstance(var, (str, unicode))
802+
def to_bytes(strlike, encoding="latin-1", errors="backslashreplace"):
803+
"""Turns a str into bytes (Python 3) or a unicode to a str (Python 2)"""
804+
if strlike is None:
805+
return
806+
if not isinstance(strlike, bytes):
807+
return strlike.encode(encoding, errors)
808+
return strlike

osgtest/tests/special_install.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,13 @@ def test_02_install_packages(self):
5858

5959
retry_fail, _, stdout, _ = yum.retry_command(command)
6060
if retry_fail == '': # the command succeeded
61-
core.state['install.transaction_ids'].append(yum.get_transaction_id())
62-
command = ('rpm', '--verify', pkg)
63-
core.check_system(command, 'Verify %s' % (pkg))
61+
id = yum.get_transaction_id()
62+
if id not in core.state['install.transaction_ids']:
63+
core.state['install.transaction_ids'].append(id)
64+
if not pkg.startswith("/"):
65+
# ^^ rpm --verify doesn't work if you asked for a file instead of a package
66+
command = ('rpm', '--verify', pkg)
67+
core.check_system(command, 'Verify %s' % (pkg))
6468
yum.parse_output_for_packages(stdout)
6569

6670
fail_msg += retry_fail

osgtest/tests/test_280_gsiopenssh.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ def test_01_set_config(self):
3434
core.state['gsisshd.can-run'] = (not (
3535
core.el_release() >= 7 and
3636
core.state['selinux.mode'] and
37-
not core.rpm_is_installed('policycoreutils-python')))
37+
not core.dependency_is_installed("/usr/sbin/semanage")))
3838
self.skip_ok_unless(core.state['gsisshd.can-run'],
39-
"Can't run with SELinux on EL >= 7 without policycoreutils-python")
39+
"Can't run with SELinux on EL >= 7 without semanage")
4040

4141
files.write(
4242
SSHD_CONFIG,
@@ -47,7 +47,7 @@ def test_01_set_config(self):
4747
def test_02_setup_selinux_port(self):
4848
if not core.state['selinux.mode']:
4949
self.skip_ok('SELinux disabled')
50-
core.skip_ok_unless_installed('policycoreutils-python')
50+
core.skip_ok_unless_installed("/usr/sbin/semanage", by_depenency=True)
5151
port = core.config['gsisshd.port']
5252
core.check_system(['semanage', 'port', '--add', '-t', 'ssh_port_t', '--proto', 'tcp', port],
5353
message="Allow [gsi]sshd to use port %s" % port)

osgtest/tests/test_407_voms.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ def test_08_voms_proxy_check(self):
8080

8181
pwd_entry = pwd.getpwnam(core.options.username)
8282
cert_path = os.path.join(pwd_entry.pw_dir, '.globus', 'usercert.pem')
83+
# Note: We're only looking for the "Signature Algorithm" line which has the same output format
84+
# regardless of openssl version.
8385
command = ['openssl', 'x509', '-in', cert_path, '-text']
8486
signature_re = re.compile(r'Signature Algorithm:\s+(\w+)\s')
8587
stdout = core.check_system(command, 'Check X.509 certificate algorithm', user=True)[0]

osgtest/tests/test_460_stashcache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def test_03_http_fetch_from_cache(self):
7979
f = urlopen(
8080
"http://localhost:%d/%s" % (getcfg("CacheHTTPPort"), path)
8181
)
82-
result = f.read()
82+
result = core.to_str(f.read())
8383
except IOError as e:
8484
self.fail("Unable to download from cache via http: %s" % e)
8585
self.assertEqualVerbose(result, contents, "downloaded file mismatch")

osgtest/tests/test_470_rsv.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
import pwd
99
import shutil
1010
import socket
11-
import ConfigParser
11+
try:
12+
import ConfigParser
13+
except ImportError:
14+
import configparser as ConfigParser
1215

1316
"""
1417
Testing number conventions:

osgtest/tests/test_550_condorce.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
import os
55
import re
6-
import urllib2
6+
try:
7+
from urllib2 import urlopen
8+
except ImportError:
9+
from urllib.request import urlopen
710

811
import osgtest.library.condor as condor
912
import osgtest.library.core as core
@@ -126,9 +129,9 @@ def test_07_ceview(self):
126129
core.skip_ok_unless_installed('htcondor-ce-view')
127130
view_url = 'http://%s:%s' % (core.get_hostname(), int(core.config['condor-ce.view-port']))
128131
try:
129-
src = urllib2.urlopen(view_url).read()
130-
except urllib2.URLError:
131-
self.fail('Could not reach HTCondor-CE View at %s' % view_url)
132+
src = to_str(urlopen(view_url).read())
133+
except EnvironmentError as err:
134+
self.fail('Could not reach HTCondor-CE View at %s: %s' % (view_url, err))
132135
self.assert_(re.search(r'HTCondor-CE Overview', src), 'Failed to find expected CE View contents')
133136
core.config['condor-ce.view-listening'] = True
134137

0 commit comments

Comments
 (0)