mirror of https://github.com/grpc/grpc.git
commit
b14ea0b907
93 changed files with 2360 additions and 323 deletions
@ -0,0 +1,41 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H |
||||
#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpcpp/impl/server_builder_plugin.h> |
||||
#include <grpcpp/impl/server_initializer.h> |
||||
#include <grpcpp/support/config.h> |
||||
|
||||
namespace grpc { |
||||
namespace channelz { |
||||
namespace experimental { |
||||
|
||||
/// Add channelz server plugin to \a ServerBuilder. This function should
|
||||
/// be called at static initialization time. This service is experimental
|
||||
/// for now. Track progress in https://github.com/grpc/grpc/issues/15988.
|
||||
void InitChannelzService(); |
||||
|
||||
} // namespace experimental
|
||||
} // namespace channelz
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H
|
@ -0,0 +1,57 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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 <grpc/support/port_platform.h> |
||||
|
||||
#include "src/cpp/server/channelz/channelz_service.h" |
||||
|
||||
#include <google/protobuf/text_format.h> |
||||
#include <google/protobuf/util/json_util.h> |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
|
||||
namespace grpc { |
||||
|
||||
Status ChannelzService::GetTopChannels( |
||||
ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, |
||||
channelz::v1::GetTopChannelsResponse* response) { |
||||
char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); |
||||
google::protobuf::util::Status s = |
||||
google::protobuf::util::JsonStringToMessage(json_str, response); |
||||
gpr_free(json_str); |
||||
if (s != google::protobuf::util::Status::OK) { |
||||
return Status(INTERNAL, s.ToString()); |
||||
} |
||||
return Status::OK; |
||||
} |
||||
|
||||
Status ChannelzService::GetChannel( |
||||
ServerContext* unused, const channelz::v1::GetChannelRequest* request, |
||||
channelz::v1::GetChannelResponse* response) { |
||||
char* json_str = grpc_channelz_get_channel(request->channel_id()); |
||||
google::protobuf::util::Status s = |
||||
google::protobuf::util::JsonStringToMessage(json_str, response); |
||||
gpr_free(json_str); |
||||
if (s != google::protobuf::util::Status::OK) { |
||||
return Status(INTERNAL, s.ToString()); |
||||
} |
||||
return Status::OK; |
||||
} |
||||
|
||||
} // namespace grpc
|
@ -0,0 +1,43 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H |
||||
#define GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpcpp/grpcpp.h> |
||||
#include "src/proto/grpc/channelz/channelz.grpc.pb.h" |
||||
|
||||
namespace grpc { |
||||
|
||||
class ChannelzService final : public channelz::v1::Channelz::Service { |
||||
private: |
||||
// implementation of GetTopChannels rpc
|
||||
Status GetTopChannels( |
||||
ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, |
||||
channelz::v1::GetTopChannelsResponse* response) override; |
||||
// implementation of GetChannel rpc
|
||||
Status GetChannel(ServerContext* unused, |
||||
const channelz::v1::GetChannelRequest* request, |
||||
channelz::v1::GetChannelResponse* response) override; |
||||
}; |
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H
|
@ -0,0 +1,79 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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 <grpc/support/port_platform.h> |
||||
|
||||
#include <grpcpp/ext/channelz_service_plugin.h> |
||||
#include <grpcpp/impl/server_builder_plugin.h> |
||||
#include <grpcpp/impl/server_initializer.h> |
||||
#include <grpcpp/server.h> |
||||
|
||||
#include "src/cpp/server/channelz/channelz_service.h" |
||||
|
||||
namespace grpc { |
||||
namespace channelz { |
||||
namespace experimental { |
||||
|
||||
class ChannelzServicePlugin : public ::grpc::ServerBuilderPlugin { |
||||
public: |
||||
ChannelzServicePlugin() : channelz_service_(new grpc::ChannelzService()) {} |
||||
|
||||
grpc::string name() override { return "channelz_service"; } |
||||
|
||||
void InitServer(grpc::ServerInitializer* si) override { |
||||
si->RegisterService(channelz_service_); |
||||
} |
||||
|
||||
void Finish(grpc::ServerInitializer* si) override {} |
||||
|
||||
void ChangeArguments(const grpc::string& name, void* value) override {} |
||||
|
||||
bool has_sync_methods() const override { |
||||
if (channelz_service_) { |
||||
return channelz_service_->has_synchronous_methods(); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool has_async_methods() const override { |
||||
if (channelz_service_) { |
||||
return channelz_service_->has_async_methods(); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private: |
||||
std::shared_ptr<grpc::ChannelzService> channelz_service_; |
||||
}; |
||||
|
||||
static std::unique_ptr< ::grpc::ServerBuilderPlugin> |
||||
CreateChannelzServicePlugin() { |
||||
return std::unique_ptr< ::grpc::ServerBuilderPlugin>( |
||||
new ChannelzServicePlugin()); |
||||
} |
||||
|
||||
void InitChannelzService() { |
||||
static bool already_here = false; |
||||
if (already_here) return; |
||||
already_here = true; |
||||
::grpc::ServerBuilder::InternalAddPluginFactory(&CreateChannelzServicePlugin); |
||||
} |
||||
|
||||
} // namespace experimental
|
||||
} // namespace channelz
|
||||
} // namespace grpc
|
@ -1,7 +1,7 @@ |
||||
<!-- This file is generated --> |
||||
<Project> |
||||
<PropertyGroup> |
||||
<GrpcCsharpVersion>1.14.0-dev</GrpcCsharpVersion> |
||||
<GrpcCsharpVersion>1.15.0-dev</GrpcCsharpVersion> |
||||
<GoogleProtobufVersion>3.5.1</GoogleProtobufVersion> |
||||
</PropertyGroup> |
||||
</Project> |
||||
|
@ -0,0 +1,28 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<_GrpcCoreNugetNativePath Condition="'$(_GrpcCoreNugetNativePath)' == ''">$(MSBuildThisFileDirectory)..\..\</_GrpcCoreNugetNativePath> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'"> |
||||
<AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\arm64-v8a\libgrpc_csharp_ext.so"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
<Abi>arm64-v8a</Abi> |
||||
</AndroidNativeLibrary> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'"> |
||||
<AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\armeabi-v7a\libgrpc_csharp_ext.so"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
<Abi>armeabi-v7a</Abi> |
||||
</AndroidNativeLibrary> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'"> |
||||
<AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\x86\libgrpc_csharp_ext.so"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
<Abi>x86</Abi> |
||||
</AndroidNativeLibrary> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,15 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
||||
<ItemGroup> |
||||
<NativeReference Include="$(MSBuildThisFileDirectory)..\..\runtimes\ios\native\libgrpc_csharp_ext.a"> |
||||
<Kind>Static</Kind> |
||||
<ForceLoad>True</ForceLoad> |
||||
</NativeReference> |
||||
<NativeReference Include="$(MSBuildThisFileDirectory)..\..\runtimes\ios\native\libgrpc.a"> |
||||
<Kind>Static</Kind> |
||||
<ForceLoad>True</ForceLoad> |
||||
</NativeReference> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,62 @@ |
||||
#!/bin/sh |
||||
# Copyright 2018 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. |
||||
|
||||
# Helper script to crosscompile grpc_csharp_ext native extension for Android. |
||||
|
||||
set -ex |
||||
|
||||
cd "$(dirname "$0")/../../.." |
||||
|
||||
# Usage: build <iphoneos|iphonesimulator> <arm64|x86_64|...> |
||||
function build { |
||||
SDK="$1" |
||||
ARCH="$2" |
||||
|
||||
PATH_AR="$(xcrun --sdk $SDK --find ar)" |
||||
PATH_CC="$(xcrun --sdk $SDK --find clang)" |
||||
PATH_CXX="$(xcrun --sdk $SDK --find clang++)" |
||||
|
||||
# TODO(jtattermusch): add -mios-version-min=6.0 and -Wl,ios_version_min=6.0 |
||||
CPPFLAGS="-O2 -Wframe-larger-than=16384 -arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -DPB_NO_PACKED_STRUCTS=1" |
||||
LDFLAGS="-arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path)" |
||||
|
||||
# TODO(jtattermusch): revisit the build arguments |
||||
make -j4 static_csharp \ |
||||
VALID_CONFIG_ios_$ARCH="1" \ |
||||
CC_ios_$ARCH="$PATH_CC" \ |
||||
CXX_ios_$ARCH="$PATH_CXX" \ |
||||
LD_ios_$ARCH="$PATH_CC" \ |
||||
LDXX_ios_$ARCH="$PATH_CXX" \ |
||||
CPPFLAGS_ios_$ARCH="$CPPFLAGS" \ |
||||
LDFLAGS_ios_$ARCH="$LDFLAGS" \ |
||||
DEFINES_ios_$ARCH="NDEBUG" \ |
||||
CONFIG="ios_$ARCH" |
||||
} |
||||
|
||||
# Usage: fatten <grpc_csharp_ext|...> |
||||
function fatten { |
||||
LIB_NAME="$1" |
||||
|
||||
mkdir -p libs/ios |
||||
lipo -create -output libs/ios/lib$LIB_NAME.a \ |
||||
libs/ios_arm64/lib$LIB_NAME.a \ |
||||
libs/ios_x86_64/lib$LIB_NAME.a |
||||
} |
||||
|
||||
build iphoneos arm64 |
||||
build iphonesimulator x86_64 |
||||
|
||||
fatten grpc |
||||
fatten grpc_csharp_ext |
@ -0,0 +1,352 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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 <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpcpp/channel.h> |
||||
#include <grpcpp/client_context.h> |
||||
#include <grpcpp/create_channel.h> |
||||
#include <grpcpp/security/credentials.h> |
||||
#include <grpcpp/security/server_credentials.h> |
||||
#include <grpcpp/server.h> |
||||
#include <grpcpp/server_builder.h> |
||||
#include <grpcpp/server_context.h> |
||||
|
||||
#include <grpcpp/ext/channelz_service_plugin.h> |
||||
#include "src/proto/grpc/channelz/channelz.grpc.pb.h" |
||||
#include "src/proto/grpc/testing/echo.grpc.pb.h" |
||||
#include "test/core/util/port.h" |
||||
#include "test/core/util/test_config.h" |
||||
#include "test/cpp/end2end/test_service_impl.h" |
||||
|
||||
#include <gtest/gtest.h> |
||||
|
||||
using grpc::channelz::v1::GetChannelRequest; |
||||
using grpc::channelz::v1::GetChannelResponse; |
||||
using grpc::channelz::v1::GetTopChannelsRequest; |
||||
using grpc::channelz::v1::GetTopChannelsResponse; |
||||
|
||||
namespace grpc { |
||||
namespace testing { |
||||
namespace { |
||||
|
||||
// Proxy service supports N backends. Sends RPC to backend dictated by
|
||||
// request->backend_channel_idx().
|
||||
class Proxy : public ::grpc::testing::EchoTestService::Service { |
||||
public: |
||||
Proxy() {} |
||||
|
||||
void AddChannelToBackend(const std::shared_ptr<Channel>& channel) { |
||||
stubs_.push_back(grpc::testing::EchoTestService::NewStub(channel)); |
||||
} |
||||
|
||||
Status Echo(ServerContext* server_context, const EchoRequest* request, |
||||
EchoResponse* response) override { |
||||
std::unique_ptr<ClientContext> client_context = |
||||
ClientContext::FromServerContext(*server_context); |
||||
size_t idx = request->param().backend_channel_idx(); |
||||
GPR_ASSERT(idx < stubs_.size()); |
||||
return stubs_[idx]->Echo(client_context.get(), *request, response); |
||||
} |
||||
|
||||
private: |
||||
std::vector<std::unique_ptr<::grpc::testing::EchoTestService::Stub>> stubs_; |
||||
}; |
||||
|
||||
} // namespace
|
||||
|
||||
class ChannelzServerTest : public ::testing::Test { |
||||
public: |
||||
ChannelzServerTest() {} |
||||
|
||||
void SetUp() override { |
||||
// ensure channel server is brought up on all severs we build.
|
||||
::grpc::channelz::experimental::InitChannelzService(); |
||||
|
||||
// We set up a proxy server with channelz enabled.
|
||||
proxy_port_ = grpc_pick_unused_port_or_die(); |
||||
ServerBuilder proxy_builder; |
||||
grpc::string proxy_server_address = "localhost:" + to_string(proxy_port_); |
||||
proxy_builder.AddListeningPort(proxy_server_address, |
||||
InsecureServerCredentials()); |
||||
// forces channelz and channel tracing to be enabled.
|
||||
proxy_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 1); |
||||
proxy_builder.AddChannelArgument(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE, |
||||
10); |
||||
proxy_builder.RegisterService(&proxy_service_); |
||||
proxy_server_ = proxy_builder.BuildAndStart(); |
||||
} |
||||
|
||||
// Sets the proxy up to have an arbitrary number of backends.
|
||||
void ConfigureProxy(size_t num_backends) { |
||||
backends_.resize(num_backends); |
||||
for (size_t i = 0; i < num_backends; ++i) { |
||||
// create a new backend.
|
||||
backends_[i].port = grpc_pick_unused_port_or_die(); |
||||
ServerBuilder backend_builder; |
||||
grpc::string backend_server_address = |
||||
"localhost:" + to_string(backends_[i].port); |
||||
backend_builder.AddListeningPort(backend_server_address, |
||||
InsecureServerCredentials()); |
||||
backends_[i].service.reset(new TestServiceImpl); |
||||
// ensure that the backend itself has channelz disabled.
|
||||
backend_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 0); |
||||
backend_builder.RegisterService(backends_[i].service.get()); |
||||
backends_[i].server = backend_builder.BuildAndStart(); |
||||
// set up a channel to the backend. We ensure that this channel has
|
||||
// channelz enabled since these channels (proxy outbound to backends)
|
||||
// are the ones that our test will actually be validating.
|
||||
ChannelArguments args; |
||||
args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1); |
||||
args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE, 10); |
||||
std::shared_ptr<Channel> channel_to_backend = CreateCustomChannel( |
||||
backend_server_address, InsecureChannelCredentials(), args); |
||||
proxy_service_.AddChannelToBackend(channel_to_backend); |
||||
} |
||||
} |
||||
|
||||
void ResetStubs() { |
||||
string target = "dns:localhost:" + to_string(proxy_port_); |
||||
ChannelArguments args; |
||||
// disable channelz. We only want to focus on proxy to backend outbound.
|
||||
args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); |
||||
std::shared_ptr<Channel> channel = |
||||
CreateCustomChannel(target, InsecureChannelCredentials(), args); |
||||
channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel); |
||||
echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); |
||||
} |
||||
|
||||
void SendSuccessfulEcho(int channel_idx) { |
||||
EchoRequest request; |
||||
EchoResponse response; |
||||
request.set_message("Hello channelz"); |
||||
request.mutable_param()->set_backend_channel_idx(channel_idx); |
||||
ClientContext context; |
||||
Status s = echo_stub_->Echo(&context, request, &response); |
||||
EXPECT_EQ(response.message(), request.message()); |
||||
EXPECT_TRUE(s.ok()); |
||||
} |
||||
|
||||
void SendFailedEcho(int channel_idx) { |
||||
EchoRequest request; |
||||
EchoResponse response; |
||||
request.set_message("Hello channelz"); |
||||
request.mutable_param()->set_backend_channel_idx(channel_idx); |
||||
auto* error = request.mutable_param()->mutable_expected_error(); |
||||
error->set_code(13); // INTERNAL
|
||||
error->set_error_message("error"); |
||||
ClientContext context; |
||||
Status s = echo_stub_->Echo(&context, request, &response); |
||||
EXPECT_FALSE(s.ok()); |
||||
} |
||||
|
||||
static string to_string(const int number) { |
||||
std::stringstream strs; |
||||
strs << number; |
||||
return strs.str(); |
||||
} |
||||
|
||||
protected: |
||||
// package of data needed for each backend server.
|
||||
struct BackendData { |
||||
std::unique_ptr<Server> server; |
||||
int port; |
||||
std::unique_ptr<TestServiceImpl> service; |
||||
}; |
||||
|
||||
std::unique_ptr<grpc::channelz::v1::Channelz::Stub> channelz_stub_; |
||||
std::unique_ptr<grpc::testing::EchoTestService::Stub> echo_stub_; |
||||
|
||||
// proxy server to ping with channelz requests.
|
||||
std::unique_ptr<Server> proxy_server_; |
||||
int proxy_port_; |
||||
Proxy proxy_service_; |
||||
|
||||
// backends. All implement the echo service.
|
||||
std::vector<BackendData> backends_; |
||||
}; |
||||
|
||||
TEST_F(ChannelzServerTest, BasicTest) { |
||||
ResetStubs(); |
||||
ConfigureProxy(1); |
||||
GetTopChannelsRequest request; |
||||
GetTopChannelsResponse response; |
||||
request.set_start_channel_id(0); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetTopChannels(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel_size(), 1); |
||||
} |
||||
|
||||
TEST_F(ChannelzServerTest, HighStartId) { |
||||
ResetStubs(); |
||||
ConfigureProxy(1); |
||||
GetTopChannelsRequest request; |
||||
GetTopChannelsResponse response; |
||||
request.set_start_channel_id(10000); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetTopChannels(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel_size(), 0); |
||||
} |
||||
|
||||
TEST_F(ChannelzServerTest, SuccessfulRequestTest) { |
||||
ResetStubs(); |
||||
ConfigureProxy(1); |
||||
SendSuccessfulEcho(0); |
||||
GetChannelRequest request; |
||||
GetChannelResponse response; |
||||
request.set_channel_id(1); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetChannel(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel().data().calls_started(), 1); |
||||
EXPECT_EQ(response.channel().data().calls_succeeded(), 1); |
||||
EXPECT_EQ(response.channel().data().calls_failed(), 0); |
||||
} |
||||
|
||||
TEST_F(ChannelzServerTest, FailedRequestTest) { |
||||
ResetStubs(); |
||||
ConfigureProxy(1); |
||||
SendFailedEcho(0); |
||||
GetChannelRequest request; |
||||
GetChannelResponse response; |
||||
request.set_channel_id(1); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetChannel(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel().data().calls_started(), 1); |
||||
EXPECT_EQ(response.channel().data().calls_succeeded(), 0); |
||||
EXPECT_EQ(response.channel().data().calls_failed(), 1); |
||||
} |
||||
|
||||
TEST_F(ChannelzServerTest, ManyRequestsTest) { |
||||
ResetStubs(); |
||||
ConfigureProxy(1); |
||||
// send some RPCs
|
||||
const int kNumSuccess = 10; |
||||
const int kNumFailed = 11; |
||||
for (int i = 0; i < kNumSuccess; ++i) { |
||||
SendSuccessfulEcho(0); |
||||
} |
||||
for (int i = 0; i < kNumFailed; ++i) { |
||||
SendFailedEcho(0); |
||||
} |
||||
GetChannelRequest request; |
||||
GetChannelResponse response; |
||||
request.set_channel_id(1); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetChannel(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel().data().calls_started(), |
||||
kNumSuccess + kNumFailed); |
||||
EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); |
||||
EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); |
||||
} |
||||
|
||||
TEST_F(ChannelzServerTest, ManyChannels) { |
||||
ResetStubs(); |
||||
const int kNumChannels = 4; |
||||
ConfigureProxy(kNumChannels); |
||||
GetTopChannelsRequest request; |
||||
GetTopChannelsResponse response; |
||||
request.set_start_channel_id(0); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetTopChannels(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel_size(), kNumChannels); |
||||
} |
||||
|
||||
TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { |
||||
ResetStubs(); |
||||
const int kNumChannels = 4; |
||||
ConfigureProxy(kNumChannels); |
||||
const int kNumSuccess = 10; |
||||
const int kNumFailed = 11; |
||||
for (int i = 0; i < kNumSuccess; ++i) { |
||||
SendSuccessfulEcho(0); |
||||
SendSuccessfulEcho(2); |
||||
} |
||||
for (int i = 0; i < kNumFailed; ++i) { |
||||
SendFailedEcho(1); |
||||
SendFailedEcho(2); |
||||
} |
||||
|
||||
// the first channel saw only successes
|
||||
{ |
||||
GetChannelRequest request; |
||||
GetChannelResponse response; |
||||
request.set_channel_id(1); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetChannel(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess); |
||||
EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); |
||||
EXPECT_EQ(response.channel().data().calls_failed(), 0); |
||||
} |
||||
|
||||
// the second channel saw only failures
|
||||
{ |
||||
GetChannelRequest request; |
||||
GetChannelResponse response; |
||||
request.set_channel_id(2); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetChannel(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel().data().calls_started(), kNumFailed); |
||||
EXPECT_EQ(response.channel().data().calls_succeeded(), 0); |
||||
EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); |
||||
} |
||||
|
||||
// the third channel saw both
|
||||
{ |
||||
GetChannelRequest request; |
||||
GetChannelResponse response; |
||||
request.set_channel_id(3); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetChannel(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel().data().calls_started(), |
||||
kNumSuccess + kNumFailed); |
||||
EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); |
||||
EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); |
||||
} |
||||
|
||||
// the fourth channel saw nothing
|
||||
{ |
||||
GetChannelRequest request; |
||||
GetChannelResponse response; |
||||
request.set_channel_id(4); |
||||
ClientContext context; |
||||
Status s = channelz_stub_->GetChannel(&context, request, &response); |
||||
EXPECT_TRUE(s.ok()); |
||||
EXPECT_EQ(response.channel().data().calls_started(), 0); |
||||
EXPECT_EQ(response.channel().data().calls_succeeded(), 0); |
||||
EXPECT_EQ(response.channel().data().calls_failed(), 0); |
||||
} |
||||
} |
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc_test_init(argc, argv); |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
@ -0,0 +1,45 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 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 "qps_server_builder.h" |
||||
|
||||
using grpc::ServerBuilder; |
||||
|
||||
namespace grpc { |
||||
namespace testing { |
||||
|
||||
namespace { |
||||
std::unique_ptr<ServerBuilder> DefaultCreateQpsServerBuilder() { |
||||
return std::unique_ptr<ServerBuilder>(new ServerBuilder()); |
||||
} |
||||
|
||||
std::function<std::unique_ptr<ServerBuilder>()> g_create_qps_server_builder = |
||||
DefaultCreateQpsServerBuilder; |
||||
} // namespace
|
||||
|
||||
std::unique_ptr<ServerBuilder> CreateQpsServerBuilder() { |
||||
return g_create_qps_server_builder(); |
||||
} |
||||
|
||||
void SetCreateQpsServerBuilderFunc( |
||||
std::function<std::unique_ptr<ServerBuilder>()> create_qps_server_builder) { |
||||
g_create_qps_server_builder = std::move(create_qps_server_builder); |
||||
} |
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
@ -0,0 +1,46 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_QPS_SERVER_BUILDER_H |
||||
#define GRPC_QPS_SERVER_BUILDER_H |
||||
|
||||
#include <functional> |
||||
#include <memory> |
||||
|
||||
#include <grpcpp/server_builder.h> |
||||
|
||||
namespace grpc { |
||||
namespace testing { |
||||
|
||||
// CreateQpsServerBuilder creates a new ServerBuilder.
|
||||
// This uses the "create ServerBuilder" func that was set
|
||||
// in SetCreateQpsServerBuilderFunc if one has been set,
|
||||
// otherwise, this defaults to creating a new ServerBuilder
|
||||
// with only its default constructor.
|
||||
std::unique_ptr<ServerBuilder> CreateQpsServerBuilder(); |
||||
|
||||
// SetCreateQpsServerBuilderFunc sets a function to use to create new
|
||||
// ServerBuilders in "CreateQpsServerBuilder". It can be used to modify options
|
||||
// that the server is built with.
|
||||
void SetCreateQpsServerBuilderFunc( |
||||
std::function<std::unique_ptr<ServerBuilder>()>); |
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_QPS_SERVER_BUILDER_H
|
@ -0,0 +1,26 @@ |
||||
# Copyright 2017 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. |
||||
|
||||
# Config file for the internal CI (in protobuf text format) |
||||
|
||||
# Location of the continuous shell script in repository. |
||||
build_file: "grpc/tools/internal_ci/linux/grpc_build_artifacts_extra.sh" |
||||
timeout_mins: 240 |
||||
action { |
||||
define_artifacts { |
||||
regex: "**/*sponge_log.xml" |
||||
regex: "github/grpc/reports/**" |
||||
regex: "github/grpc/artifacts/**" |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
404 Not Found |
@ -0,0 +1,114 @@ |
||||
<?xml version="1.0"?> |
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
||||
|
||||
<xsl:template match="//build"> |
||||
<html> |
||||
<head> |
||||
<title>Artifacts for gRPC Build <xsl:value-of select="@id"/> </title> |
||||
<link rel="stylesheet" type="text/css" href="/web-assets/style.css" /> |
||||
<link rel="apple-touch-icon" href="/web-assets/favicons/apple-touch-icon.png" sizes="180x180" /> |
||||
<link rel="icon" type="image/png" href="/web-assets/favicons/android-chrome-192x192.png" sizes="192x192" /> |
||||
<link rel="icon" type="image/png" href="/web-assets/favicons/favicon-32x32.png" sizes="32x32" /> |
||||
<link rel="icon" type="image/png" href="/web-assets/favicons/favicon-16x16.png" sizes="16x16" /> |
||||
<link rel="manifest" href="/web-assets/favicons/manifest.json" /> |
||||
<link rel="mask-icon" href="/web-assets/favicons/safari-pinned-tab.svg" color="#2DA6B0" /> |
||||
<meta name="msapplication-TileColor" content="#ffffff" /> |
||||
<meta name="msapplication-TileImage" content="/web-assets/favicons/mstile-150x150.png" /> |
||||
|
||||
<meta name="og:title" content="gRPC Package Build"/> |
||||
<meta name="og:image" content="https://grpc.io/img/grpc_square_reverse_4x.png"/> |
||||
<meta name="og:description" content="gRPC Package Build"/> |
||||
</head> |
||||
<body bgcolor="#ffffff"> |
||||
<div id="topbar"> |
||||
<span class="title">Artifacts for gRPC Build <xsl:value-of select="@id"/></span> |
||||
</div> |
||||
<div id="main"> |
||||
<div id="metadata"> |
||||
<span class="fieldname">Build: </span> <a href='#'><xsl:value-of select="@id"/></a> |
||||
[<a href="https://source.cloud.google.com/results/invocations/{@id}">invocation</a>]<br /> |
||||
<span class="fieldname">Timestamp: </span> |
||||
<xsl:value-of select="@timestamp"/> <br /> |
||||
<span class="fieldname">Branch: </span> |
||||
<a href="https://github.com/grpc/grpc/tree/{./metadata/branch[text()]}"> |
||||
<xsl:value-of select="./metadata/branch[text()]" /> |
||||
</a><br /> |
||||
<span class="fieldname">Commit: </span> |
||||
<a href="https://github.com/grpc/grpc/tree/{./metadata/commit[text()]}"> |
||||
<xsl:value-of select="./metadata/commit[text()]" /><br /></a> |
||||
</div> |
||||
<xsl:apply-templates select="artifacts" /> |
||||
<br /> |
||||
<br /> |
||||
|
||||
<p class="description"><a href="https://grpc.io">gRPC</a> is a <a href="https://www.cncf.io" class="external">Cloud Native Computing Foundation</a> project. <a href="https://policies.google.com/privacy" class="external">Privacy Policy</a>.</p> |
||||
<p class="description"> |
||||
Copyright © <xsl:value-of select="substring(@timestamp, 1, 4)" /> <a href="https://github.com/grpc/grpc/blob/{./metadata/commit[text()]}/AUTHORS">The gRPC Authors</a></p> |
||||
<br /> |
||||
<br /> |
||||
</div> |
||||
</body> |
||||
</html> |
||||
</xsl:template> |
||||
|
||||
<xsl:template match="artifacts"> |
||||
<h2> gRPC <code>protoc</code> Plugins </h2> |
||||
<table> |
||||
<xsl:apply-templates select="artifact[@type='protoc']"> |
||||
<xsl:sort select="artifact/@name" /> |
||||
</xsl:apply-templates> |
||||
</table> |
||||
|
||||
<h2> C# </h2> |
||||
<table> |
||||
<xsl:apply-templates select="artifact[@type='csharp']"> |
||||
<xsl:sort select="artifact/@name" /> |
||||
</xsl:apply-templates> |
||||
</table> |
||||
|
||||
<h2> PHP </h2> |
||||
<table> |
||||
<xsl:apply-templates select="artifact[@type='php']"> |
||||
<xsl:sort select="artifact/@name" /> |
||||
</xsl:apply-templates> |
||||
</table> |
||||
|
||||
<h2> Python </h2> |
||||
<script type="text/javascript"> |
||||
// <![CDATA[ |
||||
var pythonRepoLink = document.createElement("a"); |
||||
pythonRepoLink.href = './python'; |
||||
var pythonRepo = pythonRepoLink.href; |
||||
document.write("<p><code>" + |
||||
"$ pip install --pre --upgrade --force-reinstall --extra-index-url \\<br />" + |
||||
" <a href='" + pythonRepo + "'>" + pythonRepo + "</a> \\<br />" + |
||||
" grpcio grpcio-{tools,health-checking,reflection,testing}</code></p>"); |
||||
// ]]> |
||||
</script> |
||||
<table> |
||||
<xsl:apply-templates select="artifact[@type='python']"> |
||||
<xsl:sort select="artifact/@name" /> |
||||
</xsl:apply-templates> |
||||
</table> |
||||
|
||||
<h2> Ruby </h2> |
||||
<table> |
||||
<xsl:apply-templates select="artifact[@type='ruby']"> |
||||
<xsl:sort select="artifact/@name" /> |
||||
</xsl:apply-templates> |
||||
</table> |
||||
|
||||
</xsl:template> |
||||
|
||||
|
||||
<xsl:template match="artifact"> |
||||
<tr> |
||||
<td class="name"> <a href="{@path}"><xsl:value-of select="@name" /></a> </td> |
||||
<td class="hash"> <xsl:value-of select="@sha256"/> </td> |
||||
</tr> |
||||
</xsl:template> |
||||
|
||||
<xsl:template match="metadata"> |
||||
</xsl:template> |
||||
|
||||
</xsl:stylesheet> |
@ -0,0 +1,16 @@ |
||||
ul { |
||||
list-style-type: none; |
||||
} |
||||
a{ |
||||
text-decoration: none; |
||||
} |
||||
a:hover { |
||||
text-decoration: underline; |
||||
} |
||||
ul li a { |
||||
font-family: 'SF Mono', 'Menlo', 'Monaco', 'Consolas', 'Courier New', Courier, monospace |
||||
} |
||||
h1 { |
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif |
||||
} |
||||
|
@ -0,0 +1,86 @@ |
||||
<?xml version="1.0"?> |
||||
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
||||
|
||||
<xsl:template match="//packages"> |
||||
<html> |
||||
<head> |
||||
<title>gRPC Packages</title> |
||||
<link rel="stylesheet" type="text/css" href="/web-assets/style.css" /> |
||||
<link rel="apple-touch-icon" href="/web-assets/favicons/apple-touch-icon.png" sizes="180x180" /> |
||||
<link rel="icon" type="image/png" href="/web-assets/favicons/android-chrome-192x192.png" sizes="192x192" /> |
||||
<link rel="icon" type="image/png" href="/web-assets/favicons/favicon-32x32.png" sizes="32x32" /> |
||||
<link rel="icon" type="image/png" href="/web-assets/favicons/favicon-16x16.png" sizes="16x16" /> |
||||
<link rel="manifest" href="/web-assets/favicons/manifest.json" /> |
||||
<link rel="mask-icon" href="/web-assets/favicons/safari-pinned-tab.svg" color="#2DA6B0" /> |
||||
<meta name="msapplication-TileColor" content="#ffffff" /> |
||||
<meta name="msapplication-TileImage" content="/web-assets/favicons/mstile-150x150.png" /> |
||||
<meta name="og:title" content="gRPC Packages"/> |
||||
<meta name="og:image" content="https://grpc.io/img/grpc_square_reverse_4x.png"/> |
||||
<meta name="og:description" content="gRPC Packages"/> |
||||
</head> |
||||
<body bgcolor="#ffffff"> |
||||
<div id="topbar"> |
||||
<span class="title">gRPC Packages</span> |
||||
</div> |
||||
<div id="main"> |
||||
<xsl:apply-templates select="releases" /> |
||||
<xsl:apply-templates select="builds" /> |
||||
<br /> |
||||
<br /> |
||||
<p class="description"><a href="https://grpc.io">gRPC</a> is a <a href="https://www.cncf.io" class="external">Cloud Native Computing Foundation</a> project. <a href="https://policies.google.com/privacy" class="external">Privacy Policy</a>.</p> |
||||
<p class="description">Copyright © 2018 <a href="https://github.com/grpc/grpc/blob/master/AUTHORS">The gRPC Authors</a></p> |
||||
</div> |
||||
</body> |
||||
</html> |
||||
</xsl:template> |
||||
|
||||
<xsl:template match="releases"> |
||||
<h2>Official gRPC Releases</h2> |
||||
<p>Commits corresponding to <a href="https://github.com/grpc/grpc/releases">official gRPC release points and release candidates</a> are tagged on GitHub.</p> |
||||
<p>To maximize usability, gRPC supports the standard way of adding dependencies in your language of choice (if there is one). |
||||
In most languages, the gRPC runtime comes in form of a package available in your language's package manager.</p> |
||||
<p>For instructions on how to use the language-specific gRPC runtime in your project, please refer to the following:</p> |
||||
<ul> |
||||
<li><a href="https://github.com/grpc/grpc/blob/master/src/cpp">C++</a>: follow the instructions under the <a href="https://github.com/grpc/grpc/tree/master/src/cpp"><code>src/cpp</code> directory</a></li> |
||||
<li><a href="https://github.com/grpc/grpc/blob/master/src/csharp">C#</a>: NuGet package <code>Grpc</code></li> |
||||
<li><a href="https://github.com/grpc/grpc-dart">Dart</a>: pub package <code>grpc</code></li> |
||||
<li><a href="https://github.com/grpc/grpc-go">Go</a>: <code>go get google.golang.org/grpc</code></li> |
||||
<li><a href="https://github.com/grpc/grpc-java">Java</a>: Use JARs from <a href="https://mvnrepository.com/artifact/io.grpc">gRPC Maven Central Repository</a></li> |
||||
<li><a href="https://github.com/grpc/grpc-node">Node</a>: <code>npm install grpc</code></li> |
||||
<li><a href="https://github.com/grpc/grpc/blob/master/src/objective-c">Objective-C</a>: Add <code>gRPC-ProtoRPC</code> dependency to podspec</li> |
||||
<li><a href="https://github.com/grpc/grpc/blob/master/src/php">PHP</a>: <code>pecl install grpc</code></li> |
||||
<li><a href="https://github.com/grpc/grpc/blob/master/src/python/grpcio">Python</a>: <code>pip install grpcio</code></li> |
||||
<li><a href="https://github.com/grpc/grpc/blob/master/src/ruby">Ruby</a>: <code>gem install grpc</code></li> |
||||
<li><a href="https://github.com/grpc/grpc-web">WebJS</a>: follow the <a href="https://github.com/grpc/grpc-web">instructions in <code>grpc-web</code> repository</a></li> |
||||
</ul> |
||||
</xsl:template> |
||||
|
||||
<xsl:template match="builds"> |
||||
<h2> Daily Builds of <a href="https://github.com/grpc/grpc/tree/master"><code>master</code></a> Branch</h2> |
||||
<p>gRPC packages are built on a daily basis at the <code>HEAD</code> of <a href="https://github.com/grpc/grpc/tree/master">the <code>master</code> branch</a> and are archived here.</p> |
||||
<p> |
||||
<a href="#">The current document</a> (view source) is an XML feed pointing to the packages as they get built and uploaded. |
||||
You can subscribe to this feed and fetch, deploy, and test the precompiled packages with your continuous integration infrastructure. |
||||
</p> |
||||
<p>For stable release packages, please consult the above section and the common package manager for your language.</p> |
||||
<table style="border:solid black 1px"> |
||||
<tr style="background-color:lightgray"> |
||||
<td>Timestamp</td> |
||||
<td>Commit</td> |
||||
<td>Build ID</td> |
||||
</tr> |
||||
<xsl:apply-templates select="build[@branch='master']"> |
||||
<xsl:sort select="@timestamp" data-type="text" order="descending" /> |
||||
</xsl:apply-templates> |
||||
</table> |
||||
</xsl:template> |
||||
|
||||
<xsl:template match="build"> |
||||
<tr> |
||||
<td class="name"><xsl:value-of select="@timestamp" /></td> |
||||
<td class="name"> <a href="https://github.com/grpc/grpc/tree/{@commit}"><xsl:value-of select="@commit" /></a></td> |
||||
<td class="name"> <a href="{@path}"><xsl:value-of select="@id" /></a></td> |
||||
</tr> |
||||
</xsl:template> |
||||
|
||||
</xsl:stylesheet> |
@ -0,0 +1,76 @@ |
||||
html, body |
||||
{ |
||||
margin: 0; |
||||
font-family: sans-serif; |
||||
} |
||||
|
||||
a, a:visited, a:link, a:active { |
||||
color: #2da6b0; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
a:hover { |
||||
color: #2da6b0; |
||||
text-decoration: underline; |
||||
} |
||||
|
||||
#topbar { |
||||
background-color: #2da6b0; |
||||
height: 60px; |
||||
margin:auto; |
||||
} |
||||
|
||||
#topbar .title { |
||||
position: relative; |
||||
top: 24px; |
||||
left: 24px; |
||||
color: white; |
||||
font-family: sans-serif; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
#main { |
||||
max-width:1100px; |
||||
margin:auto; |
||||
} |
||||
|
||||
#main h2 { |
||||
text-align: left; |
||||
} |
||||
|
||||
#main table { |
||||
width:100%; |
||||
border-collapse: collapse; |
||||
font-size: small; |
||||
font-family: 'SF Mono', 'Menlo', 'Monaco', 'Courier New', Courier, monospace; |
||||
} |
||||
#main table tr td { |
||||
border: solid black 1px; |
||||
padding: 5px; |
||||
} |
||||
|
||||
#main table tr td.hash { |
||||
text-align: right; |
||||
border-left: none; |
||||
font-size: x-small; |
||||
} |
||||
|
||||
#main table tr td.name { |
||||
text-align: left; |
||||
border-right: none; |
||||
} |
||||
|
||||
p.description |
||||
{ |
||||
font-size: smaller; |
||||
} |
||||
|
||||
#metadata { |
||||
margin-top: 15px; |
||||
padding: 15px; |
||||
font-family: 'SF Mono', 'Menlo', 'Monaco', 'Courier New', Courier, monospace; |
||||
} |
||||
|
||||
#metadata span.fieldname { |
||||
font-family: sans-serif; |
||||
} |
@ -0,0 +1,30 @@ |
||||
#!/bin/bash |
||||
# Copyright 2018 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 -ex |
||||
|
||||
cd "$(dirname "$0")" |
||||
|
||||
GCS_WEB_ASSETS=gs://packages.grpc.io/web-assets/ |
||||
|
||||
WEB_ASSETS=( |
||||
404.html |
||||
build-201807.xsl |
||||
dirindex.css |
||||
home.xsl |
||||
style.css |
||||
) |
||||
|
||||
gsutil -m cp "${WEB_ASSETS[@]}" "$GCS_WEB_ASSETS" |
@ -0,0 +1,23 @@ |
||||
#!/bin/bash |
||||
# Copyright 2018 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 -ex |
||||
|
||||
cd "$(dirname "$0")/../../.." |
||||
|
||||
src/csharp/experimental/build_native_ext_for_ios.sh |
||||
|
||||
mkdir -p "${ARTIFACTS_OUT}" |
||||
cp libs/ios/libgrpc_csharp_ext.a libs/ios/libgrpc.a "${ARTIFACTS_OUT}" |
Loading…
Reference in new issue