|
|
afe0d5 |
From ab2229451827f530959d554920619d87daa34586 Mon Sep 17 00:00:00 2001
|
|
|
afe0d5 |
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
|
|
|
afe0d5 |
Date: Wed, 11 Jul 2018 16:18:25 +0200
|
|
|
afe0d5 |
Subject: [PATCH] test: make Python files supported _also_ with Python 3.3+
|
|
|
afe0d5 |
MIME-Version: 1.0
|
|
|
afe0d5 |
Content-Type: text/plain; charset=UTF-8
|
|
|
afe0d5 |
Content-Transfer-Encoding: 8bit
|
|
|
afe0d5 |
|
|
|
afe0d5 |
- use "print" like a function rather than a statement
|
|
|
afe0d5 |
. where implicit newline is to be suppressed, don't do that
|
|
|
afe0d5 |
and rather strip it from the string to be printed instead
|
|
|
afe0d5 |
- use 2+3 compatible convention for parametrizing exceptions
|
|
|
afe0d5 |
- Python 3 doesn't recognize "basestring" class, and at the place
|
|
|
afe0d5 |
of use (pre Python 2.7 only), unicode string is really not expected
|
|
|
afe0d5 |
(also re.UNICODE flag is not used...)
|
|
|
afe0d5 |
- Python 3 doesn't recognize "xrange" function, but the surrounding
|
|
|
afe0d5 |
code can be reasonably simplified using "enumerate" function
|
|
|
afe0d5 |
- arrange dict treatment in a compatible way:
|
|
|
afe0d5 |
. d.has_key(k) -> k in d
|
|
|
afe0d5 |
. d.iteritems() -> custom "iter_items", always efficient wrapper
|
|
|
afe0d5 |
. d.iterkeys(), here incl. lazy mapping and filtering
|
|
|
afe0d5 |
-> rewrite while retaining laziness
|
|
|
afe0d5 |
. optimize UT.merge_dicts in script/unit-test.py along
|
|
|
afe0d5 |
- also in three instances, deal with string/uninterpreted bytes proper
|
|
|
afe0d5 |
dichotomy introduced in Python 3, and related to that, "string"
|
|
|
afe0d5 |
module only supports "ascii_lowercase" attribute in Python 3
|
|
|
afe0d5 |
(as opposed to system-specific plain "lowercase" one)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
Note that script/unit-test.py has a pre-existing issue (regardless
|
|
|
afe0d5 |
of which Python version interpreter is used), so at least document
|
|
|
afe0d5 |
that in the header for now.
|
|
|
afe0d5 |
|
|
|
afe0d5 |
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
|
|
|
afe0d5 |
---
|
|
|
afe0d5 |
script/unit-test.py | 65 ++++++++++++++++++++++++++------------------
|
|
|
afe0d5 |
test/assertions.py | 4 +--
|
|
|
afe0d5 |
test/boothrunner.py | 32 ++++++++++++----------
|
|
|
afe0d5 |
test/boothtestenv.py | 6 ++--
|
|
|
afe0d5 |
test/clienttests.py | 4 +--
|
|
|
afe0d5 |
test/runtests.py | 2 +-
|
|
|
afe0d5 |
test/serverenv.py | 18 ++++++------
|
|
|
afe0d5 |
test/servertests.py | 10 +++----
|
|
|
afe0d5 |
test/utils.py | 10 +++++--
|
|
|
afe0d5 |
9 files changed, 84 insertions(+), 67 deletions(-)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
diff --git a/script/unit-test.py b/script/unit-test.py
|
|
|
afe0d5 |
index 6871930..399528e 100755
|
|
|
afe0d5 |
--- a/script/unit-test.py
|
|
|
afe0d5 |
+++ b/script/unit-test.py
|
|
|
afe0d5 |
@@ -1,6 +1,8 @@
|
|
|
afe0d5 |
#!/usr/bin/python
|
|
|
afe0d5 |
# vim: fileencoding=utf-8
|
|
|
afe0d5 |
# see http://stackoverflow.com/questions/728891/correct-way-to-define-python-source-code-encoding
|
|
|
afe0d5 |
+# NOTE: setting the encoding is needed as non-ASCII characters are contained
|
|
|
afe0d5 |
+# FIXME: apparently, pexpect.EOF is not being excepted properly
|
|
|
afe0d5 |
|
|
|
afe0d5 |
import os, sys, time, signal, tempfile, socket, posix, time
|
|
|
afe0d5 |
import re, shutil, pexpect, logging, pprint
|
|
|
afe0d5 |
@@ -16,6 +18,16 @@ default_log_format = '%(asctime)s: : %(message)s'
|
|
|
afe0d5 |
default_log_datefmt = '%b %d %H:%M:%S'
|
|
|
afe0d5 |
|
|
|
afe0d5 |
|
|
|
afe0d5 |
+# Compatibility with dictionary methods not present in Python 3;
|
|
|
afe0d5 |
+# https://www.python.org/dev/peps/pep-0469/#migrating-to-the-common-subset-of-python-2-and-3
|
|
|
afe0d5 |
+try:
|
|
|
afe0d5 |
+ dict.iteritems
|
|
|
afe0d5 |
+except AttributeError: # Python 3
|
|
|
afe0d5 |
+ iter_items = lambda d: iter(d.items())
|
|
|
afe0d5 |
+else: # Python 2
|
|
|
afe0d5 |
+ iter_items = lambda d: d.iteritems()
|
|
|
afe0d5 |
+
|
|
|
afe0d5 |
+
|
|
|
afe0d5 |
# {{{ pexpect-logging glue
|
|
|
afe0d5 |
# needed for use as pexpect.logfile, to relay into existing logfiles
|
|
|
afe0d5 |
class expect_logging():
|
|
|
afe0d5 |
@@ -28,9 +40,12 @@ class expect_logging():
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def flush(self, *arg):
|
|
|
afe0d5 |
pass
|
|
|
afe0d5 |
+
|
|
|
afe0d5 |
def write(self, stg):
|
|
|
afe0d5 |
if self.test.dont_log_expect == 0:
|
|
|
afe0d5 |
# TODO: split by input/output, give program
|
|
|
afe0d5 |
+ if sys.version_info[0] >= 3:
|
|
|
afe0d5 |
+ stg = str(stg, 'UTF-8')
|
|
|
afe0d5 |
for line in re.split(r"[\r\n]+", stg):
|
|
|
afe0d5 |
if line == self.test.prompt:
|
|
|
afe0d5 |
continue
|
|
|
afe0d5 |
@@ -110,7 +125,7 @@ class UT():
|
|
|
afe0d5 |
res = re.match(r"^\s*(\w+)\s*:(?:\s*(#.*?\S))?\s*$", line)
|
|
|
afe0d5 |
if res:
|
|
|
afe0d5 |
state = res.group(1)
|
|
|
afe0d5 |
- if not m.has_key(state):
|
|
|
afe0d5 |
+ if state not in m:
|
|
|
afe0d5 |
m[state] = dict_plus()
|
|
|
afe0d5 |
if res.group(2):
|
|
|
afe0d5 |
m[state].aux["comment"] = res.group(2)
|
|
|
afe0d5 |
@@ -188,17 +203,15 @@ class UT():
|
|
|
afe0d5 |
name = re.sub(r".*/", "", bin)
|
|
|
afe0d5 |
# How to get stderr, too?
|
|
|
afe0d5 |
expct = pexpect.spawn(bin,
|
|
|
afe0d5 |
- env = dict( os.environ.items() +
|
|
|
afe0d5 |
- [('PATH',
|
|
|
afe0d5 |
- self.test_base + "/bin/:" +
|
|
|
afe0d5 |
- os.getenv('PATH')),
|
|
|
afe0d5 |
- ('UNIT_TEST_PATH', self.test_base),
|
|
|
afe0d5 |
- ('LC_ALL', 'C'),
|
|
|
afe0d5 |
- ('LANG', 'C')] +
|
|
|
afe0d5 |
- env_add ),
|
|
|
afe0d5 |
- timeout = 30,
|
|
|
afe0d5 |
- maxread = 32768,
|
|
|
afe0d5 |
- **args)
|
|
|
afe0d5 |
+ env=dict(os.environ, **dict({
|
|
|
afe0d5 |
+ 'PATH': ':'.join((self.test_base + "/bin/",
|
|
|
afe0d5 |
+ os.getenv('PATH'))),
|
|
|
afe0d5 |
+ 'UNIT_TEST_PATH': self.test_base,
|
|
|
afe0d5 |
+ 'LC_ALL': 'C',
|
|
|
afe0d5 |
+ 'LANG': 'C'}, **dict(env_add))),
|
|
|
afe0d5 |
+ timeout=30,
|
|
|
afe0d5 |
+ maxread=32768,
|
|
|
afe0d5 |
+ **args)
|
|
|
afe0d5 |
expct.setecho(False)
|
|
|
afe0d5 |
expct.logfile_read = expect_logging("<- %s" % name, self)
|
|
|
afe0d5 |
expct.logfile_send = expect_logging(" -> %s" % name, self)
|
|
|
afe0d5 |
@@ -361,7 +374,7 @@ class UT():
|
|
|
afe0d5 |
|
|
|
afe0d5 |
self.current_nr = kv.aux.get("line")
|
|
|
afe0d5 |
#os.system("strace -f -tt -s 2000 -e write -p" + str(self.gdb.pid) + " &")
|
|
|
afe0d5 |
- for n, v in kv.iteritems():
|
|
|
afe0d5 |
+ for n, v in iter_items(kv):
|
|
|
afe0d5 |
self.set_val( self.translate_shorthand(n, "ticket"), v)
|
|
|
afe0d5 |
logging.info("set state")
|
|
|
afe0d5 |
|
|
|
afe0d5 |
@@ -372,7 +385,7 @@ class UT():
|
|
|
afe0d5 |
if not sys.stdin.isatty():
|
|
|
afe0d5 |
logging.error("Not a terminal, stopping.")
|
|
|
afe0d5 |
else:
|
|
|
afe0d5 |
- print "\n\nEntering interactive mode.\n\n"
|
|
|
afe0d5 |
+ print("\n\nEntering interactive mode.\n\n")
|
|
|
afe0d5 |
self.gdb.sendline("set prompt GDB> \n")
|
|
|
afe0d5 |
self.gdb.setecho(True)
|
|
|
afe0d5 |
# can't use send_cmd, doesn't reply with expected prompt anymore.
|
|
|
afe0d5 |
@@ -415,7 +428,7 @@ class UT():
|
|
|
afe0d5 |
self.send_cmd("next")
|
|
|
afe0d5 |
|
|
|
afe0d5 |
# push message.
|
|
|
afe0d5 |
- for (n, v) in msg.iteritems():
|
|
|
afe0d5 |
+ for (n, v) in iter_items(msg):
|
|
|
afe0d5 |
self.set_val( self.translate_shorthand(n, "message"), v, "htonl")
|
|
|
afe0d5 |
|
|
|
afe0d5 |
# set "received" length
|
|
|
afe0d5 |
@@ -426,7 +439,7 @@ class UT():
|
|
|
afe0d5 |
def wait_outgoing(self, msg):
|
|
|
afe0d5 |
self.wait_for_function("booth_udp_send")
|
|
|
afe0d5 |
ok = True
|
|
|
afe0d5 |
- for (n, v) in msg.iteritems():
|
|
|
afe0d5 |
+ for (n, v) in iter_items(msg):
|
|
|
afe0d5 |
if re.search(r"\.", n):
|
|
|
afe0d5 |
ok = self.check_value( self.translate_shorthand(n, "inject"), v) and ok
|
|
|
afe0d5 |
else:
|
|
|
afe0d5 |
@@ -438,14 +451,12 @@ class UT():
|
|
|
afe0d5 |
#stopped_at = self.sync()
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def merge_dicts(self, base, overlay):
|
|
|
afe0d5 |
- return dict(base.items() + overlay.items())
|
|
|
afe0d5 |
+ return dict(base, **overlay)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def loop(self, fn, data):
|
|
|
afe0d5 |
- matches = map(lambda k: re.match(r"^(outgoing|message)(\d+)$", k), data.iterkeys())
|
|
|
afe0d5 |
- valid_matches = filter(None, matches)
|
|
|
afe0d5 |
- nums = map(lambda m: int(m.group(2)), valid_matches)
|
|
|
afe0d5 |
- loop_max = max(nums)
|
|
|
afe0d5 |
+ matches = (re.match(r"^(outgoing|message)(\d+)$", k) for k in data)
|
|
|
afe0d5 |
+ loop_max = max(int(m.group(2)) for m in matches if m)
|
|
|
afe0d5 |
for counter in range(0, loop_max+1): # incl. last message
|
|
|
afe0d5 |
|
|
|
afe0d5 |
kmsg = 'message%d' % counter
|
|
|
afe0d5 |
@@ -471,14 +482,14 @@ class UT():
|
|
|
afe0d5 |
logging.info("ticket change %s (%s:%d) %s" % (ktkt, fn, self.current_nr, comment))
|
|
|
afe0d5 |
self.set_state(tkt)
|
|
|
afe0d5 |
if gdb:
|
|
|
afe0d5 |
- for (k, v) in gdb.iteritems():
|
|
|
afe0d5 |
+ for (k, v) in iter_items(gdb):
|
|
|
afe0d5 |
self.send_cmd(k + " " + v.replace("§", "\n"))
|
|
|
afe0d5 |
if msg:
|
|
|
afe0d5 |
self.current_nr = msg.aux.get("line")
|
|
|
afe0d5 |
comment = msg.aux.get("comment", "")
|
|
|
afe0d5 |
logging.info("sending %s (%s:%d) %s" % (kmsg, fn, self.current_nr, comment))
|
|
|
afe0d5 |
self.send_message(self.merge_dicts(data["message"], msg))
|
|
|
afe0d5 |
- if data.has_key(kgdb) and len(gdb) == 0:
|
|
|
afe0d5 |
+ if kgdb in data and len(gdb) == 0:
|
|
|
afe0d5 |
self.user_debug("manual override")
|
|
|
afe0d5 |
if out:
|
|
|
afe0d5 |
self.current_nr = out.aux.get("line")
|
|
|
afe0d5 |
@@ -520,7 +531,7 @@ class UT():
|
|
|
afe0d5 |
self.let_booth_go_a_bit()
|
|
|
afe0d5 |
|
|
|
afe0d5 |
ok = True
|
|
|
afe0d5 |
- for (n, v) in data.iteritems():
|
|
|
afe0d5 |
+ for (n, v) in iter_items(data):
|
|
|
afe0d5 |
ok = self.check_value( self.translate_shorthand(n, "ticket"), v) and ok
|
|
|
afe0d5 |
if not ok:
|
|
|
afe0d5 |
sys.exit(1)
|
|
|
afe0d5 |
@@ -529,8 +540,8 @@ class UT():
|
|
|
afe0d5 |
def run(self, start_from="000", end_with="999"):
|
|
|
afe0d5 |
os.chdir(self.test_base)
|
|
|
afe0d5 |
# TODO: sorted, random order
|
|
|
afe0d5 |
- tests = filter( (lambda f: re.match(r"^\d\d\d_.*\.txt$", f)), glob.glob("*"))
|
|
|
afe0d5 |
- tests.sort()
|
|
|
afe0d5 |
+ tests = sorted(f for f in glob.glob("*")
|
|
|
afe0d5 |
+ if re.match(r"^\d\d\d_.*\.txt$", f))
|
|
|
afe0d5 |
failed = 0
|
|
|
afe0d5 |
for f in tests:
|
|
|
afe0d5 |
if f[0:3] < start_from:
|
|
|
afe0d5 |
@@ -561,7 +572,7 @@ class UT():
|
|
|
afe0d5 |
except:
|
|
|
afe0d5 |
failed += 1
|
|
|
afe0d5 |
logging.error(self.colored_string("Broke in %s:%s %s" % (f, self.current_nr, sys.exc_info()), self.RED))
|
|
|
afe0d5 |
- for frame in traceback.format_tb(sys.exc_traceback):
|
|
|
afe0d5 |
+ for frame in traceback.format_tb(sys.exc_info()[2]):
|
|
|
afe0d5 |
logging.info(" - %s " % frame.rstrip())
|
|
|
afe0d5 |
finally:
|
|
|
afe0d5 |
self.stop_processes()
|
|
|
afe0d5 |
diff --git a/test/assertions.py b/test/assertions.py
|
|
|
afe0d5 |
index 0b7f995..34333ca 100644
|
|
|
afe0d5 |
--- a/test/assertions.py
|
|
|
afe0d5 |
+++ b/test/assertions.py
|
|
|
afe0d5 |
@@ -21,7 +21,7 @@ class BoothAssertions:
|
|
|
afe0d5 |
# backported from 2.7 just in case we're running on an older Python
|
|
|
afe0d5 |
def assertRegexpMatches(self, text, expected_regexp, msg=None):
|
|
|
afe0d5 |
"""Fail the test unless the text matches the regular expression."""
|
|
|
afe0d5 |
- if isinstance(expected_regexp, basestring):
|
|
|
afe0d5 |
+ if isinstance(expected_regexp, str):
|
|
|
afe0d5 |
expected_regexp = re.compile(expected_regexp)
|
|
|
afe0d5 |
if not expected_regexp.search(text, MULTILINE):
|
|
|
afe0d5 |
msg = msg or "Regexp didn't match"
|
|
|
afe0d5 |
@@ -30,7 +30,7 @@ class BoothAssertions:
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
|
|
|
afe0d5 |
"""Fail the test if the text matches the regular expression."""
|
|
|
afe0d5 |
- if isinstance(unexpected_regexp, basestring):
|
|
|
afe0d5 |
+ if isinstance(unexpected_regexp, str):
|
|
|
afe0d5 |
unexpected_regexp = re.compile(unexpected_regexp)
|
|
|
afe0d5 |
match = unexpected_regexp.search(text)
|
|
|
afe0d5 |
if match:
|
|
|
afe0d5 |
diff --git a/test/boothrunner.py b/test/boothrunner.py
|
|
|
afe0d5 |
index d981183..347912b 100644
|
|
|
afe0d5 |
--- a/test/boothrunner.py
|
|
|
afe0d5 |
+++ b/test/boothrunner.py
|
|
|
afe0d5 |
@@ -1,4 +1,5 @@
|
|
|
afe0d5 |
import os
|
|
|
afe0d5 |
+import sys
|
|
|
afe0d5 |
import subprocess
|
|
|
afe0d5 |
import time
|
|
|
afe0d5 |
import unittest
|
|
|
afe0d5 |
@@ -37,14 +38,14 @@ class BoothRunner:
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def show_output(self, stdout, stderr):
|
|
|
afe0d5 |
if stdout:
|
|
|
afe0d5 |
- print "STDOUT:"
|
|
|
afe0d5 |
- print "------"
|
|
|
afe0d5 |
- print stdout,
|
|
|
afe0d5 |
+ print("STDOUT:")
|
|
|
afe0d5 |
+ print("------")
|
|
|
afe0d5 |
+ print(stdout.rstrip('\n'))
|
|
|
afe0d5 |
if stderr:
|
|
|
afe0d5 |
- print "STDERR: (N.B. crm_ticket failures indicate daemon started correctly)"
|
|
|
afe0d5 |
- print "------"
|
|
|
afe0d5 |
- print stderr,
|
|
|
afe0d5 |
- print "-" * 70
|
|
|
afe0d5 |
+ print("STDERR: (N.B. crm_ticket failures indicate daemon started correctly)")
|
|
|
afe0d5 |
+ print("------")
|
|
|
afe0d5 |
+ print(stderr.rstrip('\n'))
|
|
|
afe0d5 |
+ print("-" * 70)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def subproc_completed_within(self, p, timeout):
|
|
|
afe0d5 |
start = time.time()
|
|
|
afe0d5 |
@@ -55,7 +56,7 @@ class BoothRunner:
|
|
|
afe0d5 |
elapsed = time.time() - start
|
|
|
afe0d5 |
if elapsed + wait > timeout:
|
|
|
afe0d5 |
wait = timeout - elapsed
|
|
|
afe0d5 |
- print "Waiting on %d for %.1fs ..." % (p.pid, wait)
|
|
|
afe0d5 |
+ print("Waiting on %d for %.1fs ..." % (p.pid, wait))
|
|
|
afe0d5 |
time.sleep(wait)
|
|
|
afe0d5 |
elapsed = time.time() - start
|
|
|
afe0d5 |
if elapsed >= timeout:
|
|
|
afe0d5 |
@@ -83,26 +84,29 @@ class BoothRunner:
|
|
|
afe0d5 |
return text
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def show_args(self):
|
|
|
afe0d5 |
- print "\n"
|
|
|
afe0d5 |
- print "-" * 70
|
|
|
afe0d5 |
- print "Running", ' '.join(self.all_args())
|
|
|
afe0d5 |
+ print("\n")
|
|
|
afe0d5 |
+ print("-" * 70)
|
|
|
afe0d5 |
+ print("Running", ' '.join(self.all_args()))
|
|
|
afe0d5 |
msg = "with config from %s" % self.config_file_used()
|
|
|
afe0d5 |
config_text = self.config_text_used()
|
|
|
afe0d5 |
if config_text is not None:
|
|
|
afe0d5 |
msg += ": [%s]" % config_text
|
|
|
afe0d5 |
- print msg
|
|
|
afe0d5 |
+ print(msg)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def run(self):
|
|
|
afe0d5 |
p = subprocess.Popen(self.all_args(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
afe0d5 |
if not p:
|
|
|
afe0d5 |
- raise RuntimeError, "failed to start subprocess"
|
|
|
afe0d5 |
+ raise RuntimeError("failed to start subprocess")
|
|
|
afe0d5 |
|
|
|
afe0d5 |
- print "Started subprocess pid %d" % p.pid
|
|
|
afe0d5 |
+ print("Started subprocess pid %d" % p.pid)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
completed = self.subproc_completed_within(p, 2)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
if completed:
|
|
|
afe0d5 |
(stdout, stderr) = p.communicate()
|
|
|
afe0d5 |
+ if sys.version_info[0] >= 3:
|
|
|
afe0d5 |
+ # only expect ASCII/UTF-8 encodings for the obtained input bytes
|
|
|
afe0d5 |
+ stdout, stderr = str(stdout, 'UTF-8'), str(stderr, 'UTF-8')
|
|
|
afe0d5 |
self.show_output(stdout, stderr)
|
|
|
afe0d5 |
return (p.pid, p.returncode, stdout, stderr)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
diff --git a/test/boothtestenv.py b/test/boothtestenv.py
|
|
|
afe0d5 |
index fcd0c4d..59e25c3 100644
|
|
|
afe0d5 |
--- a/test/boothtestenv.py
|
|
|
afe0d5 |
+++ b/test/boothtestenv.py
|
|
|
afe0d5 |
@@ -17,7 +17,7 @@ class BoothTestEnvironment(unittest.TestCase, BoothAssertions):
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def setUp(self):
|
|
|
afe0d5 |
if not self._testMethodName.startswith('test_'):
|
|
|
afe0d5 |
- raise RuntimeError, "unexpected test method name: " + self._testMethodName
|
|
|
afe0d5 |
+ raise RuntimeError("unexpected test method name: " + self._testMethodName)
|
|
|
afe0d5 |
self.test_name = self._testMethodName[5:]
|
|
|
afe0d5 |
self.test_path = os.path.join(self.test_run_path, self.test_name)
|
|
|
afe0d5 |
os.makedirs(self.test_path)
|
|
|
afe0d5 |
@@ -54,11 +54,11 @@ class BoothTestEnvironment(unittest.TestCase, BoothAssertions):
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def check_return_code(self, pid, return_code, expected_exitcode):
|
|
|
afe0d5 |
if return_code is None:
|
|
|
afe0d5 |
- print "pid %d still running" % pid
|
|
|
afe0d5 |
+ print("pid %d still running" % pid)
|
|
|
afe0d5 |
if expected_exitcode is not None:
|
|
|
afe0d5 |
self.fail("expected exit code %d, not long-running process" % expected_exitcode)
|
|
|
afe0d5 |
else:
|
|
|
afe0d5 |
- print "pid %d exited with code %d" % (pid, return_code)
|
|
|
afe0d5 |
+ print("pid %d exited with code %d" % (pid, return_code))
|
|
|
afe0d5 |
if expected_exitcode is None:
|
|
|
afe0d5 |
msg = "should not exit"
|
|
|
afe0d5 |
else:
|
|
|
afe0d5 |
diff --git a/test/clienttests.py b/test/clienttests.py
|
|
|
afe0d5 |
index c4b9d8a..512620e 100644
|
|
|
afe0d5 |
--- a/test/clienttests.py
|
|
|
afe0d5 |
+++ b/test/clienttests.py
|
|
|
afe0d5 |
@@ -7,14 +7,14 @@ class ClientConfigTests(ClientTestEnvironment):
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def test_site_buffer_overflow(self):
|
|
|
afe0d5 |
# https://bugzilla.novell.com/show_bug.cgi?id=750256
|
|
|
afe0d5 |
- longfile = (string.lowercase * 3)[:63]
|
|
|
afe0d5 |
+ longfile = (string.ascii_lowercase * 3)[:63]
|
|
|
afe0d5 |
expected_error = "'%s' exceeds maximum site name length" % longfile
|
|
|
afe0d5 |
args = [ 'grant', '-s', longfile, '-t', 'ticket' ]
|
|
|
afe0d5 |
self._test_buffer_overflow(expected_error, args=args)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def test_ticket_buffer_overflow(self):
|
|
|
afe0d5 |
# https://bugzilla.novell.com/show_bug.cgi?id=750256
|
|
|
afe0d5 |
- longfile = (string.lowercase * 3)[:63]
|
|
|
afe0d5 |
+ longfile = (string.ascii_lowercase * 3)[:63]
|
|
|
afe0d5 |
expected_error = "'%s' exceeds maximum ticket name length" % longfile
|
|
|
afe0d5 |
args = [ 'grant', '-s', 'site', '-t', longfile ]
|
|
|
afe0d5 |
self._test_buffer_overflow(expected_error, args=args)
|
|
|
afe0d5 |
diff --git a/test/runtests.py b/test/runtests.py
|
|
|
afe0d5 |
index 0532c01..833b1a7 100755
|
|
|
afe0d5 |
--- a/test/runtests.py
|
|
|
afe0d5 |
+++ b/test/runtests.py
|
|
|
afe0d5 |
@@ -53,5 +53,5 @@ if __name__ == '__main__':
|
|
|
afe0d5 |
shutil.rmtree(test_run_path)
|
|
|
afe0d5 |
sys.exit(0)
|
|
|
afe0d5 |
else:
|
|
|
afe0d5 |
- print "Left %s for debugging" % test_run_path
|
|
|
afe0d5 |
+ print("Left %s for debugging" % test_run_path)
|
|
|
afe0d5 |
sys.exit(1)
|
|
|
afe0d5 |
diff --git a/test/serverenv.py b/test/serverenv.py
|
|
|
afe0d5 |
index c6d4e30..5d6c6c4 100644
|
|
|
afe0d5 |
--- a/test/serverenv.py
|
|
|
afe0d5 |
+++ b/test/serverenv.py
|
|
|
afe0d5 |
@@ -73,12 +73,10 @@ ticket="ticketB"
|
|
|
afe0d5 |
where return_code/stdout/stderr are None iff pid is still running.
|
|
|
afe0d5 |
'''
|
|
|
afe0d5 |
if expected_daemon and expected_exitcode is not None and expected_exitcode != 0:
|
|
|
afe0d5 |
- raise RuntimeError, \
|
|
|
afe0d5 |
- "Shouldn't ever expect daemon to start and then failure"
|
|
|
afe0d5 |
+ raise RuntimeError("Shouldn't ever expect daemon to start and then failure")
|
|
|
afe0d5 |
|
|
|
afe0d5 |
if not expected_daemon and expected_exitcode == 0:
|
|
|
afe0d5 |
- raise RuntimeError, \
|
|
|
afe0d5 |
- "Shouldn't ever expect success without starting daemon"
|
|
|
afe0d5 |
+ raise RuntimeError("Shouldn't ever expect success without starting daemon")
|
|
|
afe0d5 |
|
|
|
afe0d5 |
self.init_log()
|
|
|
afe0d5 |
|
|
|
afe0d5 |
@@ -122,9 +120,9 @@ ticket="ticketB"
|
|
|
afe0d5 |
return config_file
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def kill_pid(self, pid):
|
|
|
afe0d5 |
- print "killing %d ..." % pid
|
|
|
afe0d5 |
+ print("killing %d ..." % pid)
|
|
|
afe0d5 |
os.kill(pid, 15)
|
|
|
afe0d5 |
- print "killed"
|
|
|
afe0d5 |
+ print("killed")
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def check_daemon_handling(self, runner, expected_daemon):
|
|
|
afe0d5 |
'''
|
|
|
afe0d5 |
@@ -154,7 +152,7 @@ ticket="ticketB"
|
|
|
afe0d5 |
Returns the pid contained in lock_file, or None if it doesn't exist.
|
|
|
afe0d5 |
'''
|
|
|
afe0d5 |
if not os.path.exists(lock_file):
|
|
|
afe0d5 |
- print "%s does not exist" % lock_file
|
|
|
afe0d5 |
+ print("%s does not exist" % lock_file)
|
|
|
afe0d5 |
return None
|
|
|
afe0d5 |
|
|
|
afe0d5 |
l = open(lock_file)
|
|
|
afe0d5 |
@@ -162,7 +160,7 @@ ticket="ticketB"
|
|
|
afe0d5 |
l.close()
|
|
|
afe0d5 |
self.assertEqual(len(lines), 1, "Lock file should contain one line")
|
|
|
afe0d5 |
pid = re.search('\\bbooth_pid="?(\\d+)"?', lines[0]).group(1)
|
|
|
afe0d5 |
- print "lockfile contains: <%s>" % pid
|
|
|
afe0d5 |
+ print("lockfile contains: <%s>" % pid)
|
|
|
afe0d5 |
return pid
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def is_pid_running_daemon(self, pid):
|
|
|
afe0d5 |
@@ -185,11 +183,11 @@ ticket="ticketB"
|
|
|
afe0d5 |
|
|
|
afe0d5 |
c = open("/proc/%s/cmdline" % pid)
|
|
|
afe0d5 |
cmdline = "".join(c.readlines())
|
|
|
afe0d5 |
- print cmdline
|
|
|
afe0d5 |
+ print(cmdline)
|
|
|
afe0d5 |
c.close()
|
|
|
afe0d5 |
|
|
|
afe0d5 |
if cmdline.find('boothd') == -1:
|
|
|
afe0d5 |
- print 'no boothd in cmdline:', cmdline
|
|
|
afe0d5 |
+ print('no boothd in cmdline:', cmdline)
|
|
|
afe0d5 |
return False
|
|
|
afe0d5 |
|
|
|
afe0d5 |
# self.assertRegexpMatches(
|
|
|
afe0d5 |
diff --git a/test/servertests.py b/test/servertests.py
|
|
|
afe0d5 |
index 71e808e..288d19f 100644
|
|
|
afe0d5 |
--- a/test/servertests.py
|
|
|
afe0d5 |
+++ b/test/servertests.py
|
|
|
afe0d5 |
@@ -35,13 +35,13 @@ class ServerTests(ServerTestEnvironment):
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def test_config_file_buffer_overflow(self):
|
|
|
afe0d5 |
# https://bugzilla.novell.com/show_bug.cgi?id=750256
|
|
|
afe0d5 |
- longfile = (string.lowercase * 5)[:127]
|
|
|
afe0d5 |
+ longfile = (string.ascii_lowercase * 5)[:127]
|
|
|
afe0d5 |
expected_error = "'%s' exceeds maximum config name length" % longfile
|
|
|
afe0d5 |
self._test_buffer_overflow(expected_error, config_file=longfile)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def test_lock_file_buffer_overflow(self):
|
|
|
afe0d5 |
# https://bugzilla.novell.com/show_bug.cgi?id=750256
|
|
|
afe0d5 |
- longfile = (string.lowercase * 5)[:127]
|
|
|
afe0d5 |
+ longfile = (string.ascii_lowercase * 5)[:127]
|
|
|
afe0d5 |
expected_error = "'%s' exceeds maximum lock file length" % longfile
|
|
|
afe0d5 |
self._test_buffer_overflow(expected_error, lock_file=longfile)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
@@ -54,12 +54,12 @@ class ServerTests(ServerTestEnvironment):
|
|
|
afe0d5 |
# quotes no longer required
|
|
|
afe0d5 |
return True
|
|
|
afe0d5 |
orig_lines = self.working_config.split("\n")
|
|
|
afe0d5 |
- for i in xrange(len(orig_lines)):
|
|
|
afe0d5 |
+ for (i, line) in enumerate(orig_lines):
|
|
|
afe0d5 |
new_lines = copy.copy(orig_lines)
|
|
|
afe0d5 |
- new_lines[i] = new_lines[i].replace('"', '')
|
|
|
afe0d5 |
+ new_lines[i] = line.replace('"', '')
|
|
|
afe0d5 |
new_config = "\n".join(new_lines)
|
|
|
afe0d5 |
|
|
|
afe0d5 |
- line_contains_IP = re.search('^\s*(site|arbitrator)=.*[0-9]\.', orig_lines[i])
|
|
|
afe0d5 |
+ line_contains_IP = re.search('^\s*(site|arbitrator)=.*[0-9]\.', line)
|
|
|
afe0d5 |
if line_contains_IP:
|
|
|
afe0d5 |
# IP addresses need to be surrounded by quotes,
|
|
|
afe0d5 |
# so stripping them should cause it to fail
|
|
|
afe0d5 |
diff --git a/test/utils.py b/test/utils.py
|
|
|
afe0d5 |
index 5b70cfc..aca3592 100644
|
|
|
afe0d5 |
--- a/test/utils.py
|
|
|
afe0d5 |
+++ b/test/utils.py
|
|
|
afe0d5 |
@@ -1,5 +1,6 @@
|
|
|
afe0d5 |
import subprocess
|
|
|
afe0d5 |
import re
|
|
|
afe0d5 |
+import sys
|
|
|
afe0d5 |
|
|
|
afe0d5 |
def run_cmd(cmd):
|
|
|
afe0d5 |
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
afe0d5 |
@@ -9,8 +10,11 @@ def run_cmd(cmd):
|
|
|
afe0d5 |
def get_IP():
|
|
|
afe0d5 |
(stdout, stderr, returncode) = run_cmd(['hostname', '-i'])
|
|
|
afe0d5 |
if returncode != 0:
|
|
|
afe0d5 |
- raise RuntimeError, "Failed to run hostname -i:\n" + stderr
|
|
|
afe0d5 |
+ raise RuntimeError("Failed to run hostname -i:\n" + stderr)
|
|
|
afe0d5 |
# in case multiple IP addresses are returned, use only the first
|
|
|
afe0d5 |
- # and also strip '%<device>' part possibly present with IPv6 address
|
|
|
afe0d5 |
- ret = re.sub(r'\s.*', '', stdout)
|
|
|
afe0d5 |
+ # and also strip '%<device>' part possibly present with IPv6 address;
|
|
|
afe0d5 |
+ # in Python 3 context, only expect ASCII/UTF-8 encodings for the
|
|
|
afe0d5 |
+ # obtained input bytes
|
|
|
afe0d5 |
+ ret = re.sub(r'\s.*', '',
|
|
|
afe0d5 |
+ stdout if sys.version_info[0] < 3 else str(stdout, 'UTF-8'))
|
|
|
afe0d5 |
return "::1" if '%' in ret else ret
|
|
|
afe0d5 |
--
|
|
|
afe0d5 |
2.18.0.rc2
|
|
|
afe0d5 |
|