aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/tox.ini4
-rw-r--r--tools/docker/Dockerfile2
-rw-r--r--tools/jenkins/make_test_output.py90
-rwxr-xr-xtools/jenkins/pull_request.sh1
-rwxr-xr-xtools/run_tests/jenkins.sh36
5 files changed, 122 insertions, 11 deletions
diff --git a/python/tox.ini b/python/tox.ini
index f663b538..cf8d5401 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -6,10 +6,6 @@ envlist =
usedevelop=true
passenv = CC
setenv =
- # Dummy entry works around bug where tox fails for empty "setenv" section
- # (since cpp lines aren't used for py builds).
- # https://bitbucket.org/hpk42/tox/issues/190/generative-setenv-fails-if-there-s-only
- DUMMY=dummy
cpp: LD_LIBRARY_PATH={toxinidir}/../src/.libs
cpp: DYLD_LIBRARY_PATH={toxinidir}/../src/.libs
cpp: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 57830565..bceb6044 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -98,7 +98,7 @@ RUN wget www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe
# to get updates from pip.
RUN pip install pip --upgrade
-RUN pip install virtualenv tox
+RUN pip install virtualenv tox yattag
##################
diff --git a/tools/jenkins/make_test_output.py b/tools/jenkins/make_test_output.py
new file mode 100644
index 00000000..0ba5db3b
--- /dev/null
+++ b/tools/jenkins/make_test_output.py
@@ -0,0 +1,90 @@
+"""Gather output from test runs and create an XML file in JUnit format.
+
+The output files from the individual tests have been written in a directory
+structure like:
+
+ $DIR/joblog (--joblog from "parallel")
+ $DIR/logs/1/cpp/stdout
+ $DIR/logs/1/cpp/stderr
+ $DIR/logs/1/csharp/stdout
+ $DIR/logs/1/csharp/stderr
+ $DIR/logs/1/java_jdk7/stdout
+ $DIR/logs/1/java_jdk7/stderr
+ etc.
+
+This script bundles them into a single output XML file so Jenkins can show
+detailed test results.
+"""
+
+import os;
+import sys;
+from yattag import Doc
+from collections import defaultdict
+
+def readtests(basedir):
+ tests = defaultdict(dict)
+
+ # Sample input (note: separators are tabs).
+ #
+ # Seq Host Starttime Runtime Send Receive Exitval Signal Command
+ # 1 : 1456263838.313 0.005 0 0 0 0 echo A
+ with open(basedir + "/joblog") as jobs:
+ firstline = next(jobs)
+ for line in jobs:
+ values = line.split("\t")
+
+ name = values[8].split()[-1]
+ test = tests[name]
+ test["name"] = name
+ test["time"] = values[3]
+
+ exitval = values[6]
+ if int(exitval):
+ # We don't have a more specific message. User should look at stderr.
+ test["failure"] = "TEST FAILURE"
+ else:
+ test["failure"] = False
+
+ for testname in os.listdir(basedir + "/logs/1"):
+ test = tests[testname]
+
+ with open(basedir + "/logs/1/" + testname + "/stdout") as f:
+ test["stdout"] = f.read()
+
+ with open(basedir + "/logs/1/" + testname + "/stderr") as f:
+ test["stderr"] = f.read()
+
+ # The cpp test is special since it doesn't run under parallel so doesn't show
+ # up in the job log.
+ tests["cpp"]["name"] = "cpp"
+
+ # TODO
+ tests["cpp"]["time"] = "0"
+ tests["cpp"]["failure"] = False
+
+ ret = tests.values()
+ ret.sort(key=lambda x: x["name"])
+
+ return ret
+
+def genxml(tests):
+ doc, tag, text = Doc().tagtext()
+
+ with tag("testsuites"):
+ with tag("testsuite", name="Protobuf Tests"):
+ for test in tests:
+ with tag("testcase", name=test["name"], classname=test["name"],
+ time=test["time"]):
+ with tag("system-out"):
+ text(test["stdout"])
+ with tag("system-err"):
+ text(test["stderr"])
+ if test["failure"]:
+ with tag("failure"):
+ text(test["failure"])
+
+ return doc.getvalue()
+
+sys.stderr.write("make_test_output.py: writing XML from directory: " +
+ sys.argv[1] + "\n");
+print genxml(readtests(sys.argv[1]))
diff --git a/tools/jenkins/pull_request.sh b/tools/jenkins/pull_request.sh
index cb0f4072..00538b9c 100755
--- a/tools/jenkins/pull_request.sh
+++ b/tools/jenkins/pull_request.sh
@@ -3,4 +3,5 @@
export DOCKERFILE_DIR=tools/docker
export DOCKER_RUN_SCRIPT=tools/run_tests/jenkins.sh
+export OUTPUT_DIR=testoutput
./tools/jenkins/build_and_run_docker.sh
diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh
index 620c2116..32050d25 100755
--- a/tools/run_tests/jenkins.sh
+++ b/tools/run_tests/jenkins.sh
@@ -1,5 +1,6 @@
#!/bin/bash
+WORKSPACE_BASE=`pwd`
MY_DIR="$(dirname "$0")"
TEST_SCRIPT=$MY_DIR/tests.sh
BUILD_DIR=/tmp/protobuf
@@ -17,16 +18,30 @@ git clone /var/local/jenkins/protobuf
cd protobuf
OUTPUT_DIR=`mktemp -d`
-mkdir -p $OUTPUT_DIR/1
+LOG_OUTPUT_DIR=$OUTPUT_DIR/logs
+mkdir -p $LOG_OUTPUT_DIR/1/cpp
+################################################################################
# cpp build needs to run first, non-parallelized, so that protoc is available
# for other builds.
-$TEST_SCRIPT cpp | tee $OUTPUT_DIR/1/cpp
+
+# Output filenames to follow the overall scheme used by parallel, ie:
+# $DIR/logs/1/cpp/stdout
+# $DIR/logs/1/cpp/stderr
+# $DIR/logs/1/csharp/stdout
+# $DIR/logs/1/csharp/stderr
+# $DIR/logs/1/java_jdk7/stdout
+# $DIR/logs/1/java_jdk7/stderr
+CPP_STDOUT=$LOG_OUTPUT_DIR/1/cpp/stdout
+CPP_STDERR=$LOG_OUTPUT_DIR/1/cpp/stderr
+$TEST_SCRIPT cpp > >(tee $CPP_STDOUT) 2> >(tee $CPP_STDERR >&2)
# Other tests are run in parallel. The overall run fails if any one of them
# fails.
-parallel --results $OUTPUT_DIR $TEST_SCRIPT ::: \
+FAILED=false
+
+parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: \
csharp \
java_jdk7 \
javanano_jdk7 \
@@ -34,8 +49,17 @@ parallel --results $OUTPUT_DIR $TEST_SCRIPT ::: \
javanano_oracle7 \
python \
python_cpp \
- ruby21
+ ruby21 \
+ || true # Process test results even if tests fail.
-# java_jdk6 \
+# The directory that is copied from Docker back into the Jenkins workspace.
+COPY_FROM_DOCKER=/var/local/git/protobuf/testoutput
+mkdir -p $COPY_FROM_DOCKER
+TESTOUTPUT_XML_FILE=$COPY_FROM_DOCKER/testresults.xml
-find $OUTPUT_DIR
+python $MY_DIR/../jenkins/make_test_output.py $OUTPUT_DIR > $TESTOUTPUT_XML_FILE
+
+ls -l $TESTOUTPUT_XML_FILE
+
+### disabled tests
+# java_jdk6 \