Home | History | Annotate | Download | only in util
      1 #!/bin/bash
      2 #
      3 # Build and runs tests for the protobuf project.  The tests as written here are
      4 # used by both Jenkins and Travis, though some specialized logic is required to
      5 # handle the differences between them.
      6 
      7 on_travis() {
      8   if [ "$TRAVIS" == "true" ]; then
      9     "$@"
     10   fi
     11 }
     12 
     13 # For when some other test needs the C++ main build, including protoc and
     14 # libprotobuf.
     15 internal_build_cpp() {
     16   if [ -f src/protoc ]; then
     17     # Already built.
     18     return
     19   fi
     20 
     21   if [[ $(uname -s) == "Linux" && "$TRAVIS" == "true" ]]; then
     22     # Install GCC 4.8 to replace the default GCC 4.6. We need 4.8 for more
     23     # decent C++ 11 support in order to compile conformance tests.
     24     sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
     25     sudo apt-get update -qq
     26     sudo apt-get install -qq g++-4.8
     27     export CXX="g++-4.8" CC="gcc-4.8"
     28   fi
     29 
     30   ./autogen.sh
     31   ./configure
     32   make -j2
     33 }
     34 
     35 build_cpp() {
     36   internal_build_cpp
     37   make check -j2
     38   cd conformance && make test_cpp && cd ..
     39 
     40   # Verify benchmarking code can build successfully.
     41   cd benchmarks && make && ./generate-datasets && cd ..
     42 }
     43 
     44 build_cpp_distcheck() {
     45   ./autogen.sh
     46   ./configure
     47   make distcheck -j2
     48 }
     49 
     50 build_csharp() {
     51   # Just for the conformance tests. We don't currently
     52   # need to really build protoc, but it's simplest to keep with the
     53   # conventions of the other builds.
     54   internal_build_cpp
     55   NUGET=/usr/local/bin/nuget.exe
     56 
     57   if [ "$TRAVIS" == "true" ]; then
     58     # Install latest version of Mono
     59     sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
     60     echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
     61     echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list
     62     sudo apt-get update -qq
     63     sudo apt-get install -qq mono-devel referenceassemblies-pcl nunit
     64     wget www.nuget.org/NuGet.exe -O nuget.exe
     65     NUGET=../../nuget.exe
     66   fi
     67 
     68   (cd csharp/src; mono $NUGET restore)
     69   csharp/buildall.sh
     70   cd conformance && make test_csharp && cd ..
     71 }
     72 
     73 build_golang() {
     74   # Go build needs `protoc`.
     75   internal_build_cpp
     76   # Add protoc to the path so that the examples build finds it.
     77   export PATH="`pwd`/src:$PATH"
     78 
     79   # Install Go and the Go protobuf compiler plugin.
     80   sudo apt-get update -qq
     81   sudo apt-get install -qq golang
     82   export GOPATH="$HOME/gocode"
     83   mkdir -p "$GOPATH/src/github.com/google"
     84   ln -s "`pwd`" "$GOPATH/src/github.com/google/protobuf"
     85   export PATH="$GOPATH/bin:$PATH"
     86   go get github.com/golang/protobuf/protoc-gen-go
     87 
     88   cd examples && make gotest && cd ..
     89 }
     90 
     91 use_java() {
     92   version=$1
     93   case "$version" in
     94     jdk6)
     95       on_travis sudo apt-get install openjdk-6-jdk
     96       export PATH=/usr/lib/jvm/java-6-openjdk-amd64/bin:$PATH
     97       ;;
     98     jdk7)
     99       on_travis sudo apt-get install openjdk-7-jdk
    100       export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
    101       ;;
    102     oracle7)
    103       if [ "$TRAVIS" == "true" ]; then
    104         sudo apt-get install python-software-properties # for apt-add-repository
    105         echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | \
    106           sudo debconf-set-selections
    107         yes | sudo apt-add-repository ppa:webupd8team/java
    108         yes | sudo apt-get install oracle-java7-installer
    109       fi;
    110       export PATH=/usr/lib/jvm/java-7-oracle/bin:$PATH
    111       ;;
    112   esac
    113 
    114   if [ "$TRAVIS" != "true" ]; then
    115     MAVEN_LOCAL_REPOSITORY=/var/maven_local_repository
    116     MVN="$MVN -e -X --offline -Dmaven.repo.local=$MAVEN_LOCAL_REPOSITORY"
    117   fi;
    118 
    119   which java
    120   java -version
    121 }
    122 
    123 # --batch-mode supresses download progress output that spams the logs.
    124 MVN="mvn --batch-mode"
    125 
    126 build_java() {
    127   version=$1
    128   dir=java_$version
    129   # Java build needs `protoc`.
    130   internal_build_cpp
    131   cp -r java $dir
    132   cd $dir && $MVN clean && $MVN test
    133   cd ../..
    134 }
    135 
    136 # The conformance tests are hard-coded to work with the $ROOT/java directory.
    137 # So this can't run in parallel with two different sets of tests.
    138 build_java_with_conformance_tests() {
    139   # Java build needs `protoc`.
    140   internal_build_cpp
    141   cd java && $MVN test && $MVN install
    142   cd util && $MVN package assembly:single
    143   cd ../..
    144   cd conformance && make test_java && cd ..
    145 }
    146 
    147 build_javanano() {
    148   # Java build needs `protoc`.
    149   internal_build_cpp
    150   cd javanano && $MVN test && cd ..
    151 }
    152 
    153 build_java_jdk6() {
    154   use_java jdk6
    155   build_java jdk6
    156 }
    157 build_java_jdk7() {
    158   use_java jdk7
    159   build_java_with_conformance_tests
    160 }
    161 build_java_oracle7() {
    162   use_java oracle7
    163   build_java oracle7
    164 }
    165 
    166 build_javanano_jdk6() {
    167   use_java jdk6
    168   build_javanano
    169 }
    170 build_javanano_jdk7() {
    171   use_java jdk7
    172   build_javanano
    173 }
    174 build_javanano_oracle7() {
    175   use_java oracle7
    176   build_javanano
    177 }
    178 
    179 internal_install_python_deps() {
    180   if [ "$TRAVIS" != "true" ]; then
    181     return;
    182   fi
    183   # Install tox (OS X doesn't have pip).
    184   if [ $(uname -s) == "Darwin" ]; then
    185     sudo easy_install tox
    186   else
    187     sudo pip install tox
    188   fi
    189   # Only install Python2.6/3.x on Linux.
    190   if [ $(uname -s) == "Linux" ]; then
    191     sudo apt-get install -y python-software-properties # for apt-add-repository
    192     sudo apt-add-repository -y ppa:fkrull/deadsnakes
    193     sudo apt-get update -qq
    194     sudo apt-get install -y python2.6 python2.6-dev
    195     sudo apt-get install -y python3.3 python3.3-dev
    196     sudo apt-get install -y python3.4 python3.4-dev
    197   fi
    198 }
    199 
    200 internal_objectivec_common () {
    201   # Make sure xctool is up to date. Adapted from
    202   #  http://docs.travis-ci.com/user/osx-ci-environment/
    203   # We don't use a before_install because we test multiple OSes.
    204   brew update
    205   brew outdated xctool || brew upgrade xctool
    206   # Reused the build script that takes care of configuring and ensuring things
    207   # are up to date. Xcode and conformance tests will be directly invoked.
    208   objectivec/DevTools/full_mac_build.sh \
    209       --core-only --skip-xcode --skip-objc-conformance
    210 }
    211 
    212 internal_xctool_debug_and_release() {
    213   # Always use -reporter plain to avoid escape codes in output (makes travis
    214   # logs easier to read).
    215   xctool -reporter plain -configuration Debug "$@"
    216   xctool -reporter plain -configuration Release "$@"
    217 }
    218 
    219 build_objectivec_ios() {
    220   internal_objectivec_common
    221   # https://github.com/facebook/xctool/issues/509 - unlike xcodebuild, xctool
    222   # doesn't support >1 destination, so we have to build first and then run the
    223   # tests one destination at a time.
    224   internal_xctool_debug_and_release \
    225     -project objectivec/ProtocolBuffers_iOS.xcodeproj \
    226     -scheme ProtocolBuffers \
    227     -sdk iphonesimulator \
    228     build-tests
    229   IOS_DESTINATIONS=(
    230     "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
    231     "platform=iOS Simulator,name=iPhone 6,OS=9.2" # 64bit
    232     "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit
    233     "platform=iOS Simulator,name=iPad Air,OS=9.2" # 64bit
    234   )
    235   for i in "${IOS_DESTINATIONS[@]}" ; do
    236     internal_xctool_debug_and_release \
    237       -project objectivec/ProtocolBuffers_iOS.xcodeproj \
    238       -scheme ProtocolBuffers \
    239       -sdk iphonesimulator \
    240       -destination "${i}" \
    241       run-tests
    242   done
    243 }
    244 
    245 build_objectivec_osx() {
    246   internal_objectivec_common
    247   internal_xctool_debug_and_release \
    248     -project objectivec/ProtocolBuffers_OSX.xcodeproj \
    249     -scheme ProtocolBuffers \
    250     -destination "platform=OS X,arch=x86_64" \
    251     test
    252   cd conformance && make test_objc && cd ..
    253 }
    254 
    255 build_python() {
    256   internal_build_cpp
    257   internal_install_python_deps
    258   cd python
    259   # Only test Python 2.6/3.x on Linux
    260   if [ $(uname -s) == "Linux" ]; then
    261     envlist=py\{26,27,33,34\}-python
    262   else
    263     envlist=py27-python
    264   fi
    265   tox -e $envlist
    266   cd ..
    267 }
    268 
    269 build_python_cpp() {
    270   internal_build_cpp
    271   internal_install_python_deps
    272   export LD_LIBRARY_PATH=../src/.libs # for Linux
    273   export DYLD_LIBRARY_PATH=../src/.libs # for OS X
    274   cd python
    275   # Only test Python 2.6/3.x on Linux
    276   if [ $(uname -s) == "Linux" ]; then
    277     # py26 is currently disabled due to json_format
    278     envlist=py\{27,33,34\}-cpp
    279   else
    280     envlist=py27-cpp
    281   fi
    282   tox -e $envlist
    283   cd ..
    284 }
    285 
    286 build_ruby19() {
    287   internal_build_cpp  # For conformance tests.
    288   cd ruby && bash travis-test.sh ruby-1.9 && cd ..
    289 }
    290 build_ruby20() {
    291   internal_build_cpp  # For conformance tests.
    292   cd ruby && bash travis-test.sh ruby-2.0 && cd ..
    293 }
    294 build_ruby21() {
    295   internal_build_cpp  # For conformance tests.
    296   cd ruby && bash travis-test.sh ruby-2.1 && cd ..
    297 }
    298 build_ruby22() {
    299   internal_build_cpp  # For conformance tests.
    300   cd ruby && bash travis-test.sh ruby-2.2 && cd ..
    301 }
    302 build_jruby() {
    303   internal_build_cpp  # For conformance tests.
    304   cd ruby && bash travis-test.sh jruby && cd ..
    305 }
    306 
    307 build_javascript() {
    308   internal_build_cpp
    309   cd js && npm install && npm test && cd ..
    310 }
    311 
    312 # Note: travis currently does not support testing more than one language so the
    313 # .travis.yml cheats and claims to only be cpp.  If they add multiple language
    314 # support, this should probably get updated to install steps and/or
    315 # rvm/gemfile/jdk/etc. entries rather than manually doing the work.
    316 
    317 # .travis.yml uses matrix.exclude to block the cases where app-get can't be
    318 # use to install things.
    319 
    320 # -------- main --------
    321 
    322 if [ "$#" -ne 1 ]; then
    323   echo "
    324 Usage: $0 { cpp |
    325             csharp |
    326             java_jdk6 |
    327             java_jdk7 |
    328             java_oracle7 |
    329             javanano_jdk6 |
    330             javanano_jdk7 |
    331             javanano_oracle7 |
    332             objectivec_ios |
    333             objectivec_osx |
    334             python |
    335             python_cpp |
    336             ruby19 |
    337             ruby20 |
    338             ruby21 |
    339             ruby22 |
    340             jruby }
    341 "
    342   exit 1
    343 fi
    344 
    345 set -e  # exit immediately on error
    346 set -x  # display all commands
    347 eval "build_$1"
    348