blob: ca1b90f46a3b299fb9432941221e6aa615ca1d65 [file]
// Copyright 2021 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 "test/core/transport/binder/end2end/testing_channel_create.h"
#include <utility>
#include <grpcpp/security/binder_security_policy.h>
#include "src/core/ext/transport/binder/transport/binder_transport.h"
#include "src/core/ext/transport/binder/wire_format/wire_reader_impl.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_binder {
namespace end2end_testing {
namespace {
// Since we assume the first half of the transport setup is completed before the
// server side enters WireReader::SetupTransport, we need this helper to wait
// and finish that part of the negotiation for us.
class ServerSetupTransportHelper {
public:
ServerSetupTransportHelper()
: wire_reader_(absl::make_unique<WireReaderImpl>(
/*transport_stream_receiver=*/nullptr, /*is_client=*/false,
std::make_shared<
grpc::experimental::binder::UntrustedSecurityPolicy>())) {
std::tie(endpoint_binder_, tx_receiver_) = NewBinderPair(
[this](transaction_code_t tx_code, ReadableParcel* parcel, int uid) {
return this->wire_reader_->ProcessTransaction(tx_code, parcel, uid);
});
}
std::unique_ptr<Binder> WaitForClientBinder() {
return wire_reader_->RecvSetupTransport();
}
std::unique_ptr<Binder> GetEndpointBinderForClient() {
return std::move(endpoint_binder_);
}
private:
std::unique_ptr<WireReaderImpl> wire_reader_;
// The endpoint binder for client.
std::unique_ptr<Binder> endpoint_binder_;
std::unique_ptr<TransactionReceiver> tx_receiver_;
};
} // namespace
std::pair<grpc_transport*, grpc_transport*>
CreateClientServerBindersPairForTesting() {
ServerSetupTransportHelper helper;
std::unique_ptr<Binder> endpoint_binder = helper.GetEndpointBinderForClient();
grpc_transport* client_transport = nullptr;
struct ThreadArgs {
std::unique_ptr<Binder> endpoint_binder;
grpc_transport** client_transport;
} args;
args.endpoint_binder = std::move(endpoint_binder);
args.client_transport = &client_transport;
grpc_core::Thread client_thread(
"client-thread",
[](void* arg) {
ThreadArgs* args = static_cast<ThreadArgs*>(arg);
std::unique_ptr<Binder> endpoint_binder =
std::move(args->endpoint_binder);
*args->client_transport = grpc_create_binder_transport_client(
std::move(endpoint_binder),
std::make_shared<
grpc::experimental::binder::UntrustedSecurityPolicy>());
},
&args);
client_thread.Start();
grpc_transport* server_transport = grpc_create_binder_transport_server(
helper.WaitForClientBinder(),
std::make_shared<grpc::experimental::binder::UntrustedSecurityPolicy>());
client_thread.Join();
return std::make_pair(client_transport, server_transport);
}
std::shared_ptr<grpc::Channel> BinderChannelForTesting(
grpc::Server* server, const grpc::ChannelArguments& args) {
grpc_channel_args channel_args = args.c_channel_args();
return grpc::CreateChannelInternal(
"",
grpc_binder_channel_create_for_testing(server->c_server(), &channel_args,
nullptr),
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>());
}
} // namespace end2end_testing
} // namespace grpc_binder
grpc_channel* grpc_binder_channel_create_for_testing(
grpc_server* server, const grpc_channel_args* args, void* /*reserved*/) {
grpc_core::ExecCtx exec_ctx;
args = grpc_core::CoreConfiguration::Get()
.channel_args_preconditioning()
.PreconditionChannelArgs(args)
.ToC();
auto client_args = grpc_core::ChannelArgs::FromC(args).Set(
GRPC_ARG_DEFAULT_AUTHORITY, "test.authority");
grpc_transport *client_transport, *server_transport;
std::tie(client_transport, server_transport) =
grpc_binder::end2end_testing::CreateClientServerBindersPairForTesting();
grpc_error_handle error = grpc_core::Server::FromC(server)->SetupTransport(
server_transport, nullptr, args, nullptr);
GPR_ASSERT(GRPC_ERROR_IS_NONE(error));
auto channel = grpc_core::Channel::Create(
"binder", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport);
GPR_ASSERT(channel.ok());
grpc_channel_args_destroy(args);
return channel->release()->c_ptr();
}