blob: c6eda93e2d2d395b94be9c94d0c0a5feaebae0e2 [file] [log] [blame]
Artem Titov739351d2018-05-11 12:21:36 +02001#!/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 CXXFLAGS="-fPIC" # -fPIC is needed for python cpp test.
32 # See python/setup.py for more details
33 make -j2
34}
35
36build_cpp() {
37 internal_build_cpp
38 make check -j2
39 cd conformance && make test_cpp && cd ..
40
41 # The benchmark code depends on cmake, so test if it is installed before
42 # trying to do the build.
43 # NOTE: The travis macOS images say they have cmake, but the xcode8.1 image
44 # appears to be missing it: https://github.com/travis-ci/travis-ci/issues/6996
45 if [[ $(type cmake 2>/dev/null) ]]; then
46 # Verify benchmarking code can build successfully.
47 git submodule init
48 git submodule update
49 cd third_party/benchmark && cmake -DCMAKE_BUILD_TYPE=Release && make && cd ../..
50 cd benchmarks && make && ./generate-datasets && cd ..
51 else
52 echo ""
53 echo "WARNING: Skipping validation of the bench marking code, cmake isn't installed."
54 echo ""
55 fi
56}
57
58build_cpp_distcheck() {
59 ./autogen.sh
60 ./configure
61 make dist
62
63 # List all files that should be included in the distribution package.
64 git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\)" |\
65 grep -v ".gitignore" | grep -v "java/compatibility_tests" |\
66 grep -v "python/compatibility_tests" | grep -v "csharp/compatibility_tests" > dist.lst
67 # Unzip the dist tar file.
68 DIST=`ls *.tar.gz`
69 tar -xf $DIST
70 cd ${DIST//.tar.gz}
71 # Check if every file exists in the dist tar file.
72 FILES_MISSING=""
73 for FILE in $(<../dist.lst); do
74 if ! file $FILE &>/dev/null; then
75 echo "$FILE is not found!"
76 FILES_MISSING="$FILE $FILES_MISSING"
77 fi
78 done
79 cd ..
80 if [ ! -z "$FILES_MISSING" ]; then
81 echo "Missing files in EXTRA_DIST: $FILES_MISSING"
82 exit 1
83 fi
84
85 # Do the regular dist-check for C++.
86 make distcheck -j2
87}
88
89build_csharp() {
90 # Just for the conformance tests. We don't currently
91 # need to really build protoc, but it's simplest to keep with the
92 # conventions of the other builds.
93 internal_build_cpp
94 NUGET=/usr/local/bin/nuget.exe
95
96 # Perform "dotnet new" once to get the setup preprocessing out of the
97 # way. That spews a lot of output (including backspaces) into logs
98 # otherwise, and can cause problems. It doesn't matter if this step
99 # is performed multiple times; it's cheap after the first time anyway.
100 # (It also doesn't matter if it's unnecessary, which it will be on some
101 # systems. It's necessary on Jenkins in order to avoid unprintable
102 # characters appearing in the JUnit output.)
103 mkdir dotnettmp
104 (cd dotnettmp; dotnet new > /dev/null)
105 rm -rf dotnettmp
106
107 csharp/buildall.sh
108 cd conformance && make test_csharp && cd ..
109
110 # Run csharp compatibility test between 3.0.0 and the current version.
111 csharp/compatibility_tests/v3.0.0/test.sh 3.0.0
112}
113
114build_golang() {
115 # Go build needs `protoc`.
116 internal_build_cpp
117 # Add protoc to the path so that the examples build finds it.
118 export PATH="`pwd`/src:$PATH"
119
120 # Install Go and the Go protobuf compiler plugin.
121 on_travis sudo apt-get update -qq
122 on_travis sudo apt-get install -qq golang
123
124 export GOPATH="$HOME/gocode"
125 mkdir -p "$GOPATH/src/github.com/google"
126 rm -f "$GOPATH/src/github.com/google/protobuf"
127 ln -s "`pwd`" "$GOPATH/src/github.com/google/protobuf"
128 export PATH="$GOPATH/bin:$PATH"
129 go get github.com/golang/protobuf/protoc-gen-go
130
131 cd examples && make gotest && cd ..
132}
133
134use_java() {
135 version=$1
136 case "$version" in
137 jdk7)
138 on_travis sudo apt-get install openjdk-7-jdk
139 export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
140 export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
141 ;;
142 oracle7)
143 if [ "$TRAVIS" == "true" ]; then
144 sudo apt-get install python-software-properties # for apt-add-repository
145 echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | \
146 sudo debconf-set-selections
147 yes | sudo apt-add-repository ppa:webupd8team/java
148 yes | sudo apt-get install oracle-java7-installer
149 fi;
150 export PATH=/usr/lib/jvm/java-7-oracle/bin:$PATH
151 export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
152 ;;
153 esac
154
155 if [ "$TRAVIS" != "true" ]; then
156 MAVEN_LOCAL_REPOSITORY=/var/maven_local_repository
157 MVN="$MVN -e -X --offline -Dmaven.repo.local=$MAVEN_LOCAL_REPOSITORY"
158 fi;
159
160 which java
161 java -version
162 $MVN -version
163}
164
165# --batch-mode supresses download progress output that spams the logs.
166MVN="mvn --batch-mode"
167
168build_java() {
169 version=$1
170 dir=java_$version
171 # Java build needs `protoc`.
172 internal_build_cpp
173 cp -r java $dir
174 cd $dir && $MVN clean && $MVN test
175 cd ../..
176}
177
178# The conformance tests are hard-coded to work with the $ROOT/java directory.
179# So this can't run in parallel with two different sets of tests.
180build_java_with_conformance_tests() {
181 # Java build needs `protoc`.
182 internal_build_cpp
183 cd java && $MVN test && $MVN install
184 cd util && $MVN package assembly:single
185 cd ../..
186 cd conformance && make test_java && cd ..
187}
188
189build_javanano() {
190 # Java build needs `protoc`.
191 internal_build_cpp
192 cd javanano && $MVN test && cd ..
193}
194
195build_java_jdk7() {
196 use_java jdk7
197 build_java_with_conformance_tests
198}
199build_java_oracle7() {
200 use_java oracle7
201 build_java oracle7
202}
203build_java_compatibility() {
204 use_java jdk7
205 internal_build_cpp
206 # Use the unit-tests extraced from 2.5.0 to test the compatibilty between
207 # 3.0.0-beta-4 and the current version.
208 cd java/compatibility_tests/v2.5.0
209 ./test.sh 3.0.0-beta-4
210}
211
212build_javanano_jdk7() {
213 use_java jdk7
214 build_javanano
215}
216build_javanano_oracle7() {
217 use_java oracle7
218 build_javanano
219}
220
221internal_install_python_deps() {
222 if [ "$TRAVIS" != "true" ]; then
223 return;
224 fi
225 # Install tox (OS X doesn't have pip).
226 if [ $(uname -s) == "Darwin" ]; then
227 sudo easy_install tox
228 else
229 sudo pip install tox
230 fi
231 # Only install Python2.6/3.x on Linux.
232 if [ $(uname -s) == "Linux" ]; then
233 sudo apt-get install -y python-software-properties # for apt-add-repository
234 sudo apt-add-repository -y ppa:fkrull/deadsnakes
235 sudo apt-get update -qq
236 sudo apt-get install -y python2.6 python2.6-dev
237 sudo apt-get install -y python3.3 python3.3-dev
238 sudo apt-get install -y python3.4 python3.4-dev
239 fi
240}
241
242build_objectivec_ios() {
243 # Reused the build script that takes care of configuring and ensuring things
244 # are up to date. The OS X test runs the objc conformance test, so skip it
245 # here.
246 # Note: travis has xctool installed, and we've looked at using it in the past
247 # but it has ended up proving unreliable (bugs), an they are removing build
248 # support in favor of xcbuild (or just xcodebuild).
249 objectivec/DevTools/full_mac_build.sh \
250 --core-only --skip-xcode-osx --skip-objc-conformance "$@"
251}
252
253build_objectivec_ios_debug() {
254 build_objectivec_ios --skip-xcode-release
255}
256
257build_objectivec_ios_release() {
258 build_objectivec_ios --skip-xcode-debug
259}
260
261build_objectivec_osx() {
262 # Reused the build script that takes care of configuring and ensuring things
263 # are up to date.
264 objectivec/DevTools/full_mac_build.sh \
265 --core-only --skip-xcode-ios
266}
267
268build_objectivec_cocoapods_integration() {
269 # Update pod to the latest version.
270 gem install cocoapods --no-ri --no-rdoc
271 objectivec/Tests/CocoaPods/run_tests.sh
272}
273
274build_python() {
275 internal_build_cpp
276 internal_install_python_deps
277 cd python
278 # Only test Python 2.6/3.x on Linux
279 if [ $(uname -s) == "Linux" ]; then
280 envlist=py\{26,27,33,34\}-python
281 else
282 envlist=py27-python
283 fi
284 tox -e $envlist
285 cd ..
286}
287
288build_python_cpp() {
289 internal_build_cpp
290 internal_install_python_deps
291 export LD_LIBRARY_PATH=../src/.libs # for Linux
292 export DYLD_LIBRARY_PATH=../src/.libs # for OS X
293 cd python
294 # Only test Python 2.6/3.x on Linux
295 if [ $(uname -s) == "Linux" ]; then
296 # py26 is currently disabled due to json_format
297 envlist=py\{27,33,34\}-cpp
298 else
299 envlist=py27-cpp
300 fi
301 tox -e $envlist
302 cd ..
303}
304
305build_python_compatibility() {
306 internal_build_cpp
307 # Use the unit-tests extraced from 2.5.0 to test the compatibilty.
308 cd python/compatibility_tests/v2.5.0
309 # Test between 2.5.0 and the current version.
310 ./test.sh 2.5.0
311 # Test between 3.0.0-beta-1 and the current version.
312 ./test.sh 3.0.0-beta-1
313}
314
315build_ruby21() {
316 internal_build_cpp # For conformance tests.
317 cd ruby && bash travis-test.sh ruby-2.1 && cd ..
318}
319build_ruby22() {
320 internal_build_cpp # For conformance tests.
321 cd ruby && bash travis-test.sh ruby-2.2 && cd ..
322}
323build_jruby() {
324 internal_build_cpp # For conformance tests.
325 # TODO(xiaofeng): Upgrade to jruby-9.x. There are some broken jests to be
326 # fixed.
327 cd ruby && bash travis-test.sh jruby-1.7 && cd ..
328}
329build_ruby_all() {
330 build_ruby21
331 build_ruby22
332 # TODO(teboring): Disable jruby test temperarily for it randomly fails.
333 # https://grpc-testing.appspot.com/job/protobuf_pull_request/735/consoleFull.
334 # build_jruby
335}
336
337build_javascript() {
338 internal_build_cpp
339 cd js && npm install && npm test && cd ..
340 cd conformance && make test_nodejs && cd ..
341}
342
343generate_php_test_proto() {
344 internal_build_cpp
345 pushd php/tests
346 # Generate test file
347 rm -rf generated
348 mkdir generated
349 ../../src/protoc --php_out=generated proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_service.proto proto/test_service_namespace.proto
350 pushd ../../src
351 ./protoc --php_out=../php/tests/generated google/protobuf/empty.proto
352 ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto
353 popd
354 popd
355}
356
357use_php() {
358 VERSION=$1
359 PHP=`which php`
360 PHP_CONFIG=`which php-config`
361 PHPIZE=`which phpize`
362 ln -sfn "/usr/local/php-${VERSION}/bin/php" $PHP
363 ln -sfn "/usr/local/php-${VERSION}/bin/php-config" $PHP_CONFIG
364 ln -sfn "/usr/local/php-${VERSION}/bin/phpize" $PHPIZE
365 generate_php_test_proto
366}
367
368use_php_zts() {
369 VERSION=$1
370 PHP=`which php`
371 PHP_CONFIG=`which php-config`
372 PHPIZE=`which phpize`
373 ln -sfn "/usr/local/php-${VERSION}-zts/bin/php" $PHP
374 ln -sfn "/usr/local/php-${VERSION}-zts/bin/php-config" $PHP_CONFIG
375 ln -sfn "/usr/local/php-${VERSION}-zts/bin/phpize" $PHPIZE
376 generate_php_test_proto
377}
378
379use_php_bc() {
380 VERSION=$1
381 PHP=`which php`
382 PHP_CONFIG=`which php-config`
383 PHPIZE=`which phpize`
384 ln -sfn "/usr/local/php-${VERSION}-bc/bin/php" $PHP
385 ln -sfn "/usr/local/php-${VERSION}-bc/bin/php-config" $PHP_CONFIG
386 ln -sfn "/usr/local/php-${VERSION}-bc/bin/phpize" $PHPIZE
387 generate_php_test_proto
388}
389
390build_php5.5() {
391 use_php 5.5
392
393 pushd php
394 rm -rf vendor
395 cp -r /usr/local/vendor-5.5 vendor
396 wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
397 phpunit
398 popd
399 pushd conformance
400 make test_php
401 popd
402}
403
404build_php5.5_c() {
405 use_php 5.5
406 wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
407 pushd php/tests
408 /bin/bash ./test.sh
409 popd
410 # TODO(teboring): Add it back
411 # pushd conformance
412 # make test_php_c
413 # popd
414}
415
416build_php5.5_zts_c() {
417 use_php_zts 5.5
418 wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
419 cd php/tests && /bin/bash ./test.sh && cd ../..
420 # TODO(teboring): Add it back
421 # pushd conformance
422 # make test_php_zts_c
423 # popd
424}
425
426build_php5.6() {
427 use_php 5.6
428 pushd php
429 rm -rf vendor
430 cp -r /usr/local/vendor-5.6 vendor
431 wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
432 phpunit
433 popd
434 pushd conformance
435 make test_php
436 popd
437}
438
439build_php5.6_c() {
440 use_php 5.6
441 wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
442 cd php/tests && /bin/bash ./test.sh && cd ../..
443 # TODO(teboring): Add it back
444 # pushd conformance
445 # make test_php_c
446 # popd
447}
448
449build_php5.6_zts_c() {
450 use_php_zts 5.6
451 wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
452 cd php/tests && /bin/bash ./test.sh && cd ../..
453 # TODO(teboring): Add it back
454 # pushd conformance
455 # make test_php_zts_c
456 # popd
457}
458
459build_php5.6_mac() {
460 generate_php_test_proto
461 # Install PHP
462 curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6
463 PHP_FOLDER=`find /usr/local -type d -name "php5-5.6*"` # The folder name may change upon time
464 export PATH="$PHP_FOLDER/bin:$PATH"
465
466 # Install phpunit
467 curl https://phar.phpunit.de/phpunit-5.6.10.phar -L -o phpunit.phar
468 chmod +x phpunit.phar
469 sudo mv phpunit.phar /usr/local/bin/phpunit
470
471 # Install valgrind
472 echo "#! /bin/bash" > valgrind
473 chmod ug+x valgrind
474 sudo mv valgrind /usr/local/bin/valgrind
475
476 # Test
477 cd php/tests && /bin/bash ./test.sh && cd ../..
478 # TODO(teboring): Add it back
479 # pushd conformance
480 # make test_php_c
481 # popd
482}
483
484build_php7.0() {
485 use_php 7.0
486 pushd php
487 rm -rf vendor
488 cp -r /usr/local/vendor-7.0 vendor
489 wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
490 phpunit
491 popd
492 pushd conformance
493 make test_php
494 popd
495}
496
497build_php7.0_c() {
498 use_php 7.0
499 wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
500 cd php/tests && /bin/bash ./test.sh && cd ../..
501 # TODO(teboring): Add it back
502 # pushd conformance
503 # make test_php_c
504 # popd
505}
506
507build_php7.0_zts_c() {
508 use_php_zts 7.0
509 wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
510 cd php/tests && /bin/bash ./test.sh && cd ../..
511 # TODO(teboring): Add it back.
512 # pushd conformance
513 # make test_php_zts_c
514 # popd
515}
516
517build_php7.0_mac() {
518 generate_php_test_proto
519 # Install PHP
520 curl -s https://php-osx.liip.ch/install.sh | bash -s 7.0
521 PHP_FOLDER=`find /usr/local -type d -name "php7-7.0*"` # The folder name may change upon time
522 export PATH="$PHP_FOLDER/bin:$PATH"
523
524 # Install phpunit
525 curl https://phar.phpunit.de/phpunit-5.6.0.phar -L -o phpunit.phar
526 chmod +x phpunit.phar
527 sudo mv phpunit.phar /usr/local/bin/phpunit
528
529 # Install valgrind
530 echo "#! /bin/bash" > valgrind
531 chmod ug+x valgrind
532 sudo mv valgrind /usr/local/bin/valgrind
533
534 # Test
535 cd php/tests && /bin/bash ./test.sh && cd ../..
536 # TODO(teboring): Add it back
537 # pushd conformance
538 # make test_php_c
539 # popd
540}
541
542build_php_compatibility() {
543 internal_build_cpp
544 php/tests/compatibility_test.sh
545}
546
547build_php7.1() {
548 use_php 7.1
549 pushd php
550 rm -rf vendor
551 cp -r /usr/local/vendor-7.1 vendor
552 wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
553 phpunit
554 popd
555 pushd conformance
556 # TODO(teboring): Add it back
557 # make test_php
558 popd
559}
560
561build_php7.1_c() {
562 use_php 7.1
563 wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
564 cd php/tests && /bin/bash ./test.sh && cd ../..
565 pushd conformance
566 # make test_php_c
567 popd
568}
569
570build_php7.1_zts_c() {
571 use_php_zts 7.1
572 wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
573 cd php/tests && /bin/bash ./test.sh && cd ../..
574 pushd conformance
575 # make test_php_c
576 popd
577}
578
579build_php_all_32() {
580 build_php5.5
581 build_php5.6
582 build_php7.0
583 build_php7.1
584 build_php5.5_c
585 build_php5.6_c
586 build_php7.0_c
587 build_php7.1_c
588 build_php5.5_zts_c
589 build_php5.6_zts_c
590 build_php7.0_zts_c
591 build_php7.1_zts_c
592}
593
594build_php_all() {
595 build_php_all_32
596 build_php_compatibility
597}
598
599# Note: travis currently does not support testing more than one language so the
600# .travis.yml cheats and claims to only be cpp. If they add multiple language
601# support, this should probably get updated to install steps and/or
602# rvm/gemfile/jdk/etc. entries rather than manually doing the work.
603
604# .travis.yml uses matrix.exclude to block the cases where app-get can't be
605# use to install things.
606
607# -------- main --------
608
609if [ "$#" -ne 1 ]; then
610 echo "
611Usage: $0 { cpp |
612 cpp_distcheck |
613 csharp |
614 java_jdk7 |
615 java_oracle7 |
616 java_compatibility |
617 javanano_jdk7 |
618 javanano_oracle7 |
619 objectivec_ios |
620 objectivec_ios_debug |
621 objectivec_ios_release |
622 objectivec_osx |
623 objectivec_cocoapods_integration |
624 python |
625 python_cpp |
626 python_compatibility |
627 ruby21 |
628 ruby22 |
629 jruby |
630 ruby_all |
631 php5.5 |
632 php5.5_c |
633 php5.6 |
634 php5.6_c |
635 php7.0 |
636 php7.0_c |
637 php_compatibility |
638 php7.1 |
639 php7.1_c |
640 php_all)
641"
642 exit 1
643fi
644
645set -e # exit immediately on error
646set -x # display all commands
647eval "build_$1"