Complete remaining TODOs in unit test script
Updated docker image unit test script, fixing the following TODOs:
- Replace os.system calls with subprocess.check_call
- Support possible configure.ac line breaks ('\')
- Updated 'make check' call fails Jenkins
Also added helpful command prints for Jenkins console
Change-Id: I6ba3986165b8d313228bcaa611df17bd213447eb
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/scripts/unit-test.py b/scripts/unit-test.py
index 3828369..b1ea3fa 100755
--- a/scripts/unit-test.py
+++ b/scripts/unit-test.py
@@ -8,14 +8,68 @@
"""
from urlparse import urljoin
+from subprocess import check_call, call
import os
import sys
+import argparse
+
+
+def check_call_cmd(dir, *cmd):
+ """
+ Verbose prints the directory location the given command is called from and
+ the command, then executes the command using check_call.
+
+ Parameter descriptions:
+ dir Directory location command is to be called from
+ cmd List of parameters constructing the complete command
+ """
+ printline(dir, ">", " ".join(cmd))
+ check_call(cmd)
def clone_pkg(pkg):
+ """
+ Clone the given openbmc package's git repository from gerrit into
+ the WORKSPACE location
+
+ Parameter descriptions:
+ pkg Name of the package to clone
+ """
pkg_repo = urljoin('https://gerrit.openbmc-project.xyz/openbmc/', pkg)
os.chdir(WORKSPACE)
- os.system("git clone "+pkg_repo) # TODO Replace with subprocess call
+ check_call_cmd(WORKSPACE, 'git', 'clone', pkg_repo)
+
+
+def get_deps(configure_ac):
+ """
+ Parse the given 'configure.ac' file for package dependencies and return
+ a list of the dependencies found.
+
+ Parameter descriptions:
+ configure_ac Opened 'configure.ac' file object
+ """
+ line = ""
+ dep_pkgs = []
+ for cfg_line in configure_ac:
+ # Remove whitespace & newline
+ cfg_line = cfg_line.rstrip()
+ # Check for line breaks
+ if cfg_line.endswith('\\'):
+ line += str(cfg_line[:-1])
+ continue
+ line = line+cfg_line
+
+ # Find any defined dependency
+ for macro_key in DEPENDENCIES:
+ if not line.startswith(macro_key):
+ continue
+ for dep_key in DEPENDENCIES[macro_key]:
+ if line.find(dep_key) == -1:
+ continue
+ dep_pkgs += [DEPENDENCIES[macro_key][dep_key]]
+ line = ""
+
+ return dep_pkgs
def build_depends(pkg, pkgdir, dep_installed):
@@ -32,35 +86,28 @@
"""
os.chdir(pkgdir)
# Open package's configure.ac
- with open("configure.ac", "rt") as infile:
- for line in infile: # TODO Handle line breaks
- # Find any defined dependency
- for macro_key in DEPENDENCIES:
- if not line.startswith(macro_key):
+ with open("configure.ac", "rt") as configure_ac:
+ # Retrieve dependency list from package's configure.ac
+ configure_ac_deps = get_deps(configure_ac)
+ for dep_pkg in configure_ac_deps:
+ # Dependency package not already known
+ if dep_installed.get(dep_pkg) is None:
+ # Dependency package not installed
+ dep_installed[dep_pkg] = False
+ clone_pkg(dep_pkg)
+ # Determine this dependency package's
+ # dependencies and install them before
+ # returning to install this package
+ dep_pkgdir = os.path.join(WORKSPACE, dep_pkg)
+ dep_installed = build_depends(dep_pkg, dep_pkgdir,
+ dep_installed)
+ else:
+ # Dependency package known and installed
+ if dep_installed[dep_pkg]:
continue
- for dep_key in DEPENDENCIES[macro_key]:
- if line.find(dep_key) == -1:
- continue
- dep_pkg = DEPENDENCIES[macro_key][dep_key]
- # Dependency package not already known
- if dep_installed.get(dep_pkg) is None:
- # Dependency package not installed
- dep_installed[dep_pkg] = False
- clone_pkg(dep_pkg)
- # Determine this dependency package's
- # dependencies and install them before
- # returning to install this package
- dep_pkgdir = os.path.join(WORKSPACE, dep_pkg)
- dep_installed = build_depends(dep_pkg, dep_pkgdir,
- dep_installed)
- else:
- # Dependency package known and installed
- if dep_installed[dep_pkg]:
- continue
- else:
- # Cyclic dependency failure
- raise Exception("Cyclic dependencies \
- found in "+pkg)
+ else:
+ # Cyclic dependency failure
+ raise Exception("Cyclic dependencies found in "+pkg)
# Build & install this package
if not dep_installed[pkg]:
@@ -69,8 +116,10 @@
# Add any necessary configure flags for package
if CONFIGURE_FLAGS.get(pkg) is not None:
conf_flags = " ".join(CONFIGURE_FLAGS.get(pkg))
- os.system("./bootstrap.sh && ./configure " +
- conf_flags + "&& make && make install")
+ check_call_cmd(pkgdir, './bootstrap.sh')
+ check_call_cmd(pkgdir, './configure', conf_flags)
+ check_call_cmd(pkgdir, 'make')
+ check_call_cmd(pkgdir, 'make', 'install')
dep_installed[pkg] = True
return dep_installed
@@ -88,15 +137,24 @@
'AC_CHECK_HEADER': {'host-ipmid/ipmid-api.h': 'phosphor-host-ipmid'}
}
- # Get workspace directory (package source to be tested)
- WORKSPACE = os.environ.get('WORKSPACE')
- if WORKSPACE is None:
- raise Exception("Environment variable 'WORKSPACE' not set")
-
- # Determine package name
- UNIT_TEST_PKG = os.environ.get('UNIT_TEST_PKG')
- if UNIT_TEST_PKG is None:
- raise Exception("Environment variable 'UNIT_TEST_PKG' not set")
+ # Set command line arguments
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-w", "--workspace", dest="WORKSPACE", required=True,
+ help="Workspace directory location(i.e. /home)")
+ parser.add_argument("-p", "--package", dest="PACKAGE", required=True,
+ help="OpenBMC package to be unit tested")
+ parser.add_argument("-v", "--verbose", action="store_true",
+ help="Print additional package status messages")
+ args = parser.parse_args(sys.argv[1:])
+ WORKSPACE = args.WORKSPACE
+ UNIT_TEST_PKG = args.PACKAGE
+ if args.verbose:
+ def printline(*line):
+ for arg in line:
+ print arg,
+ print
+ else:
+ printline = lambda *l: None
prev_umask = os.umask(000)
# Determine dependencies and install them
@@ -107,5 +165,5 @@
dep_installed)
os.chdir(os.path.join(WORKSPACE, UNIT_TEST_PKG))
# Run package unit tests
- os.system("make check") # TODO Verify all fails halt Jenkins
+ check_call_cmd(os.path.join(WORKSPACE, UNIT_TEST_PKG), 'make', 'check')
os.umask(prev_umask)