• 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.
9LAST_RELEASED=3.9.0
10
11internal_build_cpp() {
12  if [ -f src/protoc ]; then
13    # Already built.
14    return
15  fi
16
17  # Initialize any submodules.
18  git submodule update --init --recursive
19
20  ./autogen.sh
21  ./configure CXXFLAGS="-fPIC -std=c++11"  # -fPIC is needed for python cpp test.
22                                           # See python/setup.py for more details
23  make -j$(nproc)
24}
25
26build_cpp() {
27  internal_build_cpp
28  make check -j$(nproc) || (cat src/test-suite.log; false)
29  cd conformance && make test_cpp && cd ..
30}
31
32build_cpp_tcmalloc() {
33  internal_build_cpp
34  ./configure LIBS=-ltcmalloc && make clean && make \
35      PTHREAD_CFLAGS='-pthread -DGOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN' \
36      check
37  cd src
38  PPROF_PATH=/usr/bin/google-pprof HEAPCHECK=strict ./protobuf-test
39}
40
41build_cpp_distcheck() {
42  grep -q -- "-Og" src/Makefile.am &&
43    echo "The -Og flag is incompatible with Clang versions older than 4.0." &&
44    exit 1
45
46  # Initialize any submodules.
47  git submodule update --init --recursive
48  ./autogen.sh
49  ./configure
50  make dist
51
52  # List all files that should be included in the distribution package.
53  git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\|src/google/protobuf/.*\.proto\)" |\
54    grep -v ".gitignore" | grep -v "java/lite/proguard.pgcfg" |\
55    grep -v "python/compatibility_tests" | grep -v "python/docs" | grep -v "python/.repo-metadata.json" |\
56    grep -v "python/protobuf_distutils" | grep -v "csharp/compatibility_tests" > dist.lst
57  # Unzip the dist tar file.
58  DIST=`ls *.tar.gz`
59  tar -xf $DIST
60  cd ${DIST//.tar.gz}
61  # Check if every file exists in the dist tar file.
62  FILES_MISSING=""
63  for FILE in $(<../dist.lst); do
64    [ -f "$FILE" ] || {
65      echo "$FILE is not found!"
66      FILES_MISSING="$FILE $FILES_MISSING"
67    }
68  done
69  cd ..
70  if [ ! -z "$FILES_MISSING" ]; then
71    echo "Missing files in EXTRA_DIST: $FILES_MISSING"
72    exit 1
73  fi
74
75  # Do the regular dist-check for C++.
76  make distcheck -j$(nproc)
77}
78
79build_dist_install() {
80  # Create a symlink pointing to python2 and put it at the beginning of $PATH.
81  # This is necessary because the googletest build system involves a Python
82  # script that is not compatible with Python 3. More recent googletest
83  # versions have fixed this, but they have also removed the autotools build
84  # system support that we rely on. This is a temporary workaround to keep the
85  # googletest build working when the default python binary is Python 3.
86  mkdir tmp || true
87  pushd tmp
88  ln -s /usr/bin/python2 ./python
89  popd
90  PATH=$PWD/tmp:$PATH
91
92  # Initialize any submodules.
93  git submodule update --init --recursive
94  ./autogen.sh
95  ./configure
96  make dist
97
98  # Unzip the dist tar file and install it.
99  DIST=`ls *.tar.gz`
100  tar -xf $DIST
101  pushd ${DIST//.tar.gz}
102  ./configure && make check -j4 && make install
103
104  export LD_LIBRARY_PATH=/usr/local/lib
105
106  # Try to install Java
107  pushd java
108  use_java jdk11
109  $MVN install
110  popd
111
112  # Try to install Python
113  python3 -m venv venv
114  source venv/bin/activate
115  pushd python
116  python3 setup.py clean build sdist
117  pip3 install dist/protobuf-*.tar.gz
118  popd
119  deactivate
120  rm -rf python/venv
121}
122
123build_csharp() {
124  # Required for conformance tests and to regenerate protos.
125  internal_build_cpp
126  NUGET=/usr/local/bin/nuget.exe
127
128  # Disable some unwanted dotnet options
129  export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
130  export DOTNET_CLI_TELEMETRY_OPTOUT=true
131
132  # TODO(jtattermusch): is this still needed with "first time experience"
133  # disabled?
134  # Perform "dotnet new" once to get the setup preprocessing out of the
135  # way. That spews a lot of output (including backspaces) into logs
136  # otherwise, and can cause problems. It doesn't matter if this step
137  # is performed multiple times; it's cheap after the first time anyway.
138  # (It also doesn't matter if it's unnecessary, which it will be on some
139  # systems. It's necessary on Jenkins in order to avoid unprintable
140  # characters appearing in the JUnit output.)
141  mkdir dotnettmp
142  (cd dotnettmp; dotnet new > /dev/null)
143  rm -rf dotnettmp
144
145  # Check that the protos haven't broken C# codegen.
146  # TODO(jonskeet): Fail if regenerating creates any changes.
147  csharp/generate_protos.sh
148
149  csharp/buildall.sh
150  cd conformance && make test_csharp && cd ..
151
152  # Run csharp compatibility test between 3.0.0 and the current version.
153  csharp/compatibility_tests/v3.0.0/test.sh 3.0.0
154
155  # Run csharp compatibility test between last released and the current version.
156  csharp/compatibility_tests/v3.0.0/test.sh $LAST_RELEASED
157}
158
159build_golang() {
160  # Go build needs `protoc`.
161  internal_build_cpp
162  # Add protoc to the path so that the examples build finds it.
163  export PATH="`pwd`/src:$PATH"
164
165  export GOPATH="$HOME/gocode"
166  mkdir -p "$GOPATH/src/github.com/protocolbuffers"
167  mkdir -p "$GOPATH/src/github.com/golang"
168  rm -f "$GOPATH/src/github.com/protocolbuffers/protobuf"
169  rm -f "$GOPATH/src/github.com/golang/protobuf"
170  ln -s "`pwd`" "$GOPATH/src/github.com/protocolbuffers/protobuf"
171  export PATH="$GOPATH/bin:$PATH"
172  (cd $GOPATH/src/github.com/golang && git clone https://github.com/golang/protobuf.git && cd protobuf && git checkout v1.3.5)
173  go install github.com/golang/protobuf/protoc-gen-go
174
175  cd examples && PROTO_PATH="-I../src -I." make gotest && cd ..
176}
177
178use_java() {
179  version=$1
180  case "$version" in
181    jdk11)
182      export PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH
183      export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
184      ;;
185    jdk8)
186      export PATH=/usr/lib/jvm/java-8-openjdk-amd64/bin:$PATH
187      export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
188      ;;
189    jdk7)
190      export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
191      export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
192      ;;
193    oracle7)
194      export PATH=/usr/lib/jvm/java-7-oracle/bin:$PATH
195      export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
196      ;;
197  esac
198
199  MAVEN_LOCAL_REPOSITORY=/var/maven_local_repository
200  MVN="$MVN -e --quiet -Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$MAVEN_LOCAL_REPOSITORY"
201
202  which java
203  java -version
204  $MVN -version
205}
206
207# --batch-mode suppresses download progress output that spams the logs.
208MVN="mvn --batch-mode"
209
210internal_build_java() {
211  version=$1
212  dir=java_$version
213  # Java build needs `protoc`.
214  internal_build_cpp
215  cp -r java $dir
216  cd $dir && $MVN clean
217  # Skip tests here - callers will decide what tests they want to run
218  $MVN install -Dmaven.test.skip=true
219}
220
221build_java() {
222  version=$1
223  internal_build_java $version
224  # Skip the Kotlin tests on Oracle 7
225  if [ "$version" == "oracle7" ]; then
226    $MVN test -pl bom,lite,core,util
227  else
228    $MVN test
229  fi
230  cd ../..
231}
232
233# The conformance tests are hard-coded to work with the $ROOT/java directory.
234# So this can't run in parallel with two different sets of tests.
235build_java_with_conformance_tests() {
236  # Java build needs `protoc`.
237  internal_build_cpp
238  # This local installation avoids the problem caused by a new version not yet in Maven Central
239  cd java/bom && $MVN install
240  cd ../..
241  cd java/core && $MVN test && $MVN install
242  cd ../lite && $MVN test && $MVN install
243  cd ../util && $MVN test && $MVN install && $MVN package assembly:single
244  if [ "$version" == "jdk8" ]; then
245    cd ../kotlin && $MVN test && $MVN install
246    cd ../kotlin-lite && $MVN test && $MVN install
247  fi
248  cd ../..
249  cd conformance && make test_java && cd ..
250}
251
252build_java_jdk7() {
253  use_java jdk7
254  build_java_with_conformance_tests
255}
256build_java_oracle7() {
257  use_java oracle7
258  build_java oracle7
259}
260build_java_linkage_monitor() {
261  # Linkage Monitor checks compatibility with other Google libraries
262  # https://github.com/GoogleCloudPlatform/cloud-opensource-java/tree/master/linkage-monitor
263
264  use_java jdk11
265  internal_build_cpp
266
267  # Linkage Monitor uses $HOME/.m2 local repository
268  MVN="mvn -e -B -Dhttps.protocols=TLSv1.2"
269  cd java
270  # Installs the snapshot version locally
271  $MVN install -Dmaven.test.skip=true
272
273  # Linkage Monitor uses the snapshot versions installed in $HOME/.m2 to verify compatibility
274  JAR=linkage-monitor-latest-all-deps.jar
275  curl -v -O "https://storage.googleapis.com/cloud-opensource-java-linkage-monitor/${JAR}"
276  # Fails if there's new linkage errors compared with baseline
277  java -jar $JAR com.google.cloud:libraries-bom
278}
279
280build_objectivec_ios() {
281  # Reused the build script that takes care of configuring and ensuring things
282  # are up to date.  The OS X test runs the objc conformance test, so skip it
283  # here.
284  objectivec/DevTools/full_mac_build.sh \
285      --core-only --skip-xcode-osx --skip-xcode-tvos --skip-objc-conformance "$@"
286}
287
288build_objectivec_ios_debug() {
289  build_objectivec_ios --skip-xcode-release
290}
291
292build_objectivec_ios_release() {
293  build_objectivec_ios --skip-xcode-debug
294}
295
296build_objectivec_osx() {
297  # Reused the build script that takes care of configuring and ensuring things
298  # are up to date.
299  objectivec/DevTools/full_mac_build.sh \
300      --core-only --skip-xcode-ios --skip-xcode-tvos
301}
302
303build_objectivec_tvos() {
304  # Reused the build script that takes care of configuring and ensuring things
305  # are up to date.  The OS X test runs the objc conformance test, so skip it
306  # here.
307  objectivec/DevTools/full_mac_build.sh \
308      --core-only --skip-xcode-ios --skip-xcode-osx --skip-objc-conformance "$@"
309}
310
311build_objectivec_tvos_debug() {
312  build_objectivec_tvos --skip-xcode-release
313}
314
315build_objectivec_tvos_release() {
316  build_objectivec_tvos --skip-xcode-debug
317}
318
319build_objectivec_cocoapods_integration() {
320  objectivec/Tests/CocoaPods/run_tests.sh
321}
322
323build_python() {
324  internal_build_cpp
325  cd python
326  tox --skip-missing-interpreters
327  cd ..
328}
329
330build_python_version() {
331  internal_build_cpp
332  cd python
333  envlist=$1
334  tox -e $envlist
335  cd ..
336}
337
338build_python37() {
339  build_python_version py37-python
340}
341
342build_python38() {
343  build_python_version py38-python
344}
345
346build_python39() {
347  build_python_version py39-python
348}
349
350build_python310() {
351  build_python_version py310-python
352}
353
354build_python_cpp() {
355  internal_build_cpp
356  export LD_LIBRARY_PATH=../src/.libs # for Linux
357  export DYLD_LIBRARY_PATH=../src/.libs # for OS X
358  cd python
359  tox --skip-missing-interpreters
360  cd ..
361}
362
363build_python_cpp_version() {
364  internal_build_cpp
365  export LD_LIBRARY_PATH=../src/.libs # for Linux
366  export DYLD_LIBRARY_PATH=../src/.libs # for OS X
367  cd python
368  envlist=$1
369  tox -e $envlist
370  cd ..
371}
372
373build_python37_cpp() {
374  build_python_cpp_version py37-cpp
375}
376
377build_python38_cpp() {
378  build_python_cpp_version py38-cpp
379}
380
381build_python39_cpp() {
382  build_python_cpp_version py39-cpp
383}
384
385build_python310_cpp() {
386  build_python_cpp_version py310-cpp
387}
388
389
390build_ruby23() {
391  internal_build_cpp  # For conformance tests.
392  cd ruby && bash travis-test.sh ruby-2.3.8 && cd ..
393}
394build_ruby24() {
395  internal_build_cpp  # For conformance tests.
396  cd ruby && bash travis-test.sh ruby-2.4 && cd ..
397}
398build_ruby25() {
399  internal_build_cpp  # For conformance tests.
400  cd ruby && bash travis-test.sh ruby-2.5.1 && cd ..
401}
402build_ruby26() {
403  internal_build_cpp  # For conformance tests.
404  cd ruby && bash travis-test.sh ruby-2.6.0 && cd ..
405}
406build_ruby27() {
407  internal_build_cpp  # For conformance tests.
408  cd ruby && bash travis-test.sh ruby-2.7.0 && cd ..
409}
410build_ruby30() {
411  internal_build_cpp  # For conformance tests.
412  cd ruby && bash travis-test.sh ruby-3.0.2 && cd ..
413}
414build_ruby31() {
415  internal_build_cpp  # For conformance tests.
416  cd ruby && bash travis-test.sh ruby-3.1.0 && cd ..
417}
418
419build_jruby92() {
420  internal_build_cpp                # For conformance tests.
421  internal_build_java jdk8 && cd .. # For Maven protobuf jar with local changes
422  cd ruby && bash travis-test.sh jruby-9.2.20.1 && cd ..
423}
424
425build_jruby93() {
426  internal_build_cpp                # For conformance tests.
427  internal_build_java jdk8 && cd .. # For Maven protobuf jar with local changes
428  cd ruby && bash travis-test.sh jruby-9.3.3.0 && cd ..
429}
430
431build_javascript() {
432  internal_build_cpp
433  NODE_VERSION=node-v12.16.3-darwin-x64
434  NODE_TGZ="$NODE_VERSION.tar.gz"
435  pushd /tmp
436  curl -OL https://nodejs.org/dist/v12.16.3/$NODE_TGZ
437  tar zxvf $NODE_TGZ
438  export PATH=$PATH:`pwd`/$NODE_VERSION/bin
439  popd
440  cd js && npm install && npm test && cd ..
441  cd conformance && make test_nodejs && cd ..
442}
443
444use_php() {
445  VERSION=$1
446  export PATH=/usr/local/php-${VERSION}/bin:$PATH
447  internal_build_cpp
448}
449
450build_php() {
451  use_php $1
452  pushd php
453  rm -rf vendor
454  php -v
455  php -m
456  composer update
457  composer test
458  popd
459  (cd conformance && make test_php)
460}
461
462test_php_c() {
463  pushd php
464  rm -rf vendor
465  php -v
466  php -m
467  composer update
468  composer test_c
469  popd
470  (cd conformance && make test_php_c)
471}
472
473build_php_c() {
474  use_php $1
475  test_php_c
476}
477
478build_php7.0_mac() {
479  internal_build_cpp
480  # Install PHP
481  curl -s https://php-osx.liip.ch/install.sh | bash -s 7.0
482  PHP_FOLDER=`find /usr/local -type d -name "php5-7.0*"`  # The folder name may change upon time
483  test ! -z "$PHP_FOLDER"
484  export PATH="$PHP_FOLDER/bin:$PATH"
485
486  # Install Composer
487  wget https://getcomposer.org/download/2.0.13/composer.phar --progress=dot:mega -O /usr/local/bin/composer
488  chmod a+x /usr/local/bin/composer
489
490  # Install valgrind
491  echo "#! /bin/bash" > valgrind
492  chmod ug+x valgrind
493  sudo mv valgrind /usr/local/bin/valgrind
494
495  # Test
496  test_php_c
497}
498
499build_php7.3_mac() {
500  internal_build_cpp
501  # Install PHP
502  # We can't test PHP 7.4 with these binaries yet:
503  #   https://github.com/liip/php-osx/issues/276
504  curl -s https://php-osx.liip.ch/install.sh | bash -s 7.3
505  PHP_FOLDER=`find /usr/local -type d -name "php5-7.3*"`  # The folder name may change upon time
506  test ! -z "$PHP_FOLDER"
507  export PATH="$PHP_FOLDER/bin:$PATH"
508
509  # Install Composer
510  wget https://getcomposer.org/download/2.0.13/composer.phar --progress=dot:mega -O /usr/local/bin/composer
511  chmod a+x /usr/local/bin/composer
512
513  # Install valgrind
514  echo "#! /bin/bash" > valgrind
515  chmod ug+x valgrind
516  sudo mv valgrind /usr/local/bin/valgrind
517
518  # Test
519  test_php_c
520}
521
522build_php_compatibility() {
523  internal_build_cpp
524  php/tests/compatibility_test.sh $LAST_RELEASED
525}
526
527build_php_multirequest() {
528  use_php 7.4
529  php/tests/multirequest.sh
530}
531
532build_php8.0_all() {
533  build_php 8.0
534  build_php 8.1
535  build_php_c 8.0
536  build_php_c 8.1
537}
538
539build_php_all_32() {
540  build_php 7.0
541  build_php 7.1
542  build_php 7.4
543  build_php_c 7.0
544  build_php_c 7.1
545  build_php_c 7.4
546  build_php_c 7.1-zts
547  build_php_c 7.2-zts
548  build_php_c 7.5-zts
549}
550
551build_php_all() {
552  build_php_all_32
553  build_php_multirequest
554  build_php_compatibility
555}
556
557build_benchmark() {
558  use_php 7.2
559  cd kokoro/linux/benchmark && ./run.sh
560}
561
562# -------- main --------
563
564if [ "$#" -ne 1 ]; then
565  echo "
566Usage: $0 { cpp |
567            cpp_distcheck |
568            csharp |
569            java_jdk7 |
570            java_oracle7 |
571            java_linkage_monitor |
572            objectivec_ios |
573            objectivec_ios_debug |
574            objectivec_ios_release |
575            objectivec_osx |
576            objectivec_tvos |
577            objectivec_tvos_debug |
578            objectivec_tvos_release |
579            objectivec_cocoapods_integration |
580            python |
581            python_cpp |
582            python_compatibility |
583            ruby23 |
584            ruby24 |
585            ruby25 |
586            ruby26 |
587            ruby27 |
588            ruby30 |
589            ruby31 |
590            jruby92 |
591            jruby93 |
592            ruby_all |
593            php_all |
594            php_all_32 |
595            php7.0_mac |
596            php7.3_mac |
597            dist_install |
598            benchmark)
599"
600  exit 1
601fi
602
603set -e  # exit immediately on error
604set -x  # display all commands
605cd $(dirname $0)
606eval "build_$1"
607