From 57be1d7eb25432b9f0106d64faed323ef954f7d2 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 18 Feb 2016 14:55:00 -0800 Subject: [PATCH 01/17] Added some initial shell scripts and docker file. --- .travis.yml | 2 +- tools/docker/Dockerfile | 57 ++++++++++++++++++++ tools/jenkins/build_and_run_docker.sh | 78 +++++++++++++++++++++++++++ tools/jenkins/pull_request.sh | 6 +++ tools/run_tests/jenkins.sh | 13 +++++ travis.sh => tools/run_tests/tests.sh | 41 ++------------ tools/run_tests/travis.sh | 42 +++++++++++++++ 7 files changed, 200 insertions(+), 39 deletions(-) create mode 100644 tools/docker/Dockerfile create mode 100755 tools/jenkins/build_and_run_docker.sh create mode 100755 tools/jenkins/pull_request.sh create mode 100755 tools/run_tests/jenkins.sh rename travis.sh => tools/run_tests/tests.sh (88%) mode change 100755 => 100644 create mode 100755 tools/run_tests/travis.sh diff --git a/.travis.yml b/.travis.yml index 9bc4d88ff..4a2954016 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ os: # The Objective C build needs Xcode 7.0 or later. osx_image: xcode7.2 script: - - ./travis.sh $CONFIG + - ./tools/run_tests/travis.sh $CONFIG env: - CONFIG=cpp - CONFIG=cpp_distcheck diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile new file mode 100644 index 000000000..b5e26f9ad --- /dev/null +++ b/tools/docker/Dockerfile @@ -0,0 +1,57 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Base Dockerfile for gRPC dev images +FROM debian:latest + +# Install Git. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + strace \ + python-dev \ + python-setuptools \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +# Define the default command. +CMD ["bash"] diff --git a/tools/jenkins/build_and_run_docker.sh b/tools/jenkins/build_and_run_docker.sh new file mode 100755 index 000000000..e77ffd612 --- /dev/null +++ b/tools/jenkins/build_and_run_docker.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Builds docker image and runs a command under it. +# You should never need to call this script on your own. + +set -ex + +cd $(dirname $0)/../.. +git_root=$(pwd) +cd - + +# Inputs +# DOCKERFILE_DIR - Directory in which Dockerfile file is located. +# DOCKER_RUN_SCRIPT - Script to run under docker (relative to protobuf repo root) +# OUTPUT_DIR - Directory that will be copied from inside docker after finishing. +# $@ - Extra args to pass to docker run + +# Use image name based on Dockerfile location checksum +DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) + +# Make sure docker image has been built. Should be instantaneous if so. +docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR + +# Choose random name for docker container +CONTAINER_NAME="build_and_run_docker_$(uuidgen)" + +# Run command inside docker +docker run \ + "$@" \ + -e EXTERNAL_GIT_ROOT="/var/local/jenkins/protobuf" \ + -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ + -v "$git_root:/var/local/jenkins/protobuf:ro" \ + -w /var/local/git/protobuf \ + --name=$CONTAINER_NAME \ + $DOCKER_IMAGE_NAME \ + bash -l "/var/local/jenkins/protobuf/$DOCKER_RUN_SCRIPT" || FAILED="true" + +# Copy output artifacts +if [ "$OUTPUT_DIR" != "" ] +then + docker cp "$CONTAINER_NAME:/var/local/git/protobuf/$OUTPUT_DIR" "$git_root" || FAILED="true" +fi + +# remove the container, possibly killing it first +docker rm -f $CONTAINER_NAME || true + +if [ "$FAILED" != "" ] +then + exit 1 +fi diff --git a/tools/jenkins/pull_request.sh b/tools/jenkins/pull_request.sh new file mode 100755 index 000000000..cb0f4072b --- /dev/null +++ b/tools/jenkins/pull_request.sh @@ -0,0 +1,6 @@ +#!/bin/bash + + +export DOCKERFILE_DIR=tools/docker +export DOCKER_RUN_SCRIPT=tools/run_tests/jenkins.sh +./tools/jenkins/build_and_run_docker.sh diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh new file mode 100755 index 000000000..34a168298 --- /dev/null +++ b/tools/run_tests/jenkins.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +MY_DIR="$(dirname "$0")" +BUILD_DIR=/tmp/protobuf + +source $MY_DIR/tests.sh + +rm -rf $BUILD_DIR +mkdir -p $BUILD_DIR +cd $BUILD_DIR +git clone /var/local/jenkins/protobuf +cd protobuf +build_cpp diff --git a/travis.sh b/tools/run_tests/tests.sh old mode 100755 new mode 100644 similarity index 88% rename from travis.sh rename to tools/run_tests/tests.sh index ff5e99d58..f1c7e9693 --- a/travis.sh +++ b/tools/run_tests/tests.sh @@ -1,17 +1,10 @@ -#!/usr/bin/env bash - -# Note: travis currently does not support testing more than one language so the -# .travis.yml cheats and claims to only be cpp. If they add multiple language -# support, this should probably get updated to install steps and/or -# rvm/gemfile/jdk/etc. entries rather than manually doing the work. - -# .travis.yml uses matrix.exclude to block the cases where app-get can't be -# use to install things. +# This file is not intended to be executed directly. It is intended to be +# included in a larger shell script. # For when some other test needs the C++ main build, including protoc and # libprotobuf. internal_build_cpp() { - if [ $(uname -s) == "Linux" ]; then + if [ $(uname -s) == "Linux" && "$TRAVIS" == "true" ]; then # Install GCC 4.8 to replace the default GCC 4.6. We need 4.8 for more # decent C++ 11 support in order to compile conformance tests. sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y @@ -284,31 +277,3 @@ build_javascript() { cd js && npm install && npm test && cd .. } -# -------- main -------- - -if [ "$#" -ne 1 ]; then - echo " -Usage: $0 { cpp | - csharp | - java_jdk6 | - java_jdk7 | - java_oracle7 | - javanano_jdk6 | - javanano_jdk7 | - javanano_oracle7 | - objectivec_ios | - objectivec_osx | - python | - python_cpp | - ruby_19 | - ruby_20 | - ruby_21 | - ruby_22 | - jruby } -" - exit 1 -fi - -set -e # exit immediately on error -set -x # display all commands -eval "build_$1" diff --git a/tools/run_tests/travis.sh b/tools/run_tests/travis.sh new file mode 100755 index 000000000..8c87a47be --- /dev/null +++ b/tools/run_tests/travis.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +my_dir="$(dirname "$0")" + +source $my_dir/tests.sh + +# Note: travis currently does not support testing more than one language so the +# .travis.yml cheats and claims to only be cpp. If they add multiple language +# support, this should probably get updated to install steps and/or +# rvm/gemfile/jdk/etc. entries rather than manually doing the work. + +# .travis.yml uses matrix.exclude to block the cases where app-get can't be +# use to install things. + +# -------- main -------- + +if [ "$#" -ne 1 ]; then + echo " +Usage: $0 { cpp | + csharp | + java_jdk6 | + java_jdk7 | + java_oracle7 | + javanano_jdk6 | + javanano_jdk7 | + javanano_oracle7 | + objectivec_ios | + objectivec_osx | + python | + python_cpp | + ruby_19 | + ruby_20 | + ruby_21 | + ruby_22 | + jruby } +" + exit 1 +fi + +set -e # exit immediately on error +set -x # display all commands +eval "build_$1" From d33e93b83367ea4dfabeed9cda03bc06a1ff0f6a Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 18 Feb 2016 19:13:07 -0800 Subject: [PATCH 02/17] Added ccache support. --- tools/docker/Dockerfile | 9 +++++++++ tools/run_tests/jenkins.sh | 4 ++++ tools/run_tests/tests.sh | 8 ++++---- tools/run_tests/travis.sh | 7 +++++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index b5e26f9ad..b1d0c6827 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -36,6 +36,7 @@ RUN apt-get update && apt-get install -y \ autotools-dev \ build-essential \ bzip2 \ + ccache \ curl \ gcc \ git \ @@ -53,5 +54,13 @@ RUN apt-get update && apt-get install -y \ wget \ zip && apt-get clean +# Prepare ccache +RUN ln -s /usr/bin/ccache /usr/local/bin/gcc +RUN ln -s /usr/bin/ccache /usr/local/bin/g++ +RUN ln -s /usr/bin/ccache /usr/local/bin/cc +RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN ln -s /usr/bin/ccache /usr/local/bin/clang +RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ + # Define the default command. CMD ["bash"] diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index 34a168298..b90c099fb 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -5,9 +5,13 @@ BUILD_DIR=/tmp/protobuf source $MY_DIR/tests.sh +# Set value used in tests.sh. +PARALLELISM=-j8 + rm -rf $BUILD_DIR mkdir -p $BUILD_DIR cd $BUILD_DIR git clone /var/local/jenkins/protobuf cd protobuf + build_cpp diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index f1c7e9693..a6ba14057 100644 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -4,7 +4,7 @@ # For when some other test needs the C++ main build, including protoc and # libprotobuf. internal_build_cpp() { - if [ $(uname -s) == "Linux" && "$TRAVIS" == "true" ]; then + if [[ $(uname -s) == "Linux" && "$TRAVIS" == "true" ]]; then # Install GCC 4.8 to replace the default GCC 4.6. We need 4.8 for more # decent C++ 11 support in order to compile conformance tests. sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y @@ -15,19 +15,19 @@ internal_build_cpp() { ./autogen.sh ./configure - make -j2 + make $PARALLELISM } build_cpp() { internal_build_cpp - make check -j2 + make check $PARALLELISM cd conformance && make test_cpp && cd .. } build_cpp_distcheck() { ./autogen.sh ./configure - make distcheck -j2 + make distcheck $PARALLELISM } build_csharp() { diff --git a/tools/run_tests/travis.sh b/tools/run_tests/travis.sh index 8c87a47be..f7045f1b3 100755 --- a/tools/run_tests/travis.sh +++ b/tools/run_tests/travis.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -my_dir="$(dirname "$0")" +MY_DIR="$(dirname "$0")" -source $my_dir/tests.sh +source $MY_DIR/tests.sh # Note: travis currently does not support testing more than one language so the # .travis.yml cheats and claims to only be cpp. If they add multiple language @@ -14,6 +14,9 @@ source $my_dir/tests.sh # -------- main -------- +# Set value used in tests.sh. +PARALLELISM=-j2 + if [ "$#" -ne 1 ]; then echo " Usage: $0 { cpp | From 738393b2c0690bcb92a6689f3a07d518289c4dde Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 18 Feb 2016 20:10:23 -0800 Subject: [PATCH 03/17] Try running multiple tests in a row. --- .travis.yml | 2 +- tools/run_tests/jenkins.sh | 12 +++++++--- tools/run_tests/tests.sh | 49 ++++++++++++++++++++++++++++++++++++-- tools/run_tests/travis.sh | 45 ---------------------------------- 4 files changed, 57 insertions(+), 51 deletions(-) mode change 100644 => 100755 tools/run_tests/tests.sh delete mode 100755 tools/run_tests/travis.sh diff --git a/.travis.yml b/.travis.yml index 4a2954016..26b9dcaff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ os: # The Objective C build needs Xcode 7.0 or later. osx_image: xcode7.2 script: - - ./tools/run_tests/travis.sh $CONFIG + - ./tools/run_tests/tests.sh $CONFIG env: - CONFIG=cpp - CONFIG=cpp_distcheck diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index b90c099fb..e174a209f 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -1,17 +1,23 @@ #!/bin/bash MY_DIR="$(dirname "$0")" +TEST_SCRIPT=$MY_DIR/tests.sh BUILD_DIR=/tmp/protobuf -source $MY_DIR/tests.sh - # Set value used in tests.sh. PARALLELISM=-j8 +set -x # display all commands + rm -rf $BUILD_DIR mkdir -p $BUILD_DIR cd $BUILD_DIR git clone /var/local/jenkins/protobuf cd protobuf -build_cpp +# If protoc fails to build, we can't test anything else. +$TEST_SCRIPT cpp || exit 1 + +# Other tests can fail and we keep on going. +$TEST_SCRIPT java_jdk6 +$TEST_SCRIPT java_jdk7 diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh old mode 100644 new mode 100755 index a6ba14057..718d6de9d --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -1,9 +1,13 @@ -# This file is not intended to be executed directly. It is intended to be -# included in a larger shell script. +#!/bin/bash # For when some other test needs the C++ main build, including protoc and # libprotobuf. internal_build_cpp() { + if [ -f src/protoc ]; then + # Already built. + return + fi + if [[ $(uname -s) == "Linux" && "$TRAVIS" == "true" ]]; then # Install GCC 4.8 to replace the default GCC 4.6. We need 4.8 for more # decent C++ 11 support in order to compile conformance tests. @@ -277,3 +281,44 @@ build_javascript() { cd js && npm install && npm test && cd .. } +[ -n "${PARALLELISM}" ] && PARALLELISM=-j8 + +# Note: travis currently does not support testing more than one language so the +# .travis.yml cheats and claims to only be cpp. If they add multiple language +# support, this should probably get updated to install steps and/or +# rvm/gemfile/jdk/etc. entries rather than manually doing the work. + +# .travis.yml uses matrix.exclude to block the cases where app-get can't be +# use to install things. + +# -------- main -------- + +# Set value used in tests.sh. +PARALLELISM=-j2 + +if [ "$#" -ne 1 ]; then + echo " +Usage: $0 { cpp | + csharp | + java_jdk6 | + java_jdk7 | + java_oracle7 | + javanano_jdk6 | + javanano_jdk7 | + javanano_oracle7 | + objectivec_ios | + objectivec_osx | + python | + python_cpp | + ruby_19 | + ruby_20 | + ruby_21 | + ruby_22 | + jruby } +" + exit 1 +fi + +set -e # exit immediately on error +set -x # display all commands +eval "build_$1" diff --git a/tools/run_tests/travis.sh b/tools/run_tests/travis.sh deleted file mode 100755 index f7045f1b3..000000000 --- a/tools/run_tests/travis.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -MY_DIR="$(dirname "$0")" - -source $MY_DIR/tests.sh - -# Note: travis currently does not support testing more than one language so the -# .travis.yml cheats and claims to only be cpp. If they add multiple language -# support, this should probably get updated to install steps and/or -# rvm/gemfile/jdk/etc. entries rather than manually doing the work. - -# .travis.yml uses matrix.exclude to block the cases where app-get can't be -# use to install things. - -# -------- main -------- - -# Set value used in tests.sh. -PARALLELISM=-j2 - -if [ "$#" -ne 1 ]; then - echo " -Usage: $0 { cpp | - csharp | - java_jdk6 | - java_jdk7 | - java_oracle7 | - javanano_jdk6 | - javanano_jdk7 | - javanano_oracle7 | - objectivec_ios | - objectivec_osx | - python | - python_cpp | - ruby_19 | - ruby_20 | - ruby_21 | - ruby_22 | - jruby } -" - exit 1 -fi - -set -e # exit immediately on error -set -x # display all commands -eval "build_$1" From 0f8c25d1050b8d20ed73b72e5b36344fb9b497dc Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 19 Feb 2016 09:11:38 -0800 Subject: [PATCH 04/17] Properly add JDK deps in the Docker image. --- tools/docker/Dockerfile | 12 ++++++++++-- tools/run_tests/jenkins.sh | 2 +- tools/run_tests/tests.sh | 10 ++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index b1d0c6827..8770d16e3 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -30,7 +30,8 @@ # Base Dockerfile for gRPC dev images FROM debian:latest -# Install Git. +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build RUN apt-get update && apt-get install -y \ autoconf \ autotools-dev \ @@ -52,7 +53,14 @@ RUN apt-get update && apt-get install -y \ telnet \ unzip \ wget \ - zip && apt-get clean + zip \ + # For all Java builds \ + maven \ + # For java_jdk6 \ + # oops! not in Jessie. Too old? openjdk-6-jdk \ + # For java_jdk7 \ + openjdk-7-jdk \ + && apt-get clean # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index e174a209f..bbca33894 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -19,5 +19,5 @@ cd protobuf $TEST_SCRIPT cpp || exit 1 # Other tests can fail and we keep on going. -$TEST_SCRIPT java_jdk6 +#$TEST_SCRIPT java_jdk6 $TEST_SCRIPT java_jdk7 diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index 718d6de9d..db4997552 100755 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -1,5 +1,11 @@ #!/bin/bash +on_travis() { + if [ "$TRAVIS" == "true" ]; then + "$@" + fi +} + # For when some other test needs the C++ main build, including protoc and # libprotobuf. internal_build_cpp() { @@ -75,11 +81,11 @@ use_java() { version=$1 case "$version" in jdk6) - sudo apt-get install openjdk-6-jdk + on_travis sudo apt-get install openjdk-6-jdk export PATH=/usr/lib/jvm/java-6-openjdk-amd64/bin:$PATH ;; jdk7) - sudo apt-get install openjdk-7-jdk + on_travis sudo apt-get install openjdk-7-jdk export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH ;; oracle7) From 0b931bcd53897954cf96cd8075bb6fc16651559d Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 19 Feb 2016 12:33:17 -0800 Subject: [PATCH 05/17] Add another test (javanano), but run it in parallel. --- tools/docker/Dockerfile | 1 + tools/run_tests/jenkins.sh | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 8770d16e3..7d9def057 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -47,6 +47,7 @@ RUN apt-get update && apt-get install -y \ libgtest-dev \ libtool \ make \ + parallel \ strace \ python-dev \ python-setuptools \ diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index bbca33894..c0d02ddc7 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -7,6 +7,7 @@ BUILD_DIR=/tmp/protobuf # Set value used in tests.sh. PARALLELISM=-j8 +set -e # exit immediately on error set -x # display all commands rm -rf $BUILD_DIR @@ -15,9 +16,15 @@ cd $BUILD_DIR git clone /var/local/jenkins/protobuf cd protobuf -# If protoc fails to build, we can't test anything else. -$TEST_SCRIPT cpp || exit 1 +OUTPUT_DIR=`mktemp -d` +mkdir -p $OUTPUT_DIR/1 -# Other tests can fail and we keep on going. -#$TEST_SCRIPT java_jdk6 -$TEST_SCRIPT java_jdk7 +# cpp build needs to run first, non-parallelized, so that protoc is available +# for other builds. +$TEST_SCRIPT cpp | tee $OUTPUT_DIR/1/cpp + +# Other tests are run in parallel. The overall run fails if any one of them +# fails. + +# java_jdk6 +parallel $TEST_SCRIPT ::: java_jdk7 javanano_jdk7 From 483533d3a21a9d689aafb4c259301aa44cef75ed Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 19 Feb 2016 12:48:33 -0800 Subject: [PATCH 06/17] Install Python deps in Docker image. --- tools/docker/Dockerfile | 26 +++++++++++++++----------- tools/run_tests/jenkins.sh | 9 +++++++-- tools/run_tests/tests.sh | 3 +++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 7d9def057..b5b712fa2 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -30,6 +30,10 @@ # Base Dockerfile for gRPC dev images FROM debian:latest +RUN echo 'deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu trusty main' > /etc/apt/sources.list.d/deadsnakes.list && \ + gpg --keyserver keyserver.ubuntu.com --recv-keys DB82666C && \ + gpg --export DB82666C | apt-key add - + # Install dependencies. We start with the basic ones require to build protoc # and the C++ build RUN apt-get update && apt-get install -y \ @@ -48,19 +52,19 @@ RUN apt-get update && apt-get install -y \ libtool \ make \ parallel \ - strace \ - python-dev \ - python-setuptools \ - telnet \ - unzip \ - wget \ - zip \ - # For all Java builds \ + # -- For all Java builds -- \ maven \ - # For java_jdk6 \ - # oops! not in Jessie. Too old? openjdk-6-jdk \ - # For java_jdk7 \ + # -- For java_jdk6 -- \ + # oops! not in jessie. too old? openjdk-6-jdk \ + # -- For java_jdk7 -- \ openjdk-7-jdk \ + # -- For python / python_cpp -- \ + python-setuptools \ + python-tox \ + python-dev \ + python2.6-dev \ + python3.3-dev \ + python3.4-dev \ && apt-get clean # Prepare ccache diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index c0d02ddc7..1d192aa4b 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -26,5 +26,10 @@ $TEST_SCRIPT cpp | tee $OUTPUT_DIR/1/cpp # Other tests are run in parallel. The overall run fails if any one of them # fails. -# java_jdk6 -parallel $TEST_SCRIPT ::: java_jdk7 javanano_jdk7 +parallel $TEST_SCRIPT ::: \ + java_jdk7 \ + javanano_jdk7 \ + python \ + python_cpp + +# java_jdk6 \ diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index db4997552..5281cd200 100755 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -152,6 +152,9 @@ build_javanano_oracle7() { } internal_install_python_deps() { + if [ "$TRAVIS" != "true" ]; then + return; + fi # Install tox (OS X doesn't have pip). if [ $(uname -s) == "Darwin" ]; then sudo easy_install tox From d08c39c21884b73d9bd2a0cfd0e6b8851444d391 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Sat, 20 Feb 2016 12:03:39 -0800 Subject: [PATCH 07/17] Put Maven in batch mode to avoid spamming the logs. --- tools/run_tests/tests.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index 5281cd200..7ada81f84 100755 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -102,19 +102,22 @@ use_java() { java -version } +# --batch-mode supresses download progress output that spams the logs. +MVN=mvn --batch-mode + build_java() { # Java build needs `protoc`. internal_build_cpp - cd java && mvn test && mvn install - cd util && mvn test + cd java && $MVN test && $MVN install + cd util && $MVN test cd ../.. } build_java_with_conformance_tests() { # Java build needs `protoc`. internal_build_cpp - cd java && mvn test && mvn install - cd util && mvn test && mvn assembly:single + cd java && $MVN test && $MVN install + cd util && $MVN test && $MVN assembly:single cd ../.. cd conformance && make test_java && cd .. } From b28b3f60a105af9b7ea05637b367429a3b6852c9 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Sat, 20 Feb 2016 12:17:10 -0800 Subject: [PATCH 08/17] Configure ccache directory. --- tools/jenkins/build_and_run_docker.sh | 6 ++++++ tools/run_tests/tests.sh | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/jenkins/build_and_run_docker.sh b/tools/jenkins/build_and_run_docker.sh index e77ffd612..448b00c0b 100755 --- a/tools/jenkins/build_and_run_docker.sh +++ b/tools/jenkins/build_and_run_docker.sh @@ -52,12 +52,18 @@ docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR # Choose random name for docker container CONTAINER_NAME="build_and_run_docker_$(uuidgen)" +# Ensure existence of ccache directory +CCACHE_DIR=/tmp/protobuf-ccache +mkdir -p $CCACHE_DIR + # Run command inside docker docker run \ "$@" \ + -e CCACHE_DIR=$CCACHE_DIR \ -e EXTERNAL_GIT_ROOT="/var/local/jenkins/protobuf" \ -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ -v "$git_root:/var/local/jenkins/protobuf:ro" \ + -v $CCACHE_DIR:$CCACHE_DIR \ -w /var/local/git/protobuf \ --name=$CONTAINER_NAME \ $DOCKER_IMAGE_NAME \ diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index 7ada81f84..353ce62df 100755 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -103,7 +103,7 @@ use_java() { } # --batch-mode supresses download progress output that spams the logs. -MVN=mvn --batch-mode +MVN="mvn --batch-mode" build_java() { # Java build needs `protoc`. @@ -125,7 +125,7 @@ build_java_with_conformance_tests() { build_javanano() { # Java build needs `protoc`. internal_build_cpp - cd javanano && mvn test && cd .. + cd javanano && $MVN test && cd .. } build_java_jdk6() { From f6153b540a71475b1af8cc6818a28d1145763e83 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Sat, 20 Feb 2016 12:50:27 -0800 Subject: [PATCH 09/17] Work around tox bug. --- python/tox.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/tox.ini b/python/tox.ini index cf8d54016..f663b5387 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -6,6 +6,10 @@ 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 From 78f9b68600c32492100ad61eb6b53ffa1f74263b Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Mon, 22 Feb 2016 14:26:21 -0800 Subject: [PATCH 10/17] Upgrade Python packages using pip. --- tools/docker/Dockerfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index b5b712fa2..2a451321e 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -60,13 +60,19 @@ RUN apt-get update && apt-get install -y \ openjdk-7-jdk \ # -- For python / python_cpp -- \ python-setuptools \ - python-tox \ + python-pip \ python-dev \ python2.6-dev \ python3.3-dev \ python3.4-dev \ && apt-get clean +# These packages exist in apt-get, but their versions are too old, so we have +# to get updates from pip. + +RUN pip install pip --upgrade +RUN pip install virtualenv tox + # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc RUN ln -s /usr/bin/ccache /usr/local/bin/g++ From ffc811804f4067c39f53d89fcbcaff1680d8e1fd Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Mon, 22 Feb 2016 15:39:29 -0800 Subject: [PATCH 11/17] Added Ruby 2.1, Oracle Java, and C#. --- tools/docker/Dockerfile | 47 ++++++++++++++++++++++++++++++++++++-- tools/run_tests/jenkins.sh | 10 ++++++-- tools/run_tests/tests.sh | 40 ++++++++++++++++++-------------- 3 files changed, 76 insertions(+), 21 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 2a451321e..578305652 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -30,9 +30,19 @@ # Base Dockerfile for gRPC dev images FROM debian:latest +# Apt source for old Python versions. RUN echo 'deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu trusty main' > /etc/apt/sources.list.d/deadsnakes.list && \ - gpg --keyserver keyserver.ubuntu.com --recv-keys DB82666C && \ - gpg --export DB82666C | apt-key add - + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DB82666C + +# Apt source for Oracle Java. +run echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 && \ + echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections + +# Apt source for Mono +run echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \ + echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list && \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF # Install dependencies. We start with the basic ones require to build protoc # and the C++ build @@ -52,12 +62,19 @@ RUN apt-get update && apt-get install -y \ libtool \ make \ parallel \ + wget \ + # -- For csharp -- + mono-devel \ + referenceassemblies-pcl \ + nunit \ # -- For all Java builds -- \ maven \ # -- For java_jdk6 -- \ # oops! not in jessie. too old? openjdk-6-jdk \ # -- For java_jdk7 -- \ openjdk-7-jdk \ + # -- For java_oracle7 -- \ + oracle-java7-installer \ # -- For python / python_cpp -- \ python-setuptools \ python-pip \ @@ -65,14 +82,40 @@ RUN apt-get update && apt-get install -y \ python2.6-dev \ python3.3-dev \ python3.4-dev \ + # -- For Ruby -- + ruby \ && apt-get clean +################## +# C# dependencies + +RUN wget www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe + +################## +# Python dependencies + # These packages exist in apt-get, but their versions are too old, so we have # to get updates from pip. RUN pip install pip --upgrade RUN pip install virtualenv tox + +################## +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.1 +RUN /bin/bash -l -c "rvm install ruby-2.1" +RUN /bin/bash -l -c "rvm use --default ruby-2.1" +RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" + # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc RUN ln -s /usr/bin/ccache /usr/local/bin/g++ diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index 1d192aa4b..620c21168 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -26,10 +26,16 @@ $TEST_SCRIPT cpp | tee $OUTPUT_DIR/1/cpp # Other tests are run in parallel. The overall run fails if any one of them # fails. -parallel $TEST_SCRIPT ::: \ +parallel --results $OUTPUT_DIR $TEST_SCRIPT ::: \ + csharp \ java_jdk7 \ javanano_jdk7 \ + java_oracle7 \ + javanano_oracle7 \ python \ - python_cpp + python_cpp \ + ruby21 # java_jdk6 \ + +find $OUTPUT_DIR diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index 353ce62df..623cf96c0 100755 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -45,16 +45,20 @@ build_csharp() { # need to really build protoc, but it's simplest to keep with the # conventions of the other builds. internal_build_cpp + NUGET=/usr/local/bin/nuget.exe - # Install latest version of Mono - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF - echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list - echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list - sudo apt-get update -qq - sudo apt-get install -qq mono-devel referenceassemblies-pcl nunit - wget www.nuget.org/NuGet.exe -O nuget.exe + if [ "$TRAVIS" == "true" ]; then + # Install latest version of Mono + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF + echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list + echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list + sudo apt-get update -qq + sudo apt-get install -qq mono-devel referenceassemblies-pcl nunit + wget www.nuget.org/NuGet.exe -O nuget.exe + NUGET=../../nuget.exe + fi - (cd csharp/src; mono ../../nuget.exe restore) + (cd csharp/src; mono $NUGET restore) csharp/buildall.sh cd conformance && make test_csharp && cd .. } @@ -89,11 +93,13 @@ use_java() { export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH ;; oracle7) - sudo apt-get install python-software-properties # for apt-add-repository - echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | \ - sudo debconf-set-selections - yes | sudo apt-add-repository ppa:webupd8team/java - yes | sudo apt-get install oracle-java7-installer + if [ "$TRAVIS" == "true" ]; then + sudo apt-get install python-software-properties # for apt-add-repository + echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | \ + sudo debconf-set-selections + yes | sudo apt-add-repository ppa:webupd8team/java + yes | sudo apt-get install oracle-java7-installer + fi; export PATH=/usr/lib/jvm/java-7-oracle/bin:$PATH ;; esac @@ -322,10 +328,10 @@ Usage: $0 { cpp | objectivec_osx | python | python_cpp | - ruby_19 | - ruby_20 | - ruby_21 | - ruby_22 | + ruby19 | + ruby20 | + ruby21 | + ruby22 | jruby } " exit 1 From 38bc15552de259fa99c8e9654bed0ff8433902eb Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Tue, 23 Feb 2016 14:28:02 -0800 Subject: [PATCH 12/17] Added code to generate XML output file for more granular results. --- python/tox.ini | 4 -- tools/docker/Dockerfile | 2 +- tools/jenkins/make_test_output.py | 90 +++++++++++++++++++++++++++++++ tools/jenkins/pull_request.sh | 1 + tools/run_tests/jenkins.sh | 36 ++++++++++--- 5 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 tools/jenkins/make_test_output.py diff --git a/python/tox.ini b/python/tox.ini index f663b5387..cf8d54016 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 578305652..bceb60449 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 000000000..0ba5db3bf --- /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 cb0f4072b..00538b9c4 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 620c21168..32050d254 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. +# 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 + +python $MY_DIR/../jenkins/make_test_output.py $OUTPUT_DIR > $TESTOUTPUT_XML_FILE + +ls -l $TESTOUTPUT_XML_FILE + +### disabled tests # java_jdk6 \ - -find $OUTPUT_DIR From 2f3f1de16debdff284792367245d5ba0e9310b35 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Tue, 1 Mar 2016 15:37:17 -0800 Subject: [PATCH 13/17] Make Java copy into separate directories so the tests can run concurrently. --- tools/run_tests/tests.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index 623cf96c0..4b2aef77a 100755 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -112,18 +112,22 @@ use_java() { MVN="mvn --batch-mode" build_java() { + version=$1 + dir=java_$version # Java build needs `protoc`. internal_build_cpp - cd java && $MVN test && $MVN install - cd util && $MVN test + cp -r java $dir + cd $dir && $MVN clean && $MVN test cd ../.. } +# The conformance tests are hard-coded to work with the $ROOT/java directory. +# So this can't run in parallel with two different sets of tests. build_java_with_conformance_tests() { # Java build needs `protoc`. internal_build_cpp cd java && $MVN test && $MVN install - cd util && $MVN test && $MVN assembly:single + cd util && $MVN package assembly:single cd ../.. cd conformance && make test_java && cd .. } @@ -136,7 +140,7 @@ build_javanano() { build_java_jdk6() { use_java jdk6 - build_java + build_java jdk6 } build_java_jdk7() { use_java jdk7 @@ -144,7 +148,7 @@ build_java_jdk7() { } build_java_oracle7() { use_java oracle7 - build_java + build_java oracle7 } build_javanano_jdk6() { From 1ee0fda556b252944e7dd140ad0cd7b8949eb496 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 3 Mar 2016 16:02:55 -0800 Subject: [PATCH 14/17] Use a local Maven repository to avoid network fetches during tests. --- tools/docker/Dockerfile | 26 ++++++++++++++++++++++++++ tools/run_tests/tests.sh | 5 +++++ 2 files changed, 31 insertions(+) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index bceb60449..b7621f678 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -116,7 +116,11 @@ RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +################## # Prepare ccache + +# We do this BEFORE the Java dependency step below, so the build of protoc +# can benefit from it. RUN ln -s /usr/bin/ccache /usr/local/bin/gcc RUN ln -s /usr/bin/ccache /usr/local/bin/g++ RUN ln -s /usr/bin/ccache /usr/local/bin/cc @@ -124,5 +128,27 @@ RUN ln -s /usr/bin/ccache /usr/local/bin/c++ RUN ln -s /usr/bin/ccache /usr/local/bin/clang RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ + +################## +# Java dependencies + +# This step requires compiling protoc. :( + +ENV MAVEN_REPO /var/maven_local_repository +ENV MVN mvn --batch-mode + +RUN cd /tmp && \ + git clone https://github.com/google/protobuf.git && \ + cd protobuf && \ + ./autogen.sh && \ + ./configure && \ + make -j6 && \ + cd java && \ + $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO -P lite && \ + $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO && \ + cd ../javanano && \ + $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO + + # Define the default command. CMD ["bash"] diff --git a/tools/run_tests/tests.sh b/tools/run_tests/tests.sh index 4b2aef77a..c28a5daaa 100755 --- a/tools/run_tests/tests.sh +++ b/tools/run_tests/tests.sh @@ -104,6 +104,11 @@ use_java() { ;; esac + if [ "$TRAVIS" != "true" ]; then + MAVEN_LOCAL_REPOSITORY=/var/maven_local_repository + MVN="$MVN -e -X --offline -Dmaven.repo.local=$MAVEN_LOCAL_REPOSITORY" + fi; + which java java -version } From 2bda98f79ca9f43091d2033cf02c9732a0515a7a Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 3 Mar 2016 17:04:36 -0800 Subject: [PATCH 15/17] Properly report C++ build time. --- tools/jenkins/build_and_run_docker.sh | 14 ++++++++------ tools/jenkins/make_test_output.py | 4 ++-- tools/run_tests/jenkins.sh | 7 ++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/tools/jenkins/build_and_run_docker.sh b/tools/jenkins/build_and_run_docker.sh index 448b00c0b..18b910a73 100755 --- a/tools/jenkins/build_and_run_docker.sh +++ b/tools/jenkins/build_and_run_docker.sh @@ -46,16 +46,18 @@ cd - # Use image name based on Dockerfile location checksum DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) -# Make sure docker image has been built. Should be instantaneous if so. -docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR - -# Choose random name for docker container -CONTAINER_NAME="build_and_run_docker_$(uuidgen)" - # Ensure existence of ccache directory CCACHE_DIR=/tmp/protobuf-ccache mkdir -p $CCACHE_DIR +# Make sure docker image has been built. Should be instantaneous if so. +docker build \ + -v $CCACHE_DIR:$CCACHE_DIR \ + -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR + +# Choose random name for docker container +CONTAINER_NAME="build_and_run_docker_$(uuidgen)" + # Run command inside docker docker run \ "$@" \ diff --git a/tools/jenkins/make_test_output.py b/tools/jenkins/make_test_output.py index 0ba5db3bf..986d19793 100644 --- a/tools/jenkins/make_test_output.py +++ b/tools/jenkins/make_test_output.py @@ -58,8 +58,8 @@ def readtests(basedir): # up in the job log. tests["cpp"]["name"] = "cpp" - # TODO - tests["cpp"]["time"] = "0" + with open(basedir + '/logs/1/cpp/build_time', 'r') as f: + tests["cpp"]["time"] = f.read().strip() tests["cpp"]["failure"] = False ret = tests.values() diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index 32050d254..0bd9ffe5f 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -34,7 +34,12 @@ mkdir -p $LOG_OUTPUT_DIR/1/cpp # $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) + +# It's important that we get /usr/bin/time (which supports -f and -o) and not +# the bash builtin "time" which doesn't. +TIME_CMD="/usr/bin/time -f %e -o $LOG_OUTPUT_DIR/1/cpp/build_time" + +$TIME_CMD $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. From 7d793c167f51d5afff18e13b1dc1c0b060b3aae4 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 3 Mar 2016 17:08:37 -0800 Subject: [PATCH 16/17] Disable attempt to use ccache for docker build. --- tools/docker/Dockerfile | 23 ++++++++++------------- tools/jenkins/build_and_run_docker.sh | 8 +++----- tools/run_tests/jenkins.sh | 2 -- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index b7621f678..5136ee6b2 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -62,6 +62,7 @@ RUN apt-get update && apt-get install -y \ libtool \ make \ parallel \ + time \ wget \ # -- For csharp -- mono-devel \ @@ -116,19 +117,6 @@ RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" -################## -# Prepare ccache - -# We do this BEFORE the Java dependency step below, so the build of protoc -# can benefit from it. -RUN ln -s /usr/bin/ccache /usr/local/bin/gcc -RUN ln -s /usr/bin/ccache /usr/local/bin/g++ -RUN ln -s /usr/bin/ccache /usr/local/bin/cc -RUN ln -s /usr/bin/ccache /usr/local/bin/c++ -RUN ln -s /usr/bin/ccache /usr/local/bin/clang -RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ - - ################## # Java dependencies @@ -149,6 +137,15 @@ RUN cd /tmp && \ cd ../javanano && \ $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO +################## +# Prepare ccache + +RUN ln -s /usr/bin/ccache /usr/local/bin/gcc +RUN ln -s /usr/bin/ccache /usr/local/bin/g++ +RUN ln -s /usr/bin/ccache /usr/local/bin/cc +RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN ln -s /usr/bin/ccache /usr/local/bin/clang +RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ # Define the default command. CMD ["bash"] diff --git a/tools/jenkins/build_and_run_docker.sh b/tools/jenkins/build_and_run_docker.sh index 18b910a73..ad1075fa9 100755 --- a/tools/jenkins/build_and_run_docker.sh +++ b/tools/jenkins/build_and_run_docker.sh @@ -46,15 +46,13 @@ cd - # Use image name based on Dockerfile location checksum DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) +# Make sure docker image has been built. Should be instantaneous if so. +docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR + # Ensure existence of ccache directory CCACHE_DIR=/tmp/protobuf-ccache mkdir -p $CCACHE_DIR -# Make sure docker image has been built. Should be instantaneous if so. -docker build \ - -v $CCACHE_DIR:$CCACHE_DIR \ - -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR - # Choose random name for docker container CONTAINER_NAME="build_and_run_docker_$(uuidgen)" diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh index 0bd9ffe5f..ea67345b6 100755 --- a/tools/run_tests/jenkins.sh +++ b/tools/run_tests/jenkins.sh @@ -44,8 +44,6 @@ $TIME_CMD $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. -FAILED=false - parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: \ csharp \ java_jdk7 \ From 67c727cd411a339eb4233c84d9a1afadd8c20566 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 4 Mar 2016 14:21:18 -0800 Subject: [PATCH 17/17] Rearranged and commented files for running under Jenkins. --- .travis.yml | 2 +- jenkins/README.md | 6 ++ jenkins/build_and_run_docker.sh | 56 +++++++++++++ jenkins/buildcmds/README.md | 6 ++ jenkins/buildcmds/pull_request.sh | 15 ++++ {tools => jenkins}/docker/Dockerfile | 33 ++------ .../jenkins => jenkins}/make_test_output.py | 7 +- .../pull_request_in_docker.sh | 24 +++--- tools/run_tests/tests.sh => tests.sh | 15 ++-- tools/jenkins/build_and_run_docker.sh | 84 ------------------- tools/jenkins/pull_request.sh | 7 -- 11 files changed, 115 insertions(+), 140 deletions(-) create mode 100644 jenkins/README.md create mode 100755 jenkins/build_and_run_docker.sh create mode 100644 jenkins/buildcmds/README.md create mode 100755 jenkins/buildcmds/pull_request.sh rename {tools => jenkins}/docker/Dockerfile (70%) rename {tools/jenkins => jenkins}/make_test_output.py (91%) rename tools/run_tests/jenkins.sh => jenkins/pull_request_in_docker.sh (69%) rename tools/run_tests/tests.sh => tests.sh (97%) delete mode 100755 tools/jenkins/build_and_run_docker.sh delete mode 100755 tools/jenkins/pull_request.sh diff --git a/.travis.yml b/.travis.yml index 26b9dcaff..f8d2347c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ os: # The Objective C build needs Xcode 7.0 or later. osx_image: xcode7.2 script: - - ./tools/run_tests/tests.sh $CONFIG + - ./tests.sh $CONFIG env: - CONFIG=cpp - CONFIG=cpp_distcheck diff --git a/jenkins/README.md b/jenkins/README.md new file mode 100644 index 000000000..29f664f29 --- /dev/null +++ b/jenkins/README.md @@ -0,0 +1,6 @@ + +Jenkins Infrastructure +---------------------- + +The scripts in this directory serve as plumbing for running the protobuf +tests under Jenkins. diff --git a/jenkins/build_and_run_docker.sh b/jenkins/build_and_run_docker.sh new file mode 100755 index 000000000..abc6f055c --- /dev/null +++ b/jenkins/build_and_run_docker.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Builds docker image and runs a command under it. +# This is a generic script that is configured with the following variables: +# +# DOCKERFILE_DIR - Directory in which Dockerfile file is located. +# DOCKER_RUN_SCRIPT - Script to run under docker (relative to protobuf repo root) +# OUTPUT_DIR - Directory that will be copied from inside docker after finishing. +# $@ - Extra args to pass to docker run + + +set -ex + +cd $(dirname $0)/.. +git_root=$(pwd) +cd - + +# Use image name based on Dockerfile location checksum +DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) + +# Make sure docker image has been built. Should be instantaneous if so. +docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR + +# Ensure existence of ccache directory +CCACHE_DIR=/tmp/protobuf-ccache +mkdir -p $CCACHE_DIR + +# Choose random name for docker container +CONTAINER_NAME="build_and_run_docker_$(uuidgen)" + +# Run command inside docker +docker run \ + "$@" \ + -e CCACHE_DIR=$CCACHE_DIR \ + -e EXTERNAL_GIT_ROOT="/var/local/jenkins/protobuf" \ + -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ + -v "$git_root:/var/local/jenkins/protobuf:ro" \ + -v $CCACHE_DIR:$CCACHE_DIR \ + -w /var/local/git/protobuf \ + --name=$CONTAINER_NAME \ + $DOCKER_IMAGE_NAME \ + bash -l "/var/local/jenkins/protobuf/$DOCKER_RUN_SCRIPT" || FAILED="true" + +# Copy output artifacts +if [ "$OUTPUT_DIR" != "" ] +then + docker cp "$CONTAINER_NAME:/var/local/git/protobuf/$OUTPUT_DIR" "$git_root" || FAILED="true" +fi + +# remove the container, possibly killing it first +docker rm -f $CONTAINER_NAME || true + +if [ "$FAILED" != "" ] +then + exit 1 +fi diff --git a/jenkins/buildcmds/README.md b/jenkins/buildcmds/README.md new file mode 100644 index 000000000..7a48f2d5c --- /dev/null +++ b/jenkins/buildcmds/README.md @@ -0,0 +1,6 @@ + +Jenkins Build Commands +---------------------- + +The scripts in this directory are designed to be top-level entry points for +Jenkins projects. diff --git a/jenkins/buildcmds/pull_request.sh b/jenkins/buildcmds/pull_request.sh new file mode 100755 index 000000000..01fda7985 --- /dev/null +++ b/jenkins/buildcmds/pull_request.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# +# This is the top-level script we give to Jenkins as the entry point for +# running the "pull request" project: +# +# https://grpc-testing.appspot.com/view/Protocol%20Buffers/job/protobuf_pull_request/ +# +# This script selects a specific Dockerfile (for building a Docker image) and +# a script to run inside that image. Then we delegate to the general +# build_and_run_docker.sh script. + +export DOCKERFILE_DIR=jenkins/docker +export DOCKER_RUN_SCRIPT=jenkins/pull_request_in_docker.sh +export OUTPUT_DIR=testoutput +./jenkins/build_and_run_docker.sh diff --git a/tools/docker/Dockerfile b/jenkins/docker/Dockerfile similarity index 70% rename from tools/docker/Dockerfile rename to jenkins/docker/Dockerfile index 5136ee6b2..8467aeff5 100644 --- a/tools/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -1,31 +1,10 @@ -# Copyright 2015, Google Inc. -# All rights reserved. +# This Dockerfile specifies the recipe for creating an image for the tests +# to run in. # -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# We install as many test dependencies here as we can, because these setup +# steps can be cached. They do *not* run every time we run the build. +# The Docker image is only rebuilt when the Dockerfile (ie. this file) +# changes. # Base Dockerfile for gRPC dev images FROM debian:latest diff --git a/tools/jenkins/make_test_output.py b/jenkins/make_test_output.py similarity index 91% rename from tools/jenkins/make_test_output.py rename to jenkins/make_test_output.py index 986d19793..b1f2e2c0b 100644 --- a/tools/jenkins/make_test_output.py +++ b/jenkins/make_test_output.py @@ -1,9 +1,9 @@ -"""Gather output from test runs and create an XML file in JUnit format. +"""Gathers 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/joblog (output from "parallel --joblog joblog") $DIR/logs/1/cpp/stdout $DIR/logs/1/cpp/stderr $DIR/logs/1/csharp/stdout @@ -13,7 +13,8 @@ structure like: etc. This script bundles them into a single output XML file so Jenkins can show -detailed test results. +detailed test results. It runs as the last step before the Jenkins build +finishes. """ import os; diff --git a/tools/run_tests/jenkins.sh b/jenkins/pull_request_in_docker.sh similarity index 69% rename from tools/run_tests/jenkins.sh rename to jenkins/pull_request_in_docker.sh index ea67345b6..887f97c59 100755 --- a/tools/run_tests/jenkins.sh +++ b/jenkins/pull_request_in_docker.sh @@ -1,22 +1,25 @@ #!/bin/bash +# +# This is the script that runs inside Docker, once the image has been built, +# to execute all tests for the "pull request" project. WORKSPACE_BASE=`pwd` MY_DIR="$(dirname "$0")" -TEST_SCRIPT=$MY_DIR/tests.sh +TEST_SCRIPT=$MY_DIR/../tests.sh BUILD_DIR=/tmp/protobuf -# Set value used in tests.sh. -PARALLELISM=-j8 - set -e # exit immediately on error set -x # display all commands +# The protobuf repository is mounted into our Docker image, but read-only. +# We clone into a directory inside Docker (this is faster than cp). rm -rf $BUILD_DIR mkdir -p $BUILD_DIR cd $BUILD_DIR git clone /var/local/jenkins/protobuf cd protobuf +# Set up the directory where our test output is going to go. OUTPUT_DIR=`mktemp -d` LOG_OUTPUT_DIR=$OUTPUT_DIR/logs mkdir -p $LOG_OUTPUT_DIR/1/cpp @@ -35,14 +38,14 @@ mkdir -p $LOG_OUTPUT_DIR/1/cpp CPP_STDOUT=$LOG_OUTPUT_DIR/1/cpp/stdout CPP_STDERR=$LOG_OUTPUT_DIR/1/cpp/stderr +# Time the C++ build, so we can put this info in the test output. # It's important that we get /usr/bin/time (which supports -f and -o) and not # the bash builtin "time" which doesn't. TIME_CMD="/usr/bin/time -f %e -o $LOG_OUTPUT_DIR/1/cpp/build_time" $TIME_CMD $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. +# Other tests are run in parallel. parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: \ csharp \ @@ -55,14 +58,15 @@ parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: ruby21 \ || true # Process test results even if tests fail. +cat $OUTPUT_DIR/joblog + # 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 -python $MY_DIR/../jenkins/make_test_output.py $OUTPUT_DIR > $TESTOUTPUT_XML_FILE +# Process all the output files from "parallel" and package them into a single +# .xml file with detailed, broken-down test output. +python $MY_DIR/make_test_output.py $OUTPUT_DIR > $TESTOUTPUT_XML_FILE ls -l $TESTOUTPUT_XML_FILE - -### disabled tests -# java_jdk6 \ diff --git a/tools/run_tests/tests.sh b/tests.sh similarity index 97% rename from tools/run_tests/tests.sh rename to tests.sh index c28a5daaa..a4624c0c9 100755 --- a/tools/run_tests/tests.sh +++ b/tests.sh @@ -1,4 +1,8 @@ #!/bin/bash +# +# Build and runs tests for the protobuf project. The tests as written here are +# used by both Jenkins and Travis, though some specialized logic is required to +# handle the differences between them. on_travis() { if [ "$TRAVIS" == "true" ]; then @@ -25,19 +29,19 @@ internal_build_cpp() { ./autogen.sh ./configure - make $PARALLELISM + make -j2 } build_cpp() { internal_build_cpp - make check $PARALLELISM + make check -j2 cd conformance && make test_cpp && cd .. } build_cpp_distcheck() { ./autogen.sh ./configure - make distcheck $PARALLELISM + make distcheck -j2 } build_csharp() { @@ -308,8 +312,6 @@ build_javascript() { cd js && npm install && npm test && cd .. } -[ -n "${PARALLELISM}" ] && PARALLELISM=-j8 - # Note: travis currently does not support testing more than one language so the # .travis.yml cheats and claims to only be cpp. If they add multiple language # support, this should probably get updated to install steps and/or @@ -320,9 +322,6 @@ build_javascript() { # -------- main -------- -# Set value used in tests.sh. -PARALLELISM=-j2 - if [ "$#" -ne 1 ]; then echo " Usage: $0 { cpp | diff --git a/tools/jenkins/build_and_run_docker.sh b/tools/jenkins/build_and_run_docker.sh deleted file mode 100755 index ad1075fa9..000000000 --- a/tools/jenkins/build_and_run_docker.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash -# Copyright 2016, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Builds docker image and runs a command under it. -# You should never need to call this script on your own. - -set -ex - -cd $(dirname $0)/../.. -git_root=$(pwd) -cd - - -# Inputs -# DOCKERFILE_DIR - Directory in which Dockerfile file is located. -# DOCKER_RUN_SCRIPT - Script to run under docker (relative to protobuf repo root) -# OUTPUT_DIR - Directory that will be copied from inside docker after finishing. -# $@ - Extra args to pass to docker run - -# Use image name based on Dockerfile location checksum -DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) - -# Make sure docker image has been built. Should be instantaneous if so. -docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR - -# Ensure existence of ccache directory -CCACHE_DIR=/tmp/protobuf-ccache -mkdir -p $CCACHE_DIR - -# Choose random name for docker container -CONTAINER_NAME="build_and_run_docker_$(uuidgen)" - -# Run command inside docker -docker run \ - "$@" \ - -e CCACHE_DIR=$CCACHE_DIR \ - -e EXTERNAL_GIT_ROOT="/var/local/jenkins/protobuf" \ - -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ - -v "$git_root:/var/local/jenkins/protobuf:ro" \ - -v $CCACHE_DIR:$CCACHE_DIR \ - -w /var/local/git/protobuf \ - --name=$CONTAINER_NAME \ - $DOCKER_IMAGE_NAME \ - bash -l "/var/local/jenkins/protobuf/$DOCKER_RUN_SCRIPT" || FAILED="true" - -# Copy output artifacts -if [ "$OUTPUT_DIR" != "" ] -then - docker cp "$CONTAINER_NAME:/var/local/git/protobuf/$OUTPUT_DIR" "$git_root" || FAILED="true" -fi - -# remove the container, possibly killing it first -docker rm -f $CONTAINER_NAME || true - -if [ "$FAILED" != "" ] -then - exit 1 -fi diff --git a/tools/jenkins/pull_request.sh b/tools/jenkins/pull_request.sh deleted file mode 100755 index 00538b9c4..000000000 --- a/tools/jenkins/pull_request.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - - -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