• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2#
3# Build and runs tests for the protobuf project. We use this script to run
4# tests on kokoro (Ubuntu and MacOS). It can run locally as well but you
5# will need to make sure the required compilers/tools are available.
6
7# For when some other test needs the C++ main build, including protoc and
8# libprotobuf.
9internal_build_cpp() {
10  if [ -f src/protoc ]; then
11    # Already built.
12    return
13  fi
14
15  # Initialize any submodules.
16  git submodule update --init --recursive
17
18  ./autogen.sh
19  ./configure CXXFLAGS="-fPIC -std=c++11"  # -fPIC is needed for python cpp test.
20                                           # See python/setup.py for more details
21  make -j$(nproc)
22}
23
24build_cpp() {
25  internal_build_cpp
26  make check -j$(nproc) || (cat src/test-suite.log; false)
27  cd conformance && make test_cpp && cd ..
28
29  # The benchmark code depends on cmake, so test if it is installed before
30  # trying to do the build.
31  if [[ $(type cmake 2>/dev/null) ]]; then
32    # Verify benchmarking code can build successfully.
33    cd benchmarks && make cpp-benchmark && cd ..
34  else
35    echo ""
36    echo "WARNING: Skipping validation of the bench marking code, cmake isn't installed."
37    echo ""
38  fi
39}
40
41build_cpp_tcmalloc() {
42  internal_build_cpp
43  ./configure LIBS=-ltcmalloc && make clean && make \
44      PTHREAD_CFLAGS='-pthread -DGOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN' \
45      check
46  cd src
47  PPROF_PATH=/usr/bin/google-pprof HEAPCHECK=strict ./protobuf-test
48}
49
50build_cpp_distcheck() {
51  grep -q -- "-Og" src/Makefile.am &&
52    echo "The -Og flag is incompatible with Clang versions older than 4.0." &&
53    exit 1
54
55  # Initialize any submodules.
56  git submodule update --init --recursive
57  ./autogen.sh
58  ./configure
59  make dist
60
61  # List all files that should be included in the distribution package.
62  git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\|src/google/protobuf/.*\.proto\)" |\
63    grep -v ".gitignore" | grep -v "java/compatibility_tests" |\
64    grep -v "python/compatibility_tests" | grep -v "csharp/compatibility_tests" > dist.lst
65  # Unzip the dist tar file.
66  DIST=`ls *.tar.gz`
67  tar -xf $DIST
68  cd ${DIST//.tar.gz}
69  # Check if every file exists in the dist tar file.
70  FILES_MISSING=""
71  for FILE in $(<../dist.lst); do
72    [ -f "$FILE" ] || {
73      echo "$FILE is not found!"
74      FILES_MISSING="$FILE $FILES_MISSING"
75    }
76  done
77  cd ..
78  if [ ! -z "$FILES_MISSING" ]; then
79    echo "Missing files in EXTRA_DIST: $FILES_MISSING"
80    exit 1
81  fi
82
83  # Do the regular dist-check for C++.
84  make distcheck -j$(nproc)
85}
86
87build_dist_install() {
88  # Initialize any submodules.
89  git submodule update --init --recursive
90  ./autogen.sh
91  ./configure
92  make dist
93
94  # Unzip the dist tar file and install it.
95  DIST=`ls *.tar.gz`
96  tar -xf $DIST
97  pushd ${DIST//.tar.gz}
98  ./configure && make check -j4 && make install
99
100  export LD_LIBRARY_PATH=/usr/local/lib
101
102  # Try to install Java
103  pushd java
104  use_java jdk7
105  $MVN install
106  popd
107
108  # Try to install Python
109  virtualenv --no-site-packages venv
110  source venv/bin/activate
111  pushd python
112  python setup.py clean build sdist
113  pip install dist/protobuf-*.tar.gz
114  popd
115  deactivate
116  rm -rf python/venv
117}
118
119build_csharp() {
120  # Required for conformance tests and to regenerate protos.
121  internal_build_cpp
122  NUGET=/usr/local/bin/nuget.exe
123
124  # Disable some unwanted dotnet options
125  export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
126  export DOTNET_CLI_TELEMETRY_OPTOUT=true
127
128  # TODO(jtattermusch): is this still needed with "first time experience"
129  # disabled?
130  # Perform "dotnet new" once to get the setup preprocessing out of the
131  # way. That spews a lot of output (including backspaces) into logs
132  # otherwise, and can cause problems. It doesn't matter if this step
133  # is performed multiple times; it's cheap after the first time anyway.
134  # (It also doesn't matter if it's unnecessary, which it will be on some
135  # systems. It's necessary on Jenkins in order to avoid unprintable
136  # characters appearing in the JUnit output.)
137  mkdir dotnettmp
138  (cd dotnettmp; dotnet new > /dev/null)
139  rm -rf dotnettmp
140
141  # Check that the protos haven't broken C# codegen.
142  # TODO(jonskeet): Fail if regenerating creates any changes.
143  csharp/generate_protos.sh
144
145  csharp/buildall.sh
146  cd conformance && make test_csharp && cd ..
147
148  # Run csharp compatibility test between 3.0.0 and the current version.
149  csharp/compatibility_tests/v3.0.0/test.sh 3.0.0
150}
151
152build_golang() {
153  # Go build needs `protoc`.
154  internal_build_cpp
155  # Add protoc to the path so that the examples build finds it.
156  export PATH="`pwd`/src:$PATH"
157
158  export GOPATH="$HOME/gocode"
159  mkdir -p "$GOPATH/src/github.com/protocolbuffers"
160  rm -f "$GOPATH/src/github.com/protocolbuffers/protobuf"
161  ln -s "`pwd`" "$GOPATH/src/github.com/protocolbuffers/protobuf"
162  export PATH="$GOPATH/bin:$PATH"
163  go get github.com/golang/protobuf/protoc-gen-go
164
165  cd examples && PROTO_PATH="-I../src -I." make gotest && cd ..
166}
167
168use_java() {
169  version=$1
170  case "$version" in
171    jdk7)
172      export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
173      export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
174      ;;
175    oracle7)
176      export PATH=/usr/lib/jvm/java-7-oracle/bin:$PATH
177      export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
178      ;;
179  esac
180
181  MAVEN_LOCAL_REPOSITORY=/var/maven_local_repository
182  MVN="$MVN -e -X -Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$MAVEN_LOCAL_REPOSITORY"
183
184  which java
185  java -version
186  $MVN -version
187}
188
189# --batch-mode supresses download progress output that spams the logs.
190MVN="mvn --batch-mode"
191
192build_java() {
193  version=$1
194  dir=java_$version
195  # Java build needs `protoc`.
196  internal_build_cpp
197  cp -r java $dir
198  cd $dir && $MVN clean && $MVN test
199  cd ../..
200}
201
202# The conformance tests are hard-coded to work with the $ROOT/java directory.
203# So this can't run in parallel with two different sets of tests.
204build_java_with_conformance_tests() {
205  # Java build needs `protoc`.
206  internal_build_cpp
207  cd java && $MVN test && $MVN install
208  cd util && $MVN package assembly:single
209  cd ../..
210  cd conformance && make test_java && cd ..
211}
212
213build_java_jdk7() {
214  use_java jdk7
215  build_java_with_conformance_tests
216}
217build_java_oracle7() {
218  use_java oracle7
219  build_java oracle7
220}
221build_java_compatibility() {
222  use_java jdk7
223  internal_build_cpp
224  # Use the unit-tests extraced from 2.5.0 to test the compatibilty between
225  # 3.0.0-beta-4 and the current version.
226  cd java/compatibility_tests/v2.5.0
227  ./test.sh 3.0.0-beta-4
228}
229
230build_objectivec_ios() {
231  # Reused the build script that takes care of configuring and ensuring things
232  # are up to date.  The OS X test runs the objc conformance test, so skip it
233  # here.
234  objectivec/DevTools/full_mac_build.sh \
235      --core-only --skip-xcode-osx --skip-xcode-tvos --skip-objc-conformance "$@"
236}
237
238build_objectivec_ios_debug() {
239  build_objectivec_ios --skip-xcode-release
240}
241
242build_objectivec_ios_release() {
243  build_objectivec_ios --skip-xcode-debug
244}
245
246build_objectivec_osx() {
247  # Reused the build script that takes care of configuring and ensuring things
248  # are up to date.
249  objectivec/DevTools/full_mac_build.sh \
250      --core-only --skip-xcode-ios --skip-xcode-tvos
251}
252
253build_objectivec_tvos() {
254  # Reused the build script that takes care of configuring and ensuring things
255  # are up to date.  The OS X test runs the objc conformance test, so skip it
256  # here.
257  objectivec/DevTools/full_mac_build.sh \
258      --core-only --skip-xcode-ios --skip-xcode-osx --skip-objc-conformance "$@"
259}
260
261build_objectivec_tvos_debug() {
262  build_objectivec_tvos --skip-xcode-release
263}
264
265build_objectivec_tvos_release() {
266  build_objectivec_tvos --skip-xcode-debug
267}
268
269build_objectivec_cocoapods_integration() {
270  # Update pod to the latest version.
271  gem install cocoapods --no_document
272  objectivec/Tests/CocoaPods/run_tests.sh
273}
274
275build_python() {
276  internal_build_cpp
277  cd python
278  if [ $(uname -s) == "Linux" ]; then
279    envlist=py\{27,33,34,35,36\}-python
280  else
281    envlist=py27-python
282  fi
283  tox -e $envlist
284  cd ..
285}
286
287build_python_version() {
288  internal_build_cpp
289  cd python
290  envlist=$1
291  tox -e $envlist
292  cd ..
293}
294
295build_python27() {
296  build_python_version py27-python
297}
298
299build_python33() {
300  build_python_version py33-python
301}
302
303build_python34() {
304  build_python_version py34-python
305}
306
307build_python35() {
308  build_python_version py35-python
309}
310
311build_python36() {
312  build_python_version py36-python
313}
314
315build_python37() {
316  build_python_version py37-python
317}
318
319build_python_cpp() {
320  internal_build_cpp
321  export LD_LIBRARY_PATH=../src/.libs # for Linux
322  export DYLD_LIBRARY_PATH=../src/.libs # for OS X
323  cd python
324  if [ $(uname -s) == "Linux" ]; then
325    envlist=py\{27,33,34,35,36\}-cpp
326  else
327    envlist=py27-cpp
328  fi
329  tox -e $envlist
330  cd ..
331}
332
333build_python_cpp_version() {
334  internal_build_cpp
335  export LD_LIBRARY_PATH=../src/.libs # for Linux
336  export DYLD_LIBRARY_PATH=../src/.libs # for OS X
337  cd python
338  envlist=$1
339  tox -e $envlist
340  cd ..
341}
342
343build_python27_cpp() {
344  build_python_cpp_version py27-cpp
345}
346
347build_python33_cpp() {
348  build_python_cpp_version py33-cpp
349}
350
351build_python34_cpp() {
352  build_python_cpp_version py34-cpp
353}
354
355build_python35_cpp() {
356  build_python_cpp_version py35-cpp
357}
358
359build_python36_cpp() {
360  build_python_cpp_version py36-cpp
361}
362
363build_python37_cpp() {
364  build_python_cpp_version py37-cpp
365}
366
367build_python_compatibility() {
368  internal_build_cpp
369  # Use the unit-tests extraced from 2.5.0 to test the compatibilty.
370  cd python/compatibility_tests/v2.5.0
371  # Test between 2.5.0 and the current version.
372  ./test.sh 2.5.0
373  # Test between 3.0.0-beta-1 and the current version.
374  ./test.sh 3.0.0-beta-1
375}
376
377build_ruby23() {
378  internal_build_cpp  # For conformance tests.
379  cd ruby && bash travis-test.sh ruby-2.3.8 && cd ..
380}
381build_ruby24() {
382  internal_build_cpp  # For conformance tests.
383  cd ruby && bash travis-test.sh ruby-2.4 && cd ..
384}
385build_ruby25() {
386  internal_build_cpp  # For conformance tests.
387  cd ruby && bash travis-test.sh ruby-2.5.1 && cd ..
388}
389build_ruby26() {
390  internal_build_cpp  # For conformance tests.
391  cd ruby && bash travis-test.sh ruby-2.6.0 && cd ..
392}
393
394build_javascript() {
395  internal_build_cpp
396  cd js && npm install && npm test && cd ..
397  cd conformance && make test_nodejs && cd ..
398}
399
400generate_php_test_proto() {
401  internal_build_cpp
402  pushd php/tests
403  # Generate test file
404  rm -rf generated
405  mkdir generated
406  ../../src/protoc --php_out=generated         \
407    -I../../src -I.                            \
408    proto/empty/echo.proto                     \
409    proto/test.proto                           \
410    proto/test_include.proto                   \
411    proto/test_no_namespace.proto              \
412    proto/test_prefix.proto                    \
413    proto/test_php_namespace.proto             \
414    proto/test_empty_php_namespace.proto       \
415    proto/test_reserved_enum_lower.proto       \
416    proto/test_reserved_enum_upper.proto       \
417    proto/test_reserved_enum_value_lower.proto \
418    proto/test_reserved_enum_value_upper.proto \
419    proto/test_reserved_message_lower.proto    \
420    proto/test_reserved_message_upper.proto    \
421    proto/test_service.proto                   \
422    proto/test_service_namespace.proto         \
423    proto/test_wrapper_type_setters.proto      \
424    proto/test_descriptors.proto
425  pushd ../../src
426  ./protoc --php_out=../php/tests/generated -I../php/tests -I. \
427    ../php/tests/proto/test_import_descriptor_proto.proto
428  popd
429  popd
430}
431
432use_php() {
433  VERSION=$1
434  export PATH=/usr/local/php-${VERSION}/bin:$PATH
435  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$CPLUS_INCLUDE_PATH
436  export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$C_INCLUDE_PATH
437  generate_php_test_proto
438}
439
440use_php_zts() {
441  VERSION=$1
442  export PATH=/usr/local/php-${VERSION}-zts/bin:$PATH
443  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$CPLUS_INCLUDE_PATH
444  export C_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$C_INCLUDE_PATH
445  generate_php_test_proto
446}
447
448use_php_bc() {
449  VERSION=$1
450  export PATH=/usr/local/php-${VERSION}-bc/bin:$PATH
451  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$CPLUS_INCLUDE_PATH
452  export C_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$C_INCLUDE_PATH
453  generate_php_test_proto
454}
455
456build_php5.5() {
457  use_php 5.5
458
459  pushd php
460  rm -rf vendor
461  composer update
462  ./vendor/bin/phpunit
463  popd
464  pushd conformance
465  make test_php
466  popd
467}
468
469build_php5.5_c() {
470  use_php 5.5
471  pushd php/tests
472  /bin/bash ./test.sh 5.5
473  popd
474  # TODO(teboring): Add it back
475  # pushd conformance
476  # make test_php_c
477  # popd
478}
479
480build_php5.5_mixed() {
481  use_php 5.5
482  pushd php
483  rm -rf vendor
484  composer update
485  /bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
486  php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
487  popd
488}
489
490build_php5.5_zts_c() {
491  use_php_zts 5.5
492  cd php/tests && /bin/bash ./test.sh 5.5-zts && cd ../..
493  # TODO(teboring): Add it back
494  # pushd conformance
495  # make test_php_zts_c
496  # popd
497}
498
499build_php5.6() {
500  use_php 5.6
501  pushd php
502  rm -rf vendor
503  composer update
504  ./vendor/bin/phpunit
505  popd
506  pushd conformance
507  make test_php
508  popd
509}
510
511build_php5.6_c() {
512  use_php 5.6
513  cd php/tests && /bin/bash ./test.sh 5.6 && cd ../..
514  # TODO(teboring): Add it back
515  # pushd conformance
516  # make test_php_c
517  # popd
518}
519
520build_php5.6_mixed() {
521  use_php 5.6
522  pushd php
523  rm -rf vendor
524  composer update
525  /bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
526  php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
527  popd
528}
529
530build_php5.6_zts_c() {
531  use_php_zts 5.6
532  cd php/tests && /bin/bash ./test.sh 5.6-zts && cd ../..
533  # TODO(teboring): Add it back
534  # pushd conformance
535  # make test_php_zts_c
536  # popd
537}
538
539build_php5.6_mac() {
540  generate_php_test_proto
541  # Install PHP
542  curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6
543  PHP_FOLDER=`find /usr/local -type d -name "php5-5.6*"`  # The folder name may change upon time
544  export PATH="$PHP_FOLDER/bin:$PATH"
545
546  # Install phpunit
547  curl https://phar.phpunit.de/phpunit-5.6.8.phar -L -o phpunit.phar
548  chmod +x phpunit.phar
549  sudo mv phpunit.phar /usr/local/bin/phpunit
550
551  # Install valgrind
552  echo "#! /bin/bash" > valgrind
553  chmod ug+x valgrind
554  sudo mv valgrind /usr/local/bin/valgrind
555
556  # Test
557  cd php/tests && /bin/bash ./test.sh && cd ../..
558  # TODO(teboring): Add it back
559  # pushd conformance
560  # make test_php_c
561  # popd
562}
563
564build_php7.0() {
565  use_php 7.0
566  pushd php
567  rm -rf vendor
568  composer update
569  ./vendor/bin/phpunit
570  popd
571  pushd conformance
572  make test_php
573  popd
574}
575
576build_php7.0_c() {
577  use_php 7.0
578  cd php/tests && /bin/bash ./test.sh 7.0 && cd ../..
579  # TODO(teboring): Add it back
580  # pushd conformance
581  # make test_php_c
582  # popd
583}
584
585build_php7.0_mixed() {
586  use_php 7.0
587  pushd php
588  rm -rf vendor
589  composer update
590  /bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
591  php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
592  popd
593}
594
595build_php7.0_zts_c() {
596  use_php_zts 7.0
597  cd php/tests && /bin/bash ./test.sh 7.0-zts && cd ../..
598  # TODO(teboring): Add it back.
599  # pushd conformance
600  # make test_php_zts_c
601  # popd
602}
603
604build_php7.0_mac() {
605  generate_php_test_proto
606  # Install PHP
607  curl -s https://php-osx.liip.ch/install.sh | bash -s 7.0
608  PHP_FOLDER=`find /usr/local -type d -name "php7-7.0*"`  # The folder name may change upon time
609  export PATH="$PHP_FOLDER/bin:$PATH"
610
611  # Install phpunit
612  curl https://phar.phpunit.de/phpunit-5.6.0.phar -L -o phpunit.phar
613  chmod +x phpunit.phar
614  sudo mv phpunit.phar /usr/local/bin/phpunit
615
616  # Install valgrind
617  echo "#! /bin/bash" > valgrind
618  chmod ug+x valgrind
619  sudo mv valgrind /usr/local/bin/valgrind
620
621  # Test
622  cd php/tests && /bin/bash ./test.sh && cd ../..
623  # TODO(teboring): Add it back
624  # pushd conformance
625  # make test_php_c
626  # popd
627}
628
629build_php_compatibility() {
630  internal_build_cpp
631  php/tests/compatibility_test.sh
632}
633
634build_php7.1() {
635  use_php 7.1
636  pushd php
637  rm -rf vendor
638  composer update
639  ./vendor/bin/phpunit
640  popd
641  pushd conformance
642  make test_php
643  popd
644}
645
646build_php7.1_c() {
647  ENABLE_CONFORMANCE_TEST=$1
648  use_php 7.1
649  cd php/tests && /bin/bash ./test.sh 7.1 && cd ../..
650  if [ "$ENABLE_CONFORMANCE_TEST" = "true" ]
651  then
652    pushd conformance
653    make test_php_c
654    popd
655  fi
656}
657
658build_php7.1_mixed() {
659  use_php 7.1
660  pushd php
661  rm -rf vendor
662  composer update
663  /bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
664  php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
665  popd
666}
667
668build_php7.1_zts_c() {
669  use_php_zts 7.1
670  cd php/tests && /bin/bash ./test.sh 7.1-zts && cd ../..
671  pushd conformance
672  # make test_php_c
673  popd
674}
675
676build_php_all_32() {
677  build_php5.5
678  build_php5.6
679  build_php7.0
680  build_php7.1
681  build_php5.5_c
682  build_php5.6_c
683  build_php7.0_c
684  build_php7.1_c $1
685  build_php5.5_mixed
686  build_php5.6_mixed
687  build_php7.0_mixed
688  build_php7.1_mixed
689  build_php5.5_zts_c
690  build_php5.6_zts_c
691  build_php7.0_zts_c
692  build_php7.1_zts_c
693}
694
695build_php_all() {
696  build_php_all_32 true
697  build_php_compatibility
698}
699
700build_benchmark() {
701  use_php 7.2
702  cd kokoro/linux/benchmark && ./run.sh
703}
704
705# -------- main --------
706
707if [ "$#" -ne 1 ]; then
708  echo "
709Usage: $0 { cpp |
710            cpp_distcheck |
711            csharp |
712            java_jdk7 |
713            java_oracle7 |
714            java_compatibility |
715            objectivec_ios |
716            objectivec_ios_debug |
717            objectivec_ios_release |
718            objectivec_osx |
719            objectivec_tvos |
720            objectivec_tvos_debug |
721            objectivec_tvos_release |
722            objectivec_cocoapods_integration |
723            python |
724            python_cpp |
725            python_compatibility |
726            ruby23 |
727            ruby24 |
728            ruby25 |
729            ruby26 |
730            jruby |
731            ruby_all |
732            php5.5   |
733            php5.5_c |
734            php5.6   |
735            php5.6_c |
736            php7.0   |
737            php7.0_c |
738            php_compatibility |
739            php7.1   |
740            php7.1_c |
741            php_all |
742            dist_install |
743            benchmark)
744"
745  exit 1
746fi
747
748set -e  # exit immediately on error
749set -x  # display all commands
750cd $(dirname $0)
751eval "build_$1"
752