Add bazel cpp distribtest for grpc_cc_library (#29175)

* Add bazel cpp distribtest for grpc_cc_library

* Add new directory to bazelignore

* Try changing to workspace differently

* Debug cd

* Fix bazel wrapper

* Yet more debug

* Try again

* Clean up

* Sanity fixes

* Run per-language distribtests even if overall build fails
pull/29229/head
Richard Belleville 3 years ago committed by GitHub
parent e79b2a9b32
commit 7942f30f63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .bazelignore
  2. 2
      bazel/test/python_test_repo/WORKSPACE
  3. 43
      test/distrib/bazel/cpp/BUILD
  4. 27
      test/distrib/bazel/cpp/WORKSPACE
  5. 104
      test/distrib/bazel/cpp/greeter_client.cc
  6. 73
      test/distrib/bazel/cpp/greeter_server.cc
  7. 61
      test/distrib/bazel/cpp/greeter_test.sh
  8. 37
      test/distrib/bazel/cpp/protos/BUILD
  9. 38
      test/distrib/bazel/cpp/protos/helloworld.proto
  10. 1
      test/distrib/bazel/cpp/tools/bazel
  11. 2
      test/distrib/bazel/run_bazel_distrib_test.sh
  12. 14
      test/distrib/bazel/test_single_bazel_version.sh

@ -21,6 +21,7 @@ third_party/upb
third_party/xds third_party/xds
bazel/test/python_test_repo bazel/test/python_test_repo
test/distrib/bazel/cpp
# Directories generated by setuptools build containing BUILD files. # Directories generated by setuptools build containing BUILD files.
src/python/grpcio_tests/src/ src/python/grpcio_tests/src/

@ -1,3 +1,5 @@
# TODO: Move to test/distrib/python.
local_repository( local_repository(
name = "com_github_grpc_grpc", name = "com_github_grpc_grpc",
path = "../../..", path = "../../..",

@ -0,0 +1,43 @@
# Copyright 2022 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
cc_binary(
name = "greeter_client",
srcs = ["greeter_client.cc"],
deps = [
"//protos:helloworld_cc_grpc",
"@com_github_grpc_grpc//:grpc++",
],
)
cc_binary(
name = "greeter_server",
srcs = ["greeter_server.cc"],
deps = [
"//protos:helloworld_cc_grpc",
"@com_github_grpc_grpc//:grpc++",
"@com_github_grpc_grpc//:grpc++_reflection",
],
)
sh_test(
name = "greeter_test",
srcs = ["greeter_test.sh"],
data = [
":greeter_client",
":greeter_server",
],
)

@ -0,0 +1,27 @@
# Copyright 2022 The gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
local_repository(
name = "com_github_grpc_grpc",
path = "../../../..",
)
workspace(name = "bazel_cpp_distribtests")
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
grpc_extra_deps()

@ -0,0 +1,104 @@
/*
*
* Copyright 2022 The gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "protos/helloworld.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
Status status = stub_->SayHello(&context, request, &reply);
// Act upon its status.
if (status.ok()) {
return reply.message();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
std::string target_str;
std::string arg_str("--target");
if (argc > 1) {
std::string arg_val = argv[1];
size_t start_pos = arg_val.find(arg_str);
if (start_pos != std::string::npos) {
start_pos += arg_str.size();
if (arg_val[start_pos] == '=') {
target_str = arg_val.substr(start_pos + 1);
} else {
std::cout << "The only correct argument syntax is --target="
<< std::endl;
return 0;
}
} else {
std::cout << "The only acceptable argument is --target=" << std::endl;
return 0;
}
} else {
target_str = "localhost:50051";
}
GreeterClient greeter(
grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}

@ -0,0 +1,73 @@
/*
*
* Copyright 2022 The gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#include "protos/helloworld.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:0");
GreeterServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
int bound_port;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials(), &bound_port);
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "127.0.0.1:" << bound_port << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv) {
RunServer();
return 0;
}

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Copyright 2022 The gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -exo pipefail
SERVER_PID=""
SERVER_TIMEOUT=10
SERVER_OUTPUT=$(mktemp)
function cleanup() {
if [ -n "$SERVER_PID" ]; then
kill "$SERVER_PID"
fi
}
function fail() {
echo "$1" >/dev/stderr
echo "Failed." >/dev/stderr
exit 1
}
function await_server() {
TIME=0
while [ ! -s "$SERVER_OUTPUT" ]; do
if [ "$TIME" == "$SERVER_TIMEOUT" ] ; then
fail "Server not listening after $SERVER_TIMEOUT seconds."
fi
sleep 1
TIME=$((TIME+1))
done
cat "$SERVER_OUTPUT"
}
trap cleanup SIGINT SIGTERM EXIT
./greeter_server >"$SERVER_OUTPUT" &
SERVER_PID=$!
SERVER_ADDRESS=$(await_server)
RESPONSE=$(./greeter_client --target="$SERVER_ADDRESS")
EXPECTED_RESPONSE="Greeter received: Hello world"
if [ "$RESPONSE" != "$EXPECTED_RESPONSE" ]; then
fail "Received response \"$RESPONSE\" but expected \"$EXPECTED_RESPONSE\""
fi
echo "Success."

@ -0,0 +1,37 @@
# Copyright 2022 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
licenses(["notice"])
package(default_visibility = ["//:__subpackages__"])
proto_library(
name = "helloworld_proto",
srcs = ["helloworld.proto"],
)
cc_proto_library(
name = "helloworld_cc_proto",
deps = [":helloworld_proto"],
)
cc_grpc_library(
name = "helloworld_cc_grpc",
srcs = [":helloworld_proto"],
grpc_only = True,
deps = [":helloworld_cc_proto"],
)

@ -0,0 +1,38 @@
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

@ -0,0 +1 @@
../../../../../tools/bazel

@ -28,6 +28,6 @@ done
if [ "$FAILED_VERSIONS" != "" ] if [ "$FAILED_VERSIONS" != "" ]
then then
echo "Bazel distribtest failed: Failed to build with bazel versions ${FAILED_VERSIONS}" echo "Bazel distribtest failed: Failing versions: ${FAILED_VERSIONS}"
exit 1 exit 1
fi fi

@ -41,7 +41,19 @@ EXCLUDED_TARGETS=(
"-//examples/android/binder/..." "-//examples/android/binder/..."
) )
FAILED_TESTS=""
export OVERRIDE_BAZEL_VERSION="$VERSION" export OVERRIDE_BAZEL_VERSION="$VERSION"
# when running under bazel docker image, the workspace is read only. # when running under bazel docker image, the workspace is read only.
export OVERRIDE_BAZEL_WRAPPER_DOWNLOAD_DIR=/tmp export OVERRIDE_BAZEL_WRAPPER_DOWNLOAD_DIR=/tmp
bazel build -- //... "${EXCLUDED_TARGETS[@]}" bazel build -- //... "${EXCLUDED_TARGETS[@]}" || FAILED_TESTS="${FAILED_TESTS}Build "
cd test/distrib/bazel/cpp/
bazel test //:all || FAILED_TESTS="${FAILED_TESTS}C++ Distribtest"
if [ "$FAILED_TESTS" != "" ]
then
echo "Failed tests at version ${VERSION}: ${FAILED_TESTS}"
exit 1
fi

Loading…
Cancel
Save