diff -Nru realmd-0.16.3/debian/changelog realmd-0.16.3/debian/changelog --- realmd-0.16.3/debian/changelog 2018-05-01 06:51:22.000000000 +0000 +++ realmd-0.16.3/debian/changelog 2019-10-02 15:26:19.000000000 +0000 @@ -1,3 +1,16 @@ +realmd (0.16.3-3) unstable; urgency=medium + + [ Andreas Henriksson ] + * Switch to using python3 during build (Closes: #938339) + * Cherry-pick patch from upstream to fix test failure (Closes: #935294) + + [ Laurent Bigonville ] + * Fix FTBFS with glib 2.62 (patch from upstream) (Closes: #940159) + * debian/control: Bump Standards-Version to 4.4.1 (no further changes) + * Bump debhelper compatibility to 12 + + -- Laurent Bigonville Wed, 02 Oct 2019 17:26:19 +0200 + realmd (0.16.3-2) unstable; urgency=medium * Team upload. diff -Nru realmd-0.16.3/debian/compat realmd-0.16.3/debian/compat --- realmd-0.16.3/debian/compat 2018-05-01 06:51:22.000000000 +0000 +++ realmd-0.16.3/debian/compat 2019-10-02 15:26:19.000000000 +0000 @@ -1 +1 @@ -10 +12 diff -Nru realmd-0.16.3/debian/control realmd-0.16.3/debian/control --- realmd-0.16.3/debian/control 2018-05-01 06:51:22.000000000 +0000 +++ realmd-0.16.3/debian/control 2019-10-02 15:26:19.000000000 +0000 @@ -3,7 +3,7 @@ Priority: optional Maintainer: Utopia Maintenance Team Uploaders: Laurent Bigonville -Build-Depends: debhelper (>= 10), +Build-Depends: debhelper (>= 12), intltool (>= 0.35.0), libglib2.0-dev (>= 2.39.1), libkrb5-dev, @@ -11,10 +11,10 @@ libpolkit-gobject-1-dev, libsystemd-dev [linux-any], pkg-config, - python:any, + python3:any, xmlto, xsltproc -Standards-Version: 4.1.4 +Standards-Version: 4.4.1 Homepage: https://www.freedesktop.org/software/realmd/ Vcs-Git: https://salsa.debian.org/utopia-team/realmd.git Vcs-Browser: https://salsa.debian.org/utopia-team/realmd diff -Nru realmd-0.16.3/debian/patches/remove-support-for-deprecated-gtester-format.patch realmd-0.16.3/debian/patches/remove-support-for-deprecated-gtester-format.patch --- realmd-0.16.3/debian/patches/remove-support-for-deprecated-gtester-format.patch 1970-01-01 00:00:00.000000000 +0000 +++ realmd-0.16.3/debian/patches/remove-support-for-deprecated-gtester-format.patch 2019-10-02 15:26:19.000000000 +0000 @@ -0,0 +1,252 @@ +From 5ae42c176e7bb550fc6cf10f29e75f58c733ae4f Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 2 Aug 2019 12:10:43 +0200 +Subject: [PATCH] Remove support for deprecated gtester format + +Support for the already deprecated gtester format was remove from recent +versions of glib2 but the test still call the tab-gtester conversion +tool. + +This patch removes tab-gtester and the tab format is used directly. + +Related to https://gitlab.freedesktop.org/realmd/realmd/issues/21 +--- + Makefile.am | 3 +- + build/tap-gtester | 204 ---------------------------------------------- + 2 files changed, 1 insertion(+), 206 deletions(-) + delete mode 100755 build/tap-gtester + +diff --git a/Makefile.am b/Makefile.am +index 27e3494..4ffd5b4 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -161,7 +161,7 @@ endif + # + + LOG_DRIVER = $(top_srcdir)/build/tap-driver +-LOG_COMPILER = $(top_srcdir)/build/tap-gtester ++LOG_COMPILER = sh -c '"$$0" "$$@" --tap' + + VALGRIND_ARGS = --trace-children=no --quiet --error-exitcode=33 \ + --suppressions=valgrind-suppressions --gen-suppressions=all \ +@@ -183,7 +183,6 @@ recheck-memory: valgrind-suppressions + + EXTRA_DIST += \ + $(LOG_DRIVER) \ +- $(LOG_COMPILER) \ + $(VALGRIND_SUPPRESSIONS) \ + $(NULL) + +diff --git a/build/tap-gtester b/build/tap-gtester +deleted file mode 100755 +index bbda266..0000000 +--- a/build/tap-gtester ++++ /dev/null +@@ -1,204 +0,0 @@ +-#!/usr/bin/python3 +-# This can also be run with Python 2. +- +-# Copyright (C) 2014 Red Hat, Inc. +-# +-# Cockpit is free software; you can redistribute it and/or modify it +-# under the terms of the GNU Lesser General Public License as published by +-# the Free Software Foundation; either version 2.1 of the License, or +-# (at your option) any later version. +-# +-# Cockpit is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# Lesser General Public License for more details. +-# +-# You should have received a copy of the GNU Lesser General Public License +-# along with Cockpit; If not, see . +- +-# +-# This is a test output compiler which produces TAP from GTest output +-# if GTest output is detected. +-# +-# Versions of glib later than 2.38.x output TAP natively when tests are +-# run with the --tap option. However we can't depend on such a recent +-# version of glib for our purposes. +-# +-# This implements the Test Anything Protocol (ie: TAP) +-# https://metacpan.org/pod/release/PETDANCE/Test-Harness-2.64/lib/Test/Harness/TAP.pod +-# +- +-import argparse +-import os +-import select +-import signal +-import subprocess +-import sys +- +-# Yes, it's dumb, but strsignal is not exposed in python +-# In addition signal numbers varify heavily from arch to arch +-def strsignal(sig): +- for name in dir(signal): +- if name.startswith("SIG") and sig == getattr(signal, name): +- return name +- return str(sig) +- +- +-class NullCompiler: +- def __init__(self, command): +- self.command = command +- +- def input(self, line): +- sys.stdout.write(line) +- +- def process(self, proc): +- while True: +- line = proc.stdout.readline() +- if not line: +- break +- self.input(line) +- proc.wait() +- return proc.returncode +- +- def run(self, proc, line=None): +- if line: +- self.input(line) +- return self.process(proc) +- +- +-class GTestCompiler(NullCompiler): +- def __init__(self, filename): +- NullCompiler.__init__(self, filename) +- self.test_num = 0 +- self.test_name = None +- self.test_remaining = [] +- +- def input(self, line): +- line = line.strip() +- if line.startswith("GTest: "): +- (cmd, unused, data) = line[7:].partition(": ") +- cmd = cmd.strip() +- data = data.strip() +- if cmd == "run": +- self.test_name = data +- assert self.test_name in self.test_remaining, "%s %s" % (self.test_name, repr(self.test_remaining)) +- self.test_remaining.remove(self.test_name) +- self.test_num += 1 +- elif cmd == "result": +- if self.test_name: +- if data == "OK": +- print("ok %d %s" % (self.test_num, self.test_name)) +- if data == "FAIL": +- print("not ok %d %s" % (self.test_num, self.test_name)) +- self.test_name = None +- elif cmd == "skipping": +- if "/subprocess" not in data: +- print("ok %d # skip -- %s" % (self.test_num, data)) +- self.test_name = None +- elif data: +- print("# %s: %s" % (cmd, data)) +- else: +- print("# %s" % cmd) +- elif line.startswith("(MSG: "): +- print("# %s" % line[6:-1]) +- elif line: +- print("# %s" % line) +- sys.stdout.flush() +- +- def run(self, proc, output=""): +- # Complete retrieval of the list of tests +- output += proc.stdout.read() +- proc.wait() +- if proc.returncode: +- sys.stderr.write("tap-gtester: listing GTest tests failed: %d\n" % proc.returncode) +- return proc.returncode +- self.test_remaining = [] +- for line in output.split("\n"): +- if line.startswith("/"): +- self.test_remaining.append(line.strip()) +- if not self.test_remaining: +- print("Bail out! No tests found in GTest: %s" % self.command[0]) +- return 0 +- +- print("1..%d" % len(self.test_remaining)) +- +- # First try to run all the tests in a batch +- proc = subprocess.Popen(self.command + ["--verbose" ], close_fds=True, +- stdout=subprocess.PIPE, universal_newlines=True) +- result = self.process(proc) +- if result == 0: +- return 0 +- +- if result < 0: +- sys.stderr.write("%s terminated with %s\n" % (self.command[0], strsignal(-result))) +- +- # Now pick up any stragglers due to failures +- while True: +- # Assume that the last test failed +- if self.test_name: +- print("not ok %d %s" % (self.test_num, self.test_name)) +- self.test_name = None +- +- # Run any tests which didn't get run +- if not self.test_remaining: +- break +- +- proc = subprocess.Popen(self.command + ["--verbose", "-p", self.test_remaining[0]], +- close_fds=True, stdout=subprocess.PIPE, +- universal_newlines=True) +- result = self.process(proc) +- +- # The various exit codes and signals we continue for +- if result not in [ 0, 1, -4, -5, -6, -7, -8, -11, 33 ]: +- break +- +- return result +- +-def main(argv): +- parser = argparse.ArgumentParser(description='Automake TAP compiler', +- usage="tap-gtester [--format FORMAT] command ...") +- parser.add_argument('--format', metavar='FORMAT', choices=[ "auto", "gtest", "tap" ], +- default="auto", help='The input format to compile') +- parser.add_argument('--verbose', action='store_true', +- default=True, help='Verbose mode (ignored)') +- parser.add_argument('command', nargs=argparse.REMAINDER, help="A test command to run") +- args = parser.parse_args(argv[1:]) +- +- output = None +- format = args.format +- cmd = args.command +- if not cmd: +- sys.stderr.write("tap-gtester: specify a command to run\n") +- return 2 +- if cmd[0] == '--': +- cmd.pop(0) +- +- proc = None +- +- os.environ['HARNESS_ACTIVE'] = '1' +- +- if format in ["auto", "gtest"]: +- list_cmd = cmd + ["-l", "--verbose"] +- proc = subprocess.Popen(list_cmd, close_fds=True, stdout=subprocess.PIPE, +- universal_newlines=True) +- output = proc.stdout.readline() +- # Smell whether we're dealing with GTest list output from first line +- if "random seed" in output or "GTest" in output or output.startswith("/"): +- format = "gtest" +- else: +- format = "tap" +- else: +- proc = subprocess.Popen(cmd, close_fds=True, stdout=subprocess.PIPE, +- universal_newlines=True) +- +- if format == "gtest": +- compiler = GTestCompiler(cmd) +- elif format == "tap": +- compiler = NullCompiler(cmd) +- else: +- assert False, "not reached" +- +- return compiler.run(proc, output) +- +-if __name__ == "__main__": +- sys.exit(main(sys.argv)) +-- +2.22.0 + diff -Nru realmd-0.16.3/debian/patches/series realmd-0.16.3/debian/patches/series --- realmd-0.16.3/debian/patches/series 2018-05-01 06:51:22.000000000 +0000 +++ realmd-0.16.3/debian/patches/series 2019-10-02 15:26:19.000000000 +0000 @@ -1,2 +1,5 @@ 01_freeipa_section.patch 02_cross.patch +tests-use-python3.patch +tests-ignore-order.patch +remove-support-for-deprecated-gtester-format.patch diff -Nru realmd-0.16.3/debian/patches/tests-ignore-order.patch realmd-0.16.3/debian/patches/tests-ignore-order.patch --- realmd-0.16.3/debian/patches/tests-ignore-order.patch 1970-01-01 00:00:00.000000000 +0000 +++ realmd-0.16.3/debian/patches/tests-ignore-order.patch 2019-10-02 15:26:19.000000000 +0000 @@ -0,0 +1,84 @@ +From b6753bd048b4012b11d60c094d1ab6ca181ee50d Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 21 Feb 2019 21:16:26 +0100 +Subject: tests: ignore order in test_update_domain + +Individual options of a domain or in general for a section in an ini +file are stored by realmd in a hash table. When writing out the ini file +the options can show up in any order and the unit tests should be aware +of it. + +Resolves: https://gitlab.freedesktop.org/realmd/realmd/issues/19 +--- + tests/test-sssd-config.c | 41 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 39 insertions(+), 2 deletions(-) + +(limited to 'tests') + +diff --git a/tests/test-sssd-config.c b/tests/test-sssd-config.c +index 59eab75..8f3fec5 100644 +--- a/tests/test-sssd-config.c ++++ b/tests/test-sssd-config.c +@@ -163,12 +163,49 @@ test_add_domain_only (Test *test, + g_free (output); + } + ++static void check_for_test_update_domain (char *new) ++{ ++ char *token; ++ char *saveptr; ++ size_t c; ++ int result = 0; ++ ++ token = strtok_r (new, "\n", &saveptr); ++ g_assert_nonnull (token); ++ g_assert_cmpstr (token, ==, "[domain/one]"); ++ ++ for (c = 0; c < 3; c++) { ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_nonnull (token); ++ if (strcmp (token, "val=1") == 0) { ++ result += 1; ++ } else if (strcmp (token, "uno = 1") == 0) { ++ result += 2; ++ } else if (strcmp (token, "eins = one") == 0) { ++ result += 4; ++ } else { ++ g_assert_not_reached (); ++ } ++ } ++ g_assert_cmpint (result, ==, 7); ++ ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_nonnull (token); ++ g_assert_cmpstr (token, ==, "[sssd]"); ++ ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_nonnull (token); ++ g_assert_cmpstr (token, ==, "domains=one"); ++ ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_null (token); ++} ++ + static void + test_update_domain (Test *test, + gconstpointer unused) + { + const gchar *data = "[domain/one]\nval=1\n[sssd]\ndomains=one"; +- const gchar *check = "[domain/one]\nval=1\nuno = 1\neins = one\n[sssd]\ndomains=one"; + GError *error = NULL; + gchar *output; + gboolean ret; +@@ -190,7 +227,7 @@ test_update_domain (Test *test, + g_assert_no_error (error); + g_assert (ret == TRUE); + +- g_assert_cmpstr (check, ==, output); ++ check_for_test_update_domain (output); + g_free (output); + } + +-- +cgit v1.1 + diff -Nru realmd-0.16.3/debian/patches/tests-use-python3.patch realmd-0.16.3/debian/patches/tests-use-python3.patch --- realmd-0.16.3/debian/patches/tests-use-python3.patch 1970-01-01 00:00:00.000000000 +0000 +++ realmd-0.16.3/debian/patches/tests-use-python3.patch 2019-10-02 15:26:19.000000000 +0000 @@ -0,0 +1,374 @@ +From 65eece0995146a2de68c408332b6d4ef16aaced5 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 4 Jul 2018 16:41:16 +0200 +Subject: tests: run tests with python3 + +To allow the test to run with python3 build/tap-driver and +build/tap-gtester are updated to the latest version provided by the +cockpit project https://github.com/cockpit-project/cockpit. + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1595813 +--- + build/tap-driver | 104 +++++++++++++++++++++++++++++++++++++++++++----------- + build/tap-gtester | 59 ++++++++++++++++++++++--------- + 2 files changed, 125 insertions(+), 38 deletions(-) + +diff --git a/build/tap-driver b/build/tap-driver +index 42f57c8..241fd50 100755 +--- a/build/tap-driver ++++ b/build/tap-driver +@@ -1,4 +1,5 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 ++# This can also be run with Python 2. + + # Copyright (C) 2013 Red Hat, Inc. + # +@@ -29,20 +30,58 @@ + # + + import argparse ++import fcntl + import os + import select ++import struct + import subprocess + import sys ++import termios ++import errno ++ ++_PY3 = sys.version[0] >= '3' ++_str = _PY3 and str or unicode ++ ++def out(data, stream=None, flush=False): ++ if not isinstance(data, bytes): ++ data = data.encode("UTF-8") ++ if not stream: ++ stream = _PY3 and sys.stdout.buffer or sys.stdout ++ while True: ++ try: ++ if data: ++ stream.write(data) ++ data = None ++ if flush: ++ stream.flush() ++ flush = False ++ break ++ except IOError as e: ++ if e.errno == errno.EAGAIN: ++ continue ++ raise ++ ++def terminal_width(): ++ try: ++ h, w, hp, wp = struct.unpack('HHHH', ++ fcntl.ioctl(1, termios.TIOCGWINSZ, ++ struct.pack('HHHH', 0, 0, 0, 0))) ++ return w ++ except IOError as e: ++ if e.errno != errno.ENOTTY: ++ sys.stderr.write("%i %s %s\n" % (e.errno, e.strerror, sys.exc_info())) ++ return sys.maxsize + + class Driver: + def __init__(self, args): + self.argv = args.command + self.test_name = args.test_name +- self.log = open(args.log_file, "w") +- self.log.write("# %s\n" % " ".join(sys.argv)) ++ self.log = open(args.log_file, "wb") ++ self.log.write(("# %s\n" % " ".join(sys.argv)).encode("UTF-8")) + self.trs = open(args.trs_file, "w") + self.color_tests = args.color_tests + self.expect_failure = args.expect_failure ++ self.width = terminal_width() - 9 + + def report(self, code, *args): + CODES = { +@@ -57,17 +96,18 @@ class Driver: + # Print out to console + if self.color_tests: + if code in CODES: +- sys.stdout.write(CODES[code]) +- sys.stdout.write(code) ++ out(CODES[code]) ++ out(code) + if self.color_tests: +- sys.stdout.write('\x1b[m') +- sys.stdout.write(": ") +- sys.stdout.write(self.test_name) +- sys.stdout.write(" ") +- for arg in args: +- sys.stdout.write(str(arg)) +- sys.stdout.write("\n") +- sys.stdout.flush() ++ out('\x1b[m') ++ out(": ") ++ msg = "".join([ self.test_name + " " ] + list(map(_str, args))) ++ if code == "PASS" and len(msg) > self.width: ++ out(msg[:self.width]) ++ out("...") ++ else: ++ out(msg) ++ out("\n", flush=True) + + # Book keeping + if code in CODES: +@@ -100,12 +140,14 @@ class Driver: + def execute(self): + try: + proc = subprocess.Popen(self.argv, close_fds=True, ++ stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) +- except OSError, ex: ++ except OSError as ex: + self.report_error("Couldn't run %s: %s" % (self.argv[0], str(ex))) + return + ++ proc.stdin.close() + outf = proc.stdout.fileno() + errf = proc.stderr.fileno() + rset = [outf, errf] +@@ -113,18 +155,25 @@ class Driver: + ret = select.select(rset, [], [], 10) + if outf in ret[0]: + data = os.read(outf, 1024) +- if data == "": ++ if data == b"": + rset.remove(outf) + self.log.write(data) + self.process(data) + if errf in ret[0]: + data = os.read(errf, 1024) +- if data == "": ++ if data == b"": + rset.remove(errf) + self.log.write(data) +- sys.stderr.write(data) ++ stream = _PY3 and sys.stderr.buffer or sys.stderr ++ out(data, stream=stream, flush=True) + + proc.wait() ++ ++ # Make sure the test didn't change blocking output ++ assert fcntl.fcntl(0, fcntl.F_GETFL) & os.O_NONBLOCK == 0 ++ assert fcntl.fcntl(1, fcntl.F_GETFL) & os.O_NONBLOCK == 0 ++ assert fcntl.fcntl(2, fcntl.F_GETFL) & os.O_NONBLOCK == 0 ++ + return proc.returncode + + +@@ -137,6 +186,7 @@ class TapDriver(Driver): + self.late_plan = False + self.errored = False + self.bail_out = False ++ self.skip_all_reason = None + + def report(self, code, num, *args): + if num: +@@ -170,13 +220,19 @@ class TapDriver(Driver): + else: + self.result_fail(num, description) + +- def consume_test_plan(self, first, last): ++ def consume_test_plan(self, line): + # Only one test plan is supported + if self.test_plan: + self.report_error("Get a second TAP test plan") + return + ++ if line.lower().startswith('1..0 # skip'): ++ self.skip_all_reason = line[5:].strip() ++ self.bail_out = True ++ return ++ + try: ++ (first, unused, last) = line.partition("..") + first = int(first) + last = int(last) + except ValueError: +@@ -192,7 +248,7 @@ class TapDriver(Driver): + + def process(self, output): + if output: +- self.output += output ++ self.output += output.decode("UTF-8") + elif self.output: + self.output += "\n" + (ready, unused, self.output) = self.output.rpartition("\n") +@@ -202,8 +258,7 @@ class TapDriver(Driver): + elif line.startswith("not ok "): + self.consume_test_line(False, line[7:]) + elif line and line[0].isdigit() and ".." in line: +- (first, unused, last) = line.partition("..") +- self.consume_test_plan(first, last) ++ self.consume_test_plan(line) + elif line.lower().startswith("bail out!"): + self.consume_bail_out(line) + +@@ -213,6 +268,13 @@ class TapDriver(Driver): + failed = False + skipped = True + ++ if self.skip_all_reason is not None: ++ self.result_skip("skipping:", self.skip_all_reason) ++ self.trs.write(":global-test-result: SKIP\n") ++ self.trs.write(":test-global-result: SKIP\n") ++ self.trs.write(":recheck: no\n") ++ return 0 ++ + # Basic collation of results + for (num, code) in self.reported.items(): + if code == "ERROR": +diff --git a/build/tap-gtester b/build/tap-gtester +index 7e667d4..bbda266 100755 +--- a/build/tap-gtester ++++ b/build/tap-gtester +@@ -1,4 +1,5 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 ++# This can also be run with Python 2. + + # Copyright (C) 2014 Red Hat, Inc. + # +@@ -30,9 +31,19 @@ + import argparse + import os + import select ++import signal + import subprocess + import sys + ++# Yes, it's dumb, but strsignal is not exposed in python ++# In addition signal numbers varify heavily from arch to arch ++def strsignal(sig): ++ for name in dir(signal): ++ if name.startswith("SIG") and sig == getattr(signal, name): ++ return name ++ return str(sig) ++ ++ + class NullCompiler: + def __init__(self, command): + self.command = command +@@ -76,22 +87,22 @@ class GTestCompiler(NullCompiler): + elif cmd == "result": + if self.test_name: + if data == "OK": +- print "ok %d %s" % (self.test_num, self.test_name) ++ print("ok %d %s" % (self.test_num, self.test_name)) + if data == "FAIL": +- print "not ok %d %s", (self.test_num, self.test_name) ++ print("not ok %d %s" % (self.test_num, self.test_name)) + self.test_name = None + elif cmd == "skipping": + if "/subprocess" not in data: +- print "ok %d # skip -- %s" % (self.test_num, data) ++ print("ok %d # skip -- %s" % (self.test_num, data)) + self.test_name = None + elif data: +- print "# %s: %s" % (cmd, data) ++ print("# %s: %s" % (cmd, data)) + else: +- print "# %s" % cmd ++ print("# %s" % cmd) + elif line.startswith("(MSG: "): +- print "# %s" % line[6:-1] ++ print("# %s" % line[6:-1]) + elif line: +- print "# %s" % line ++ print("# %s" % line) + sys.stdout.flush() + + def run(self, proc, output=""): +@@ -106,22 +117,26 @@ class GTestCompiler(NullCompiler): + if line.startswith("/"): + self.test_remaining.append(line.strip()) + if not self.test_remaining: +- print "Bail out! No tests found in GTest: %s" % self.command[0] ++ print("Bail out! No tests found in GTest: %s" % self.command[0]) + return 0 + +- print "1..%d" % len(self.test_remaining) ++ print("1..%d" % len(self.test_remaining)) + + # First try to run all the tests in a batch +- proc = subprocess.Popen(self.command + ["--verbose" ], close_fds=True, stdout=subprocess.PIPE) ++ proc = subprocess.Popen(self.command + ["--verbose" ], close_fds=True, ++ stdout=subprocess.PIPE, universal_newlines=True) + result = self.process(proc) + if result == 0: + return 0 + ++ if result < 0: ++ sys.stderr.write("%s terminated with %s\n" % (self.command[0], strsignal(-result))) ++ + # Now pick up any stragglers due to failures + while True: + # Assume that the last test failed + if self.test_name: +- print "not ok %d %s" % (self.test_num, self.test_name) ++ print("not ok %d %s" % (self.test_num, self.test_name)) + self.test_name = None + + # Run any tests which didn't get run +@@ -129,7 +144,8 @@ class GTestCompiler(NullCompiler): + break + + proc = subprocess.Popen(self.command + ["--verbose", "-p", self.test_remaining[0]], +- close_fds=True, stdout=subprocess.PIPE) ++ close_fds=True, stdout=subprocess.PIPE, ++ universal_newlines=True) + result = self.process(proc) + + # The various exit codes and signals we continue for +@@ -139,24 +155,32 @@ class GTestCompiler(NullCompiler): + return result + + def main(argv): +- parser = argparse.ArgumentParser(description='Automake TAP compiler') ++ parser = argparse.ArgumentParser(description='Automake TAP compiler', ++ usage="tap-gtester [--format FORMAT] command ...") + parser.add_argument('--format', metavar='FORMAT', choices=[ "auto", "gtest", "tap" ], + default="auto", help='The input format to compile') + parser.add_argument('--verbose', action='store_true', + default=True, help='Verbose mode (ignored)') +- parser.add_argument('command', nargs='+', help="A test command to run") ++ parser.add_argument('command', nargs=argparse.REMAINDER, help="A test command to run") + args = parser.parse_args(argv[1:]) + + output = None + format = args.format + cmd = args.command ++ if not cmd: ++ sys.stderr.write("tap-gtester: specify a command to run\n") ++ return 2 ++ if cmd[0] == '--': ++ cmd.pop(0) ++ + proc = None + + os.environ['HARNESS_ACTIVE'] = '1' + + if format in ["auto", "gtest"]: + list_cmd = cmd + ["-l", "--verbose"] +- proc = subprocess.Popen(list_cmd, close_fds=True, stdout=subprocess.PIPE) ++ proc = subprocess.Popen(list_cmd, close_fds=True, stdout=subprocess.PIPE, ++ universal_newlines=True) + output = proc.stdout.readline() + # Smell whether we're dealing with GTest list output from first line + if "random seed" in output or "GTest" in output or output.startswith("/"): +@@ -164,7 +188,8 @@ def main(argv): + else: + format = "tap" + else: +- proc = subprocess.Popen(cmd, close_fds=True, stdout=subprocess.PIPE) ++ proc = subprocess.Popen(cmd, close_fds=True, stdout=subprocess.PIPE, ++ universal_newlines=True) + + if format == "gtest": + compiler = GTestCompiler(cmd) +-- +cgit v1.1 +