From 342f6d06f8812b0a01500d304220dd20550a9e5d Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Fri, 3 May 2019 16:37:12 +0100
Subject: [PATCH] Rewrite relocatable-install test in Python

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 ci/Jenkinsfile           |  12 ----
 meson.build              |  12 ++--
 t/mypy.sh                |   1 +
 t/pycodestyle.sh         |   4 +-
 t/pyflakes.sh            |   1 +
 t/relocatable-install.py | 146 +++++++++++++++++++++++++++++++++++++++
 t/relocatable-install.sh |  99 --------------------------
 7 files changed, 157 insertions(+), 118 deletions(-)
 create mode 100755 t/relocatable-install.py
 delete mode 100755 t/relocatable-install.sh

diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile
index 270f34e91..e396c50f9 100644
--- a/ci/Jenkinsfile
+++ b/ci/Jenkinsfile
@@ -70,18 +70,6 @@ pipeline {
               '''
             }
           }
-
-          /* Check for self-containedness by repeating relocatable-install.sh
-           * in a somewhat minimal container. */
-          docker.image('debian:buster-slim').inside() {
-            sh '''
-            set -eu
-            export G_TEST_SRCDIR="${WORKSPACE}/src"
-            export G_TEST_BUILDDIR="${WORKSPACE}/src/_build"
-            cd src
-            ./t/relocatable-install.sh
-            '''
-          }
         }
 
         dir('src/_build') {
diff --git a/meson.build b/meson.build
index 8b1a24ca6..c3b077f98 100644
--- a/meson.build
+++ b/meson.build
@@ -45,11 +45,11 @@ scripts = [
 ]
 
 tests = [
-  'mypy',
-  'pycodestyle',
-  'pyflakes',
-  'relocatable-install',
-  'shellcheck',
+  'mypy.sh',
+  'pycodestyle.sh',
+  'pyflakes.sh',
+  'relocatable-install.py',
+  'shellcheck.sh',
 ]
 
 test_env = environment()
@@ -60,7 +60,7 @@ foreach test_name : tests
   if prove.found()
     test(
       test_name, prove,
-      args : ['-v', files('t/' + test_name + '.sh')],
+      args : ['-v', files('t/' + test_name)],
       env : test_env,
     )
   endif
diff --git a/t/mypy.sh b/t/mypy.sh
index b55235975..6dd270a71 100755
--- a/t/mypy.sh
+++ b/t/mypy.sh
@@ -23,6 +23,7 @@ for script in \
     "${G_TEST_SRCDIR}"/*.py \
     "${G_TEST_SRCDIR}"/pressure-vessel-test-ui \
     "${G_TEST_SRCDIR}"/sysroot/*.py \
+    "${G_TEST_SRCDIR}"/t/*.py \
 ; do
     i=$((i + 1))
     if [ "x${MYPY:="$(command -v mypy || echo false)"}" = xfalse ]; then
diff --git a/t/pycodestyle.sh b/t/pycodestyle.sh
index 0c0113a1b..a26f9e5c6 100755
--- a/t/pycodestyle.sh
+++ b/t/pycodestyle.sh
@@ -26,12 +26,14 @@ echo "1..1"
 
 # Ignore E402: when using GObject-Introspection, not all imports
 # can come first
+# Ignore W503: allow wrapping long expressions before a binary operator
 
 if "${PYCODESTYLE}" \
-    --ignore=E402 \
+    --ignore=E402,W503 \
     "$G_TEST_SRCDIR"/*.py \
     "${G_TEST_SRCDIR}"/pressure-vessel-test-ui \
     "${G_TEST_SRCDIR}"/sysroot/*.py \
+    "${G_TEST_SRCDIR}"/t/*.py \
     >&2; then
     echo "ok 1 - $PYCODESTYLE reported no issues"
 else
diff --git a/t/pyflakes.sh b/t/pyflakes.sh
index 5134e7644..5f7f497c8 100755
--- a/t/pyflakes.sh
+++ b/t/pyflakes.sh
@@ -23,6 +23,7 @@ elif "${PYFLAKES}" \
     "${G_TEST_SRCDIR}"/*.py \
     "${G_TEST_SRCDIR}"/pressure-vessel-test-ui \
     "${G_TEST_SRCDIR}"/sysroot/*.py \
+    "${G_TEST_SRCDIR}"/t/*.py \
     >&2; then
     echo "1..1"
     echo "ok 1 - $PYFLAKES reported no issues"
diff --git a/t/relocatable-install.py b/t/relocatable-install.py
new file mode 100755
index 000000000..4c06e4615
--- /dev/null
+++ b/t/relocatable-install.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+# Copyright 2018-2019 Collabora Ltd.
+#
+# SPDX-License-Identifier: MIT
+
+import os
+import subprocess
+import sys
+
+try:
+    import typing
+    typing      # silence pyflakes
+except ImportError:
+    pass
+
+
+G_TEST_SRCDIR = os.getenv(
+    'G_TEST_SRCDIR',
+    os.path.abspath(
+        os.path.join(os.path.dirname(__file__), os.pardir),
+    ),
+)
+G_TEST_BUILDDIR = os.getenv('G_TEST_BUILDDIR', os.path.abspath('_build'))
+
+
+class TapTest:
+    def __init__(self):
+        # type: () -> None
+        self.test_num = 0
+        self.failed = False
+
+    def ok(self, desc):
+        # type: (str) -> None
+        self.test_num += 1
+        print('ok %d - %s' % (self.test_num, desc))
+
+    def skip(self, desc):
+        # type: (str) -> None
+        self.test_num += 1
+        print('ok %d # SKIP %s' % (self.test_num, desc))
+
+    def diag(self, text):
+        # type: (str) -> None
+        print('# %s' % text)
+
+    def not_ok(self, desc):
+        # type: (str) -> None
+        self.test_num += 1
+        print('not ok %d - %s' % (self.test_num, desc))
+        self.failed = True
+
+    def done_testing(self):
+        # type: () -> None
+        print('1..%d' % self.test_num)
+
+        if self.failed:
+            sys.exit(1)
+
+
+EXES = [
+    'pressure-vessel-wrap-c',
+]
+WRAPPED = [
+    'bwrap',
+]
+MULTIARCH = [
+    'capsule-capture-libs',
+    'capsule-symbols',
+]
+SCRIPTS = [
+    'pressure-vessel-unruntime',
+    'pressure-vessel-wrap',
+]
+LD_SO = [
+    ('x86_64-linux-gnu', '/lib64/ld-linux-x86-64.so.2'),
+    ('i386-linux-gnu', '/lib/ld-linux.so.2'),
+]
+
+
+def isexec(path):
+    # type: (str) -> bool
+    try:
+        return (os.stat(path).st_mode & 0o111) != 0
+    except OSError:
+        return False
+
+
+def main():
+    # type: () -> None
+    relocatable_install = os.path.join(G_TEST_BUILDDIR, 'relocatable-install')
+
+    if not os.path.exists(relocatable_install):
+        print('1..0 # SKIP relocatable-install not in expected location')
+        sys.exit(0)
+
+    test = TapTest()
+
+    for exe in EXES + WRAPPED:
+        path = os.path.join(relocatable_install, 'bin', exe)
+
+        if subprocess.call([path, '--help'], stdout=2) == 0:
+            test.ok('{} --help'.format(path))
+        else:
+            test.not_ok('{} --help'.format(path))
+
+    for exe in EXES:
+        path = os.path.join(relocatable_install, 'bin', exe)
+
+    for exe in WRAPPED:
+        path = os.path.join(relocatable_install, 'bin', exe)
+
+    for basename in MULTIARCH:
+        for multiarch, ld_so in LD_SO:
+            exe = '{}-{}'.format(multiarch, basename)
+            path = os.path.join(relocatable_install, 'bin', exe)
+
+            if isexec(path):
+                test.ok('{} exists and is executable'.format(path))
+            else:
+                test.not_ok('{} not executable'.format(path))
+
+            if not isexec(ld_so):
+                test.skip('{} not found'.format(ld_so))
+            elif basename == 'capsule-symbols':
+                test.skip('capsule-symbols has no --help yet')
+            elif subprocess.call([path, '--help'], stdout=2) == 0:
+                test.ok('{} --help'.format(path))
+            else:
+                test.not_ok('{} --help'.format(path))
+
+    for exe in SCRIPTS:
+        path = os.path.join(relocatable_install, 'bin', exe)
+        if not isexec('/bin/bash'):
+            test.skip('bash not found')
+        elif subprocess.call([path, '--help'], stdout=2) == 0:
+            test.ok('{} --help'.format(path))
+        else:
+            test.not_ok('{} --help'.format(path))
+
+    test.done_testing()
+
+
+if __name__ == '__main__':
+    main()
+
+# vi: set sw=4 sts=4 et:
diff --git a/t/relocatable-install.sh b/t/relocatable-install.sh
deleted file mode 100755
index 9d9c1f571..000000000
--- a/t/relocatable-install.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/sh
-set -eu
-
-if [ -z "${G_TEST_SRCDIR-}" ]; then
-    me="$(readlink -f "$0")"
-    srcdir="${me%/*}"
-    G_TEST_SRCDIR="${srcdir%/*}"
-fi
-
-: "${G_TEST_BUILDDIR:=.}"
-
-n=0
-failed=
-
-EXES="
-bwrap
-"
-
-MULTIARCH="
-capsule-capture-libs
-capsule-symbols
-"
-
-SCRIPTS="
-pressure-vessel-wrap
-pressure-vessel-unruntime
-"
-
-relocatable_install="${G_TEST_BUILDDIR}/relocatable-install"
-
-if ! [ -e "${relocatable_install}" ]; then
-    echo "1..0 # SKIP relocatable-install not in expected location"
-    exit 0
-fi
-
-for exe in $EXES; do
-    n=$(( n + 1 ))
-
-    if "${relocatable_install}/bin/$exe" --help >&2; then
-        echo "ok $n - $exe --help"
-    else
-        echo "not ok $n - $exe --help"
-        failed=yes
-    fi
-done
-
-for basename in $MULTIARCH; do
-    for pair in \
-        x86_64-linux-gnu:/lib64/ld-linux-x86-64.so.2 \
-        i386-linux-gnu:/lib/ld-linux.so.2 \
-    ; do
-        ld_so="${pair#*:}"
-        multiarch="${pair%:*}"
-        exe="${multiarch}-${basename}"
-
-        n=$(( n + 1 ))
-
-        if [ -x "${relocatable_install}/bin/$exe" ]; then
-            echo "ok $n - $exe exists and is executable"
-        else
-            echo "not ok $n - $exe not executable"
-            failed=yes
-        fi
-
-        n=$(( n + 1 ))
-
-        if ! [ -x "$ld_so" ]; then
-            echo "ok $n - $exe # SKIP: $ld_so not found"
-        elif [ "$basename" = "capsule-symbols" ]; then
-            echo "ok $n - $exe # SKIP: capsule-symbols has no --help yet"
-        elif "${relocatable_install}/bin/$exe" --help >&2; then
-            echo "ok $n - $exe --help"
-        else
-            echo "not ok $n - $exe --help"
-            failed=yes
-        fi
-    done
-done
-
-for exe in $SCRIPTS; do
-    n=$(( n + 1 ))
-
-    if ! [ -x /bin/bash ]; then
-        echo "ok $n - $exe # SKIP Cannot run a bash script without bash"
-    elif "${relocatable_install}/bin/$exe" --help >&2; then
-        echo "ok $n - $exe --help"
-    else
-        echo "not ok $n - $exe --help"
-        failed=yes
-    fi
-done
-
-echo "1..$n"
-
-if [ -n "$failed" ]; then
-    exit 1
-fi
-
-# vim:set sw=4 sts=4 et:
-- 
GitLab