diff --git a/src/node/examples/math.proto b/src/node/examples/math.proto
index e34ad5e9672..311e148c021 100644
--- a/src/node/examples/math.proto
+++ b/src/node/examples/math.proto
@@ -33,25 +33,25 @@ syntax = "proto3";
package math;
message DivArgs {
- optional int64 dividend = 1;
- optional int64 divisor = 2;
+ int64 dividend = 1;
+ int64 divisor = 2;
}
message DivReply {
- optional int64 quotient = 1;
- optional int64 remainder = 2;
+ int64 quotient = 1;
+ int64 remainder = 2;
}
message FibArgs {
- optional int64 limit = 1;
+ int64 limit = 1;
}
message Num {
- optional int64 num = 1;
+ int64 num = 1;
}
message FibReply {
- optional int64 count = 1;
+ int64 count = 1;
}
service Math {
diff --git a/src/node/examples/route_guide.proto b/src/node/examples/route_guide.proto
index 442112823e5..fceb632a97d 100644
--- a/src/node/examples/route_guide.proto
+++ b/src/node/examples/route_guide.proto
@@ -66,18 +66,18 @@ service RouteGuide {
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {
- optional int32 latitude = 1;
- optional int32 longitude = 2;
+ int32 latitude = 1;
+ int32 longitude = 2;
}
// A latitude-longitude rectangle, represented as two diagonally opposite
// points "lo" and "hi".
message Rectangle {
// One corner of the rectangle.
- optional Point lo = 1;
+ Point lo = 1;
// The other corner of the rectangle.
- optional Point hi = 2;
+ Point hi = 2;
}
// A feature names something at a given point.
@@ -85,19 +85,19 @@ message Rectangle {
// If a feature could not be named, the name is empty.
message Feature {
// The name of the feature.
- optional string name = 1;
+ string name = 1;
// The point where the feature is detected.
- optional Point location = 2;
+ Point location = 2;
}
// A RouteNote is a message sent while at a given point.
message RouteNote {
// The location from which the message is sent.
- optional Point location = 1;
+ Point location = 1;
// The message to be sent.
- optional string message = 2;
+ string message = 2;
}
// A RouteSummary is received in response to a RecordRoute rpc.
@@ -107,14 +107,14 @@ message RouteNote {
// the distance between each point.
message RouteSummary {
// The number of points received.
- optional int32 point_count = 1;
+ int32 point_count = 1;
// The number of known features passed while traversing the route.
- optional int32 feature_count = 2;
+ int32 feature_count = 2;
// The distance covered in metres.
- optional int32 distance = 3;
+ int32 distance = 3;
// The duration of the traversal in seconds.
- optional int32 elapsed_time = 4;
+ int32 elapsed_time = 4;
}
diff --git a/src/node/examples/stock.proto b/src/node/examples/stock.proto
index 328e050aefb..5ee2bcbce66 100644
--- a/src/node/examples/stock.proto
+++ b/src/node/examples/stock.proto
@@ -33,13 +33,13 @@ package examples;
// Protocol type definitions
message StockRequest {
- optional string symbol = 1;
- optional int32 num_trades_to_watch = 2 [default=0];
+ string symbol = 1;
+ int32 num_trades_to_watch = 2;
}
message StockReply {
- optional float price = 1;
- optional string symbol = 2;
+ float price = 1;
+ string symbol = 2;
}
diff --git a/src/node/interop/empty.proto b/src/node/interop/empty.proto
index 4295a0a960c..6d0eb937d67 100644
--- a/src/node/interop/empty.proto
+++ b/src/node/interop/empty.proto
@@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-syntax = "proto2";
+syntax = "proto3";
package grpc.testing;
diff --git a/src/node/interop/messages.proto b/src/node/interop/messages.proto
index de0b1a23205..7df85e3c136 100644
--- a/src/node/interop/messages.proto
+++ b/src/node/interop/messages.proto
@@ -30,7 +30,7 @@
// Message definitions to be used by integration test service definitions.
-syntax = "proto2";
+syntax = "proto3";
package grpc.testing;
@@ -49,46 +49,46 @@ enum PayloadType {
// A block of data, to simply increase gRPC message size.
message Payload {
// The type of data in body.
- optional PayloadType type = 1 [default = COMPRESSABLE];
+ PayloadType type = 1;
// Primary contents of payload.
- optional bytes body = 2;
+ bytes body = 2;
}
// Unary request.
message SimpleRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
- optional PayloadType response_type = 1 [default = COMPRESSABLE];
+ PayloadType response_type = 1;
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
- optional int32 response_size = 2;
+ int32 response_size = 2;
// Optional input payload sent along with the request.
- optional Payload payload = 3;
+ Payload payload = 3;
// Whether SimpleResponse should include username.
- optional bool fill_username = 4;
+ bool fill_username = 4;
// Whether SimpleResponse should include OAuth scope.
- optional bool fill_oauth_scope = 5;
+ bool fill_oauth_scope = 5;
}
// Unary response, as configured by the request.
message SimpleResponse {
// Payload to increase message size.
- optional Payload payload = 1;
+ Payload payload = 1;
// The user the request came from, for verifying authentication was
// successful when the client expected it.
- optional string username = 2;
+ string username = 2;
// OAuth scope.
- optional string oauth_scope = 3;
+ string oauth_scope = 3;
}
// Client-streaming request.
message StreamingInputCallRequest {
// Optional input payload sent along with the request.
- optional Payload payload = 1;
+ Payload payload = 1;
// Not expecting any payload from the response.
}
@@ -96,18 +96,18 @@ message StreamingInputCallRequest {
// Client-streaming response.
message StreamingInputCallResponse {
// Aggregated size of payloads received from the client.
- optional int32 aggregated_payload_size = 1;
+ int32 aggregated_payload_size = 1;
}
// Configuration for a particular response.
message ResponseParameters {
// Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
- optional int32 size = 1;
+ int32 size = 1;
// Desired interval between consecutive responses in the response stream in
// microseconds.
- optional int32 interval_us = 2;
+ int32 interval_us = 2;
}
// Server-streaming request.
@@ -116,17 +116,17 @@ message StreamingOutputCallRequest {
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
// stream.
- optional PayloadType response_type = 1 [default = COMPRESSABLE];
+ PayloadType response_type = 1;
// Configuration for each expected response message.
repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request.
- optional Payload payload = 3;
+ Payload payload = 3;
}
// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
// Payload to increase response size.
- optional Payload payload = 1;
+ Payload payload = 1;
}
diff --git a/src/node/interop/test.proto b/src/node/interop/test.proto
index 927a3a83aa2..d2c3f9befef 100644
--- a/src/node/interop/test.proto
+++ b/src/node/interop/test.proto
@@ -30,7 +30,8 @@
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
-syntax = "proto2";
+
+syntax = "proto3";
import "empty.proto";
import "messages.proto";
diff --git a/src/node/package.json b/src/node/package.json
index 0bb3c3d1fd0..4033bc59cf9 100644
--- a/src/node/package.json
+++ b/src/node/package.json
@@ -26,7 +26,7 @@
"dependencies": {
"bindings": "^1.2.0",
"nan": "^1.5.0",
- "protobufjs": "^4.0.0-b2",
+ "protobufjs": "dcodeIO/ProtoBuf.js",
"underscore": "^1.6.0",
"underscore.string": "^3.0.0"
},
diff --git a/src/node/test/test_service.proto b/src/node/test/test_service.proto
index 5d3d891841f..564169829c3 100644
--- a/src/node/test/test_service.proto
+++ b/src/node/test/test_service.proto
@@ -27,14 +27,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-syntax = "proto2";
+syntax = "proto3";
message Request {
- optional bool error = 1;
+ bool error = 1;
}
message Response {
- optional int32 count = 1;
+ int32 count = 1;
}
service TestService {
diff --git a/src/python/README.md b/src/python/README.md
index 82bc7767322..b5eea239f33 100644
--- a/src/python/README.md
+++ b/src/python/README.md
@@ -7,7 +7,7 @@ The Python facility of gRPC.
Status
-------
-Usable with limitations, Pre-Alpha
+Usable with limitations, Alpha
Prerequisites
-----------------------
diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb
index 1bfe253b855..e46d9c671f9 100755
--- a/src/ruby/bin/math_server.rb
+++ b/src/ruby/bin/math_server.rb
@@ -55,7 +55,7 @@ class Fibber
return enum_for(:generator) unless block_given?
idx, current, previous = 0, 1, 1
until idx == @limit
- if idx == 0 || idx == 1
+ if idx.zero? || idx == 1
yield Math::Num.new(num: 1)
idx += 1
next
@@ -94,7 +94,7 @@ end
# package. That practice should be avoided by defining real services.
class Calculator < Math::Math::Service
def div(div_args, _call)
- if div_args.divisor == 0
+ if div_args.divisor.zero?
# To send non-OK status handlers raise a StatusError with the code and
# and detail they want sent as a Status.
fail GRPC::StatusError.new(GRPC::Status::INVALID_ARGUMENT,
diff --git a/src/ruby/lib/grpc/core/time_consts.rb b/src/ruby/lib/grpc/core/time_consts.rb
index 7750cb0febb..e6dae7b08a0 100644
--- a/src/ruby/lib/grpc/core/time_consts.rb
+++ b/src/ruby/lib/grpc/core/time_consts.rb
@@ -58,7 +58,7 @@ module GRPC
"Cannot make an absolute deadline from #{timeish.inspect}")
elsif timeish < 0
TimeConsts::INFINITE_FUTURE
- elsif timeish == 0
+ elsif timeish.zero?
TimeConsts::ZERO
else
Time.now + timeish
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 424719304e6..de224660894 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -146,7 +146,7 @@ module GRPC
def remove_current_thread
@stop_mutex.synchronize do
@workers.delete(Thread.current)
- @stop_cond.signal if @workers.size == 0
+ @stop_cond.signal if @workers.size.zero?
end
end
@@ -364,7 +364,7 @@ module GRPC
# - #running? returns true after this is called, until #stop cause the
# the server to stop.
def run
- if rpc_descs.size == 0
+ if rpc_descs.size.zero?
logger.warn('did not run as no services were present')
return
end
@@ -455,7 +455,7 @@ module GRPC
unless cls.include?(GenericService)
fail "#{cls} must 'include GenericService'"
end
- if cls.rpc_descs.size == 0
+ if cls.rpc_descs.size.zero?
fail "#{cls} should specify some rpc descriptions"
end
cls.assert_rpc_descs_have_methods
diff --git a/tools/gce_setup/cloud_prod_test.sh b/tools/gce_setup/cloud_prod_test.sh
new file mode 100755
index 00000000000..94869ee9b60
--- /dev/null
+++ b/tools/gce_setup/cloud_prod_test.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+thisfile=$(readlink -ne "${BASH_SOURCE[0]}")
+test_case=$1
+client_vm=$2
+result=cloud_prod_result.$1
+cur=$(date "+%Y-%m-%d-%H-%M-%S")
+log_link=https://pantheon.corp.google.com/m/cloudstorage/b/stoked-keyword-656-output/o/prod_result/$test_case/$cur
+
+main() {
+ source grpc_docker.sh
+ clients=(cxx java go ruby node csharp_mono python php)
+ for client in "${clients[@]}"
+ do
+ log_file_name=cloud_{$test_case}_{$client}.txt
+ if grpc_cloud_prod_test $test_case $client_vm $client > /tmp/$log_file_name 2>&1
+ then
+ echo " ['$test_case', '$client', 'prod', true, 'log']," >> /tmp/$result.txt
+ else
+ echo " ['$test_case', '$client', 'prod', false, 'log']," >> /tmp/$result.txt
+ fi
+ gsutil cp /tmp/$log_file_name gs://stoked-keyword-656-output/prod_result/$test_case/$cur/$log_file_name
+ rm /tmp/$log_file_name
+ done
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
+ cat pre.html /tmp/$result.txt post.html > /tmp/$result.html
+ gsutil cp /tmp/$result.html gs://stoked-keyword-656-output/prod_result/$test_case/$cur/$result.html
+ rm /tmp/$result.txt
+ rm /tmp/$result.html
+ fi
+}
+
+set -x
+main "$@"
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index d3a7bdef285..c49efbab606 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -384,6 +384,7 @@ grpc_interop_test_args() {
[[ -n $1 ]] && { # client_type
case $1 in
cxx|go|java|node|php|python|ruby|csharp_mono)
+ grpc_client_platform='Docker'
grpc_gen_test_cmd="grpc_interop_gen_$1_cmd"
declare -F $grpc_gen_test_cmd >> /dev/null || {
echo "-f: test_func for $1 => $grpc_gen_test_cmd is not defined" 1>&2
@@ -391,6 +392,11 @@ grpc_interop_test_args() {
}
shift
;;
+ csharp_dotnet)
+ grpc_client_platform='Windows'
+ grpc_gen_test_cmd="grpc_interop_gen_$1_cmd"
+ shift
+ ;;
*)
echo "bad client_type: $1" 1>&2
return 1
@@ -456,6 +462,7 @@ grpc_cloud_prod_test_args() {
[[ -n $1 ]] && { # client_type
case $1 in
cxx|go|java|node|php|python|ruby|csharp_mono)
+ grpc_client_platform='Docker'
grpc_gen_test_cmd="grpc_cloud_prod_gen_$1_cmd"
declare -F $grpc_gen_test_cmd >> /dev/null || {
echo "-f: test_func for $1 => $grpc_gen_test_cmd is not defined" 1>&2
@@ -463,6 +470,11 @@ grpc_cloud_prod_test_args() {
}
shift
;;
+ csharp_dotnet)
+ grpc_client_platform='Windows'
+ grpc_gen_test_cmd="grpc_cloud_prod_gen_$1_cmd"
+ shift
+ ;;
*)
echo "bad client_type: $1" 1>&2
return 1
@@ -851,12 +863,23 @@ grpc_launch_servers() {
test_runner() {
local project_opt="--project $grpc_project"
local zone_opt="--zone $grpc_zone"
- local ssh_cmd="bash -l -c \"$cmd\""
- echo "will run:"
- echo " $ssh_cmd"
- echo "on $host"
[[ $dry_run == 1 ]] && return 0 # don't run the command on a dry run
- gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
+ if [ "$grpc_client_platform" != "Windows" ]
+ then
+ echo "will run:"
+ echo " $cmd"
+ echo "on $host"
+ gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
+ else
+ # gcloud's auto-uploading of RSA keys doesn't work for Windows VMs.
+ # So we have a linux machine that is authorized to access the Windows
+ # machine through ssh and we use gcloud auth support to logon to the proxy.
+ echo "will run:"
+ echo " $cmd"
+ echo "on $host (through grpc-windows-proxy)"
+ gcloud compute $project_opt ssh $zone_opt stoked-keyword-656@grpc-windows-proxy --command "ssh $host '$cmd'" &
+ fi
+ #
PID=$!
echo "pid is $PID"
for x in {0..5}
@@ -924,7 +947,7 @@ grpc_interop_test() {
local grpc_zone grpc_project dry_run # set by _grpc_set_project_and_zone
# grpc_interop_test_args
- local test_case host grpc_gen_test_cmd grpc_server grpc_port
+ local test_case host grpc_gen_test_cmd grpc_server grpc_port grpc_client_platform
# set the project zone and check that all necessary args are provided
_grpc_set_project_and_zone -f grpc_interop_test_args "$@" || return 1
@@ -966,7 +989,7 @@ grpc_cloud_prod_test() {
local grpc_zone grpc_project dry_run # set by _grpc_set_project_and_zone
# grpc_cloud_prod_test_args
- local test_case host grpc_gen_test_cmd
+ local test_case host grpc_gen_test_cmd grpc_client_platform
# set the project zone and check that all necessary args are provided
_grpc_set_project_and_zone -f grpc_cloud_prod_test_args "$@" || return 1
@@ -1431,6 +1454,18 @@ grpc_interop_gen_csharp_mono_cmd() {
echo $the_cmd
}
+# constructs the csharp-dotnet interop test cmd.
+#
+# call-seq:
+# flags= .... # generic flags to include the command
+# cmd=$($grpc_gen_test_cmd $flags)
+grpc_interop_gen_csharp_dotnet_cmd() {
+ local set_workdir="cd /cygdrive/c/github/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug &&"
+ local test_script="./Grpc.IntegrationTesting.Client.exe --use_tls=true --use_test_ca=true";
+ local the_cmd="$set_workdir $test_script $@";
+ echo $the_cmd
+}
+
# constructs the full dockerized csharp-mono gce=>prod interop test cmd.
#
# call-seq:
@@ -1446,6 +1481,20 @@ grpc_cloud_prod_gen_csharp_mono_cmd() {
echo $the_cmd
}
+# constructs the csharp-dotnet gce=>prod interop test cmd.
+#
+# call-seq:
+# flags= .... # generic flags to include the command
+# cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_gen_csharp_dotnet_cmd() {
+ local set_workdir="cd /cygdrive/c/github/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug &&"
+ local test_script="./Grpc.IntegrationTesting.Client.exe --use_tls=true";
+ local set_certfile="SSL_CERT_FILE=/cacerts/roots.pem "
+ local gfe_flags=$(_grpc_prod_gfe_flags);
+ local the_cmd="$set_workdir $set_certfile $test_script $gfe_flags $@";
+ echo $the_cmd
+}
+
# constructs the full dockerized csharp-mono service_account auth interop test cmd.
#
# call-seq:
diff --git a/tools/gce_setup/interop_test.sh b/tools/gce_setup/interop_test.sh
new file mode 100755
index 00000000000..037b117e1aa
--- /dev/null
+++ b/tools/gce_setup/interop_test.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+thisfile=$(readlink -ne "${BASH_SOURCE[0]}")
+test_case=$1
+client_vm=$2
+server_vm=$3
+result=interop_result.$1
+cur=$(date "+%Y-%m-%d-%H-%M-%S")
+log_link=https://pantheon.corp.google.com/m/cloudstorage/b/stoked-keyword-656-output/o/interop_result/$test_case/$cur
+
+main() {
+ source grpc_docker.sh
+ clients=(cxx java go ruby node csharp_mono python php)
+ servers=(cxx java go ruby node python csharp_mono)
+ for client in "${clients[@]}"
+ do
+ for server in "${servers[@]}"
+ do
+ log_file_name=cloud_{$test_case}_{$client}_{$server}.txt
+ if grpc_interop_test $test_case $client_vm $client $server_vm $server> /tmp/$log_file_name 2>&1
+ then
+ echo " ['$test_case', '$client', '$server', true, 'log']," >> /tmp/$result.txt
+ else
+ echo " ['$test_case', '$client', '$server', false, 'log']," >> /tmp/$result.txt
+ fi
+ gsutil cp /tmp/$log_file_name gs://stoked-keyword-656-output/interop_result/$test_case/$cur/$log_file_name
+ rm /tmp/$log_file_name
+ done
+ done
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
+ cat pre.html /tmp/$result.txt post.html > /tmp/$result.html
+ gsutil cp /tmp/$result.html gs://stoked-keyword-656-output/interop_result/$test_case/$cur/$result.html
+ rm /tmp/$result.txt
+ rm /tmp/$result.html
+ fi
+}
+
+set -x
+main "$@"