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 7on_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. 15internal_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 35build_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 44build_cpp_distcheck() { 45 ./autogen.sh 46 ./configure 47 make distcheck -j2 48} 49 50build_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 73build_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 91use_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. 124MVN="mvn --batch-mode" 125 126build_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. 138build_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 147build_javanano() { 148 # Java build needs `protoc`. 149 internal_build_cpp 150 cd javanano && $MVN test && cd .. 151} 152 153build_java_jdk6() { 154 use_java jdk6 155 build_java jdk6 156} 157build_java_jdk7() { 158 use_java jdk7 159 build_java_with_conformance_tests 160} 161build_java_oracle7() { 162 use_java oracle7 163 build_java oracle7 164} 165 166build_javanano_jdk6() { 167 use_java jdk6 168 build_javanano 169} 170build_javanano_jdk7() { 171 use_java jdk7 172 build_javanano 173} 174build_javanano_oracle7() { 175 use_java oracle7 176 build_javanano 177} 178 179internal_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 200internal_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 212internal_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 219build_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 245build_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 255build_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 269build_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 286build_ruby19() { 287 internal_build_cpp # For conformance tests. 288 cd ruby && bash travis-test.sh ruby-1.9 && cd .. 289} 290build_ruby20() { 291 internal_build_cpp # For conformance tests. 292 cd ruby && bash travis-test.sh ruby-2.0 && cd .. 293} 294build_ruby21() { 295 internal_build_cpp # For conformance tests. 296 cd ruby && bash travis-test.sh ruby-2.1 && cd .. 297} 298build_ruby22() { 299 internal_build_cpp # For conformance tests. 300 cd ruby && bash travis-test.sh ruby-2.2 && cd .. 301} 302build_jruby() { 303 internal_build_cpp # For conformance tests. 304 cd ruby && bash travis-test.sh jruby && cd .. 305} 306 307build_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 322if [ "$#" -ne 1 ]; then 323 echo " 324Usage: $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 343fi 344 345set -e # exit immediately on error 346set -x # display all commands 347eval "build_$1" 348