blob: ad06c4129ba11ed5f54d399bb962cde341c41bfb [file] [log] [blame]
Joe Tsai1bed4542018-08-03 19:13:55 -07001#!/bin/bash
2# Copyright 2018 The Go Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style
4# license that can be found in the LICENSE file.
5
6REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
Joe Tsaiea04a132018-08-07 16:42:30 -07008function print() { echo -e "\x1b[1m> $@\x1b[0m"; }
9
Joe Tsai913ace22018-08-15 11:53:54 -070010# The test directory contains the Go and protobuf toolchains used for testing.
11# The bin directory contains symlinks to each tool by version.
12# It is safe to delete this directory and run the test script from scratch.
Joe Tsaif8505dac2018-09-06 12:37:19 -070013TEST_DIR=$REPO_ROOT/.cache
Joe Tsai913ace22018-08-15 11:53:54 -070014mkdir -p $TEST_DIR/bin
15function register_binary() {
16 rm -f $TEST_DIR/bin/$1 # best-effort delete
17 ln -s $TEST_DIR/$2 $TEST_DIR/bin/$1
18}
19export PATH=$TEST_DIR/bin:$PATH
20cd $TEST_DIR # install toolchains relative to test directory
Joe Tsai1bed4542018-08-03 19:13:55 -070021
22# Download and build the protobuf toolchain.
23# We avoid downloading the pre-compiled binaries since they do not contain
24# the conformance test runner.
25PROTOBUF_VERSION=3.6.1
26PROTOBUF_DIR="protobuf-$PROTOBUF_VERSION"
27if [ ! -d $PROTOBUF_DIR ]; then
Joe Tsaiea04a132018-08-07 16:42:30 -070028 print "download and build $PROTOBUF_DIR"
Joe Tsai1bed4542018-08-03 19:13:55 -070029 (curl -s -L https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz | tar -zxf -) || exit 1
30 (cd $PROTOBUF_DIR && ./configure && make && cd conformance && make) || exit 1
31fi
Joe Tsai913ace22018-08-15 11:53:54 -070032register_binary conformance-test-runner $PROTOBUF_DIR/conformance/conformance-test-runner
33register_binary protoc $PROTOBUF_DIR/src/protoc
Joe Tsai19058432019-02-27 21:46:29 -080034export PROTOBUF_ROOT=$TEST_DIR/$PROTOBUF_DIR
35
36# Patch proto files in the toolchain with new locations of Go packages.
37# TODO: these changes should be committed upstream.
38if ! grep -q "option go_package =" $PROTOBUF_ROOT/conformance/conformance.proto; then
39(cat << EOF
40--- a/conformance/conformance.proto 2018-07-30 15:16:10.000000000 -0700
41+++ b/conformance/conformance.proto 2019-01-20 03:03:47.000000000 -0800
42@@ -32,0 +33 @@
43+option go_package = "github.com/golang/protobuf/v2/internal/testprotos/conformance;conformance_proto";
44--- a/src/google/protobuf/any.proto 2018-07-23 13:56:42.000000000 -0700
45+++ b/src/google/protobuf/any.proto 2019-01-20 02:58:13.000000000 -0800
46@@ -36 +36 @@
47-option go_package = "github.com/golang/protobuf/ptypes/any";
48+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
49--- a/src/google/protobuf/api.proto 2018-07-23 13:56:42.000000000 -0700
50+++ b/src/google/protobuf/api.proto 2019-01-20 03:00:58.000000000 -0800
51@@ -43 +43 @@
52-option go_package = "google.golang.org/genproto/protobuf/api;api";
53+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
54--- a/src/google/protobuf/compiler/plugin.proto 2018-07-23 13:56:42.000000000 -0700
55+++ b/src/google/protobuf/compiler/plugin.proto 2019-01-20 03:03:49.000000000 -0800
56@@ -52 +52 @@
57-option go_package = "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go";
58+option go_package = "github.com/golang/protobuf/v2/types/plugin;plugin_proto";
59--- a/src/google/protobuf/descriptor.proto 2018-07-23 13:56:42.000000000 -0700
60+++ b/src/google/protobuf/descriptor.proto 2019-01-20 03:03:52.000000000 -0800
61@@ -43 +43 @@
62-option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor";
63+option go_package = "github.com/golang/protobuf/v2/types/descriptor;descriptor_proto";
64--- a/src/google/protobuf/duration.proto 2018-07-23 13:56:42.000000000 -0700
65+++ b/src/google/protobuf/duration.proto 2019-01-20 03:00:55.000000000 -0800
66@@ -37 +37 @@
67-option go_package = "github.com/golang/protobuf/ptypes/duration";
68+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
69--- a/src/google/protobuf/empty.proto 2018-07-23 13:56:42.000000000 -0700
70+++ b/src/google/protobuf/empty.proto 2019-01-20 03:00:52.000000000 -0800
71@@ -36 +36 @@
72-option go_package = "github.com/golang/protobuf/ptypes/empty";
73+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
74--- a/src/google/protobuf/field_mask.proto 2018-07-23 13:56:42.000000000 -0700
75+++ b/src/google/protobuf/field_mask.proto 2019-01-20 03:00:50.000000000 -0800
76@@ -40 +40 @@
77-option go_package = "google.golang.org/genproto/protobuf/field_mask;field_mask";
78+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
79--- a/src/google/protobuf/source_context.proto 2018-07-23 13:56:42.000000000 -0700
80+++ b/src/google/protobuf/source_context.proto 2019-01-20 03:00:47.000000000 -0800
81@@ -40 +40 @@
82-option go_package = "google.golang.org/genproto/protobuf/source_context;source_context";
83+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
84--- a/src/google/protobuf/struct.proto 2018-07-23 13:56:42.000000000 -0700
85+++ b/src/google/protobuf/struct.proto 2019-01-20 03:00:42.000000000 -0800
86@@ -37 +37 @@
87-option go_package = "github.com/golang/protobuf/ptypes/struct;structpb";
88+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
89--- a/src/google/protobuf/timestamp.proto 2018-07-23 13:56:42.000000000 -0700
90+++ b/src/google/protobuf/timestamp.proto 2019-01-20 03:00:40.000000000 -0800
91@@ -37 +37 @@
92-option go_package = "github.com/golang/protobuf/ptypes/timestamp";
93+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
94--- a/src/google/protobuf/type.proto 2018-07-23 13:56:42.000000000 -0700
95+++ b/src/google/protobuf/type.proto 2019-01-20 03:03:44.000000000 -0800
96@@ -44 +44 @@
97-option go_package = "google.golang.org/genproto/protobuf/ptype;ptype";
98+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
99--- a/src/google/protobuf/wrappers.proto 2018-07-23 13:56:42.000000000 -0700
100+++ b/src/google/protobuf/wrappers.proto 2019-01-20 03:03:45.000000000 -0800
101@@ -42 +42 @@
102-option go_package = "github.com/golang/protobuf/ptypes/wrappers";
103+option go_package = "github.com/golang/protobuf/v2/types/known;known_proto";
104EOF
105) | patch -d $PROTOBUF_ROOT -p1
106fi
Joe Tsai1bed4542018-08-03 19:13:55 -0700107
108# Download each Go toolchain version.
Herbie Ong402382e2019-01-02 15:58:39 -0800109GO_LATEST=go1.11.4
110GO_VERSIONS=(go1.9.7 go1.10.7 $GO_LATEST)
Joe Tsai1bed4542018-08-03 19:13:55 -0700111for GO_VERSION in ${GO_VERSIONS[@]}; do
Joe Tsai913ace22018-08-15 11:53:54 -0700112 if [ ! -d $GO_VERSION ]; then
113 print "download $GO_VERSION"
Joe Tsai1bed4542018-08-03 19:13:55 -0700114 GOOS=$(uname | tr '[:upper:]' '[:lower:]')
Joe Tsai913ace22018-08-15 11:53:54 -0700115 (mkdir $GO_VERSION && curl -s -L https://dl.google.com/go/$GO_VERSION.$GOOS-amd64.tar.gz | tar -zxf - -C $GO_VERSION --strip-components 1) || exit 1
Joe Tsai1bed4542018-08-03 19:13:55 -0700116 fi
Joe Tsai913ace22018-08-15 11:53:54 -0700117 register_binary $GO_VERSION $GO_VERSION/bin/go
Joe Tsai1bed4542018-08-03 19:13:55 -0700118done
Joe Tsai913ace22018-08-15 11:53:54 -0700119register_binary go $GO_LATEST/bin/go
120register_binary gofmt $GO_LATEST/bin/gofmt
Joe Tsai1bed4542018-08-03 19:13:55 -0700121
Joe Tsaid1e65e62018-08-07 14:54:07 -0700122# Travis-CI sets GOROOT, which confuses later invocations of the Go toolchains.
123# Explicitly clear GOROOT, so each toolchain uses their default GOROOT.
124unset GOROOT
125
Joe Tsai913ace22018-08-15 11:53:54 -0700126# Setup GOPATH for pre-module support.
Joe Tsaib4af2c62018-09-22 16:00:02 -0700127export GOPATH=$TEST_DIR/gopath
Joe Tsai913ace22018-08-15 11:53:54 -0700128MODULE_PATH=$(cd $REPO_ROOT && go list -m -f "{{.Path}}")
Joe Tsaib4af2c62018-09-22 16:00:02 -0700129rm -rf gopath/src # best-effort delete
Joe Tsai913ace22018-08-15 11:53:54 -0700130mkdir -p gopath/src/$(dirname $MODULE_PATH)
131(cd gopath/src/$(dirname $MODULE_PATH) && ln -s $REPO_ROOT $(basename $MODULE_PATH))
Joe Tsai913ace22018-08-15 11:53:54 -0700132
Joe Tsaied2fbe02018-08-04 00:17:53 -0700133# Download dependencies using modules.
134# For pre-module support, dump the dependencies in a vendor directory.
Joe Tsai913ace22018-08-15 11:53:54 -0700135(cd $REPO_ROOT && go mod tidy && go mod vendor) || exit 1
Joe Tsai1bed4542018-08-03 19:13:55 -0700136
Joe Tsai19058432019-02-27 21:46:29 -0800137# Regenerate Go source files.
138if [ "$1" == "-regenerate" ]; then
139 cd $REPO_ROOT
140 go run ./internal/cmd/generate-types -execute || exit 1
141 go run ./internal/cmd/generate-protos -execute || exit 1
142 gofmt -w $(git ls-files '*.go') || exit 1
143 exit 0
144fi
145
Joe Tsai1bed4542018-08-03 19:13:55 -0700146# Run tests across every supported version of Go.
Joe Tsaiea04a132018-08-07 16:42:30 -0700147LABELS=()
148PIDS=()
149OUTS=()
150function cleanup() { for OUT in ${OUTS[@]}; do rm $OUT; done; }
151trap cleanup EXIT
Joe Tsai1bed4542018-08-03 19:13:55 -0700152for GO_VERSION in ${GO_VERSIONS[@]}; do
Joe Tsaiea04a132018-08-07 16:42:30 -0700153 # Run the go command in a background process.
154 function go() {
Joe Tsai913ace22018-08-15 11:53:54 -0700155 # Use a per-version Go cache to work around bugs in Go build caching.
156 # See https://golang.org/issue/26883
157 GO_CACHE="$TEST_DIR/cache.$GO_VERSION"
158 LABELS+=("$(echo "$GO_VERSION $@")")
Joe Tsaiea04a132018-08-07 16:42:30 -0700159 OUT=$(mktemp)
Joe Tsai913ace22018-08-15 11:53:54 -0700160 (cd $GOPATH/src/$MODULE_PATH && GOCACHE=$GO_CACHE $GO_VERSION "$@" &> $OUT) &
Joe Tsaiea04a132018-08-07 16:42:30 -0700161 PIDS+=($!)
162 OUTS+=($OUT)
Joe Tsai1bed4542018-08-03 19:13:55 -0700163 }
164
Joe Tsai19058432019-02-27 21:46:29 -0800165 # TODO: "go build" does not descend into testdata, which means that
166 # generated .pb.go files are not being built.
Joe Tsaiea04a132018-08-07 16:42:30 -0700167 go build ./...
168 go test -race ./...
Joe Tsaidbc9a122018-08-03 17:13:23 -0700169 go test -race -tags purego ./...
Joe Tsaiea04a132018-08-07 16:42:30 -0700170 go test -race -tags proto1_legacy ./...
Joe Tsai913ace22018-08-15 11:53:54 -0700171
172 unset go # to avoid confusing later invocations of "go"
Joe Tsai1bed4542018-08-03 19:13:55 -0700173done
Joe Tsaied2fbe02018-08-04 00:17:53 -0700174
Joe Tsaiea04a132018-08-07 16:42:30 -0700175# Wait for all processes to finish.
176RET=0
177for I in ${!PIDS[@]}; do
178 print "${LABELS[$I]}"
179 if ! wait ${PIDS[$I]}; then
180 cat ${OUTS[$I]} # only output upon error
181 RET=1
182 fi
183done
184
Joe Tsai913ace22018-08-15 11:53:54 -0700185# Run commands that produce output when there is a failure.
186function check() {
187 OUT=$(cd $REPO_ROOT && "$@" 2>&1)
188 if [ ! -z "$OUT" ]; then
189 print "$@"
190 echo "$OUT"
191 RET=1
192 fi
193}
Joe Tsaiea04a132018-08-07 16:42:30 -0700194
Joe Tsai913ace22018-08-15 11:53:54 -0700195# Check for stale or unformatted source files.
196check go run ./internal/cmd/generate-types
Joe Tsai19058432019-02-27 21:46:29 -0800197check go run ./internal/cmd/generate-protos
Joe Tsaif8505dac2018-09-06 12:37:19 -0700198check gofmt -d $(cd $REPO_ROOT && git ls-files '*.go')
Joe Tsaiea04a132018-08-07 16:42:30 -0700199
Joe Tsai913ace22018-08-15 11:53:54 -0700200# Check for changed or untracked files.
201check git diff --no-prefix HEAD
202check git ls-files --others --exclude-standard
Joe Tsaied2fbe02018-08-04 00:17:53 -0700203
Joe Tsaiea04a132018-08-07 16:42:30 -0700204# Print termination status.
205if [ $RET -eq 0 ]; then
206 echo -e "\x1b[32;1mPASS\x1b[0m"
207else
208 echo -e "\x1b[31;1mFAIL\x1b[0m"
209fi
210exit $RET