1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h> 20*38e8c45fSAndroid Build Coastguard Worker 21*38e8c45fSAndroid Build Coastguard Worker #include "binderRpcTestCommon.h" 22*38e8c45fSAndroid Build Coastguard Worker 23*38e8c45fSAndroid Build Coastguard Worker #define EXPECT_OK(status) \ 24*38e8c45fSAndroid Build Coastguard Worker do { \ 25*38e8c45fSAndroid Build Coastguard Worker android::binder::Status stat = (status); \ 26*38e8c45fSAndroid Build Coastguard Worker EXPECT_TRUE(stat.isOk()) << stat; \ 27*38e8c45fSAndroid Build Coastguard Worker } while (false) 28*38e8c45fSAndroid Build Coastguard Worker 29*38e8c45fSAndroid Build Coastguard Worker namespace android { 30*38e8c45fSAndroid Build Coastguard Worker 31*38e8c45fSAndroid Build Coastguard Worker // Abstract base class with a virtual destructor that handles the 32*38e8c45fSAndroid Build Coastguard Worker // ownership of a process session for BinderRpcTestSession below 33*38e8c45fSAndroid Build Coastguard Worker class ProcessSession { 34*38e8c45fSAndroid Build Coastguard Worker public: 35*38e8c45fSAndroid Build Coastguard Worker struct SessionInfo { 36*38e8c45fSAndroid Build Coastguard Worker sp<RpcSession> session; 37*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> root; 38*38e8c45fSAndroid Build Coastguard Worker // Trusty defines its own socket APIs in trusty_ipc.h but doesn't include 39*38e8c45fSAndroid Build Coastguard Worker // sockaddr types. 40*38e8c45fSAndroid Build Coastguard Worker #ifndef __TRUSTY__ 41*38e8c45fSAndroid Build Coastguard Worker sockaddr_storage addr; 42*38e8c45fSAndroid Build Coastguard Worker socklen_t addrLen; 43*38e8c45fSAndroid Build Coastguard Worker #endif 44*38e8c45fSAndroid Build Coastguard Worker }; 45*38e8c45fSAndroid Build Coastguard Worker 46*38e8c45fSAndroid Build Coastguard Worker // client session objects associated with other process 47*38e8c45fSAndroid Build Coastguard Worker // each one represents a separate session 48*38e8c45fSAndroid Build Coastguard Worker std::vector<SessionInfo> sessions; 49*38e8c45fSAndroid Build Coastguard Worker 50*38e8c45fSAndroid Build Coastguard Worker virtual ~ProcessSession() = 0; 51*38e8c45fSAndroid Build Coastguard Worker 52*38e8c45fSAndroid Build Coastguard Worker // If the process exits with a status, run the given callback on that value. 53*38e8c45fSAndroid Build Coastguard Worker virtual void setCustomExitStatusCheck(std::function<void(int wstatus)> f) = 0; 54*38e8c45fSAndroid Build Coastguard Worker 55*38e8c45fSAndroid Build Coastguard Worker // Kill the process. Avoid if possible. Shutdown gracefully via an RPC instead. 56*38e8c45fSAndroid Build Coastguard Worker virtual void terminate() = 0; 57*38e8c45fSAndroid Build Coastguard Worker }; 58*38e8c45fSAndroid Build Coastguard Worker 59*38e8c45fSAndroid Build Coastguard Worker // Process session where the process hosts IBinderRpcTest, the server used 60*38e8c45fSAndroid Build Coastguard Worker // for most testing here 61*38e8c45fSAndroid Build Coastguard Worker struct BinderRpcTestProcessSession { 62*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<ProcessSession> proc; 63*38e8c45fSAndroid Build Coastguard Worker 64*38e8c45fSAndroid Build Coastguard Worker // pre-fetched root object (for first session) 65*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> rootBinder; 66*38e8c45fSAndroid Build Coastguard Worker 67*38e8c45fSAndroid Build Coastguard Worker // pre-casted root object (for first session) 68*38e8c45fSAndroid Build Coastguard Worker sp<IBinderRpcTest> rootIface; 69*38e8c45fSAndroid Build Coastguard Worker 70*38e8c45fSAndroid Build Coastguard Worker // whether session should be invalidated by end of run 71*38e8c45fSAndroid Build Coastguard Worker bool expectAlreadyShutdown = false; 72*38e8c45fSAndroid Build Coastguard Worker 73*38e8c45fSAndroid Build Coastguard Worker // TODO(b/271830568): fix this in binderRpcTest, we always use the first session to cause the 74*38e8c45fSAndroid Build Coastguard Worker // remote process to shutdown. Normally, when we shutdown, the default in the destructor is to 75*38e8c45fSAndroid Build Coastguard Worker // check that there are no leaks and shutdown. However, when there are incoming threadpools, 76*38e8c45fSAndroid Build Coastguard Worker // there will be a few extra binder threads there, so we can't shutdown the server. We should 77*38e8c45fSAndroid Build Coastguard Worker // consider an alternative way of doing the test so that we don't need this, some ideas, such as 78*38e8c45fSAndroid Build Coastguard Worker // program in understanding of incoming threadpool into the destructor so that (e.g. 79*38e8c45fSAndroid Build Coastguard Worker // intelligently wait for sessions to shutdown now that they will do this) forceShutdownBinderRpcTestProcessSession80*38e8c45fSAndroid Build Coastguard Worker void forceShutdown() { 81*38e8c45fSAndroid Build Coastguard Worker if (auto status = rootIface->scheduleShutdown(); !status.isOk()) { 82*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status; 83*38e8c45fSAndroid Build Coastguard Worker } 84*38e8c45fSAndroid Build Coastguard Worker EXPECT_TRUE(proc->sessions.at(0).session->shutdownAndWait(true)); 85*38e8c45fSAndroid Build Coastguard Worker expectAlreadyShutdown = true; 86*38e8c45fSAndroid Build Coastguard Worker } 87*38e8c45fSAndroid Build Coastguard Worker BinderRpcTestProcessSessionBinderRpcTestProcessSession88*38e8c45fSAndroid Build Coastguard Worker BinderRpcTestProcessSession(std::unique_ptr<ProcessSession> proc) : proc(std::move(proc)){}; 89*38e8c45fSAndroid Build Coastguard Worker BinderRpcTestProcessSession(BinderRpcTestProcessSession&&) = default; ~BinderRpcTestProcessSessionBinderRpcTestProcessSession90*38e8c45fSAndroid Build Coastguard Worker ~BinderRpcTestProcessSession() { 91*38e8c45fSAndroid Build Coastguard Worker if (!expectAlreadyShutdown) { 92*38e8c45fSAndroid Build Coastguard Worker EXPECT_NE(nullptr, rootIface); 93*38e8c45fSAndroid Build Coastguard Worker if (rootIface == nullptr) return; 94*38e8c45fSAndroid Build Coastguard Worker 95*38e8c45fSAndroid Build Coastguard Worker std::vector<int32_t> remoteCounts; 96*38e8c45fSAndroid Build Coastguard Worker // calling over any sessions counts across all sessions 97*38e8c45fSAndroid Build Coastguard Worker EXPECT_OK(rootIface->countBinders(&remoteCounts)); 98*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(remoteCounts.size(), proc->sessions.size()); 99*38e8c45fSAndroid Build Coastguard Worker for (auto remoteCount : remoteCounts) { 100*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(remoteCount, 1); 101*38e8c45fSAndroid Build Coastguard Worker } 102*38e8c45fSAndroid Build Coastguard Worker 103*38e8c45fSAndroid Build Coastguard Worker // even though it is on another thread, shutdown races with 104*38e8c45fSAndroid Build Coastguard Worker // the transaction reply being written 105*38e8c45fSAndroid Build Coastguard Worker if (auto status = rootIface->scheduleShutdown(); !status.isOk()) { 106*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status; 107*38e8c45fSAndroid Build Coastguard Worker } 108*38e8c45fSAndroid Build Coastguard Worker } 109*38e8c45fSAndroid Build Coastguard Worker 110*38e8c45fSAndroid Build Coastguard Worker rootIface = nullptr; 111*38e8c45fSAndroid Build Coastguard Worker rootBinder = nullptr; 112*38e8c45fSAndroid Build Coastguard Worker } 113*38e8c45fSAndroid Build Coastguard Worker }; 114*38e8c45fSAndroid Build Coastguard Worker 115*38e8c45fSAndroid Build Coastguard Worker struct BinderRpcParam { 116*38e8c45fSAndroid Build Coastguard Worker SocketType type; 117*38e8c45fSAndroid Build Coastguard Worker RpcSecurity security; 118*38e8c45fSAndroid Build Coastguard Worker uint32_t clientVersion; 119*38e8c45fSAndroid Build Coastguard Worker uint32_t serverVersion; 120*38e8c45fSAndroid Build Coastguard Worker bool singleThreaded; 121*38e8c45fSAndroid Build Coastguard Worker bool noKernel; 122*38e8c45fSAndroid Build Coastguard Worker }; 123*38e8c45fSAndroid Build Coastguard Worker class BinderRpc : public ::testing::TestWithParam<BinderRpcParam> { 124*38e8c45fSAndroid Build Coastguard Worker public: 125*38e8c45fSAndroid Build Coastguard Worker // TODO: avoid unnecessary layer of indirection socketType()126*38e8c45fSAndroid Build Coastguard Worker SocketType socketType() const { return GetParam().type; } rpcSecurity()127*38e8c45fSAndroid Build Coastguard Worker RpcSecurity rpcSecurity() const { return GetParam().security; } clientVersion()128*38e8c45fSAndroid Build Coastguard Worker uint32_t clientVersion() const { return GetParam().clientVersion; } serverVersion()129*38e8c45fSAndroid Build Coastguard Worker uint32_t serverVersion() const { return GetParam().serverVersion; } serverSingleThreaded()130*38e8c45fSAndroid Build Coastguard Worker bool serverSingleThreaded() const { return GetParam().singleThreaded; } noKernel()131*38e8c45fSAndroid Build Coastguard Worker bool noKernel() const { return GetParam().noKernel; } 132*38e8c45fSAndroid Build Coastguard Worker clientOrServerSingleThreaded()133*38e8c45fSAndroid Build Coastguard Worker bool clientOrServerSingleThreaded() const { 134*38e8c45fSAndroid Build Coastguard Worker return !kEnableRpcThreads || serverSingleThreaded(); 135*38e8c45fSAndroid Build Coastguard Worker } 136*38e8c45fSAndroid Build Coastguard Worker 137*38e8c45fSAndroid Build Coastguard Worker // Whether the test params support sending FDs in parcels. supportsFdTransport()138*38e8c45fSAndroid Build Coastguard Worker bool supportsFdTransport() const { 139*38e8c45fSAndroid Build Coastguard Worker if (socketType() == SocketType::TIPC) { 140*38e8c45fSAndroid Build Coastguard Worker // Trusty does not support file descriptors yet 141*38e8c45fSAndroid Build Coastguard Worker return false; 142*38e8c45fSAndroid Build Coastguard Worker } 143*38e8c45fSAndroid Build Coastguard Worker return clientVersion() >= 1 && serverVersion() >= 1 && rpcSecurity() != RpcSecurity::TLS && 144*38e8c45fSAndroid Build Coastguard Worker (socketType() == SocketType::PRECONNECTED || socketType() == SocketType::UNIX || 145*38e8c45fSAndroid Build Coastguard Worker socketType() == SocketType::UNIX_BOOTSTRAP || 146*38e8c45fSAndroid Build Coastguard Worker socketType() == SocketType::UNIX_RAW); 147*38e8c45fSAndroid Build Coastguard Worker } 148*38e8c45fSAndroid Build Coastguard Worker SetUp()149*38e8c45fSAndroid Build Coastguard Worker void SetUp() override { 150*38e8c45fSAndroid Build Coastguard Worker if (socketType() == SocketType::UNIX_BOOTSTRAP && rpcSecurity() == RpcSecurity::TLS) { 151*38e8c45fSAndroid Build Coastguard Worker GTEST_SKIP() << "Unix bootstrap not supported over a TLS transport"; 152*38e8c45fSAndroid Build Coastguard Worker } 153*38e8c45fSAndroid Build Coastguard Worker } 154*38e8c45fSAndroid Build Coastguard Worker createRpcTestSocketServerProcess(const BinderRpcOptions & options)155*38e8c45fSAndroid Build Coastguard Worker BinderRpcTestProcessSession createRpcTestSocketServerProcess(const BinderRpcOptions& options) { 156*38e8c45fSAndroid Build Coastguard Worker BinderRpcTestProcessSession ret(createRpcTestSocketServerProcessEtc(options)); 157*38e8c45fSAndroid Build Coastguard Worker 158*38e8c45fSAndroid Build Coastguard Worker ret.rootBinder = ret.proc->sessions.empty() ? nullptr : ret.proc->sessions.at(0).root; 159*38e8c45fSAndroid Build Coastguard Worker ret.rootIface = interface_cast<IBinderRpcTest>(ret.rootBinder); 160*38e8c45fSAndroid Build Coastguard Worker 161*38e8c45fSAndroid Build Coastguard Worker return ret; 162*38e8c45fSAndroid Build Coastguard Worker } 163*38e8c45fSAndroid Build Coastguard Worker PrintParamInfo(const testing::TestParamInfo<ParamType> & info)164*38e8c45fSAndroid Build Coastguard Worker static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) { 165*38e8c45fSAndroid Build Coastguard Worker auto ret = PrintToString(info.param.type) + "_" + 166*38e8c45fSAndroid Build Coastguard Worker newFactory(info.param.security)->toCString() + "_clientV" + 167*38e8c45fSAndroid Build Coastguard Worker std::to_string(info.param.clientVersion) + "_serverV" + 168*38e8c45fSAndroid Build Coastguard Worker std::to_string(info.param.serverVersion); 169*38e8c45fSAndroid Build Coastguard Worker if (info.param.singleThreaded) { 170*38e8c45fSAndroid Build Coastguard Worker ret += "_single_threaded"; 171*38e8c45fSAndroid Build Coastguard Worker } else { 172*38e8c45fSAndroid Build Coastguard Worker ret += "_multi_threaded"; 173*38e8c45fSAndroid Build Coastguard Worker } 174*38e8c45fSAndroid Build Coastguard Worker if (info.param.noKernel) { 175*38e8c45fSAndroid Build Coastguard Worker ret += "_no_kernel"; 176*38e8c45fSAndroid Build Coastguard Worker } else { 177*38e8c45fSAndroid Build Coastguard Worker ret += "_with_kernel"; 178*38e8c45fSAndroid Build Coastguard Worker } 179*38e8c45fSAndroid Build Coastguard Worker return ret; 180*38e8c45fSAndroid Build Coastguard Worker } 181*38e8c45fSAndroid Build Coastguard Worker 182*38e8c45fSAndroid Build Coastguard Worker protected: 183*38e8c45fSAndroid Build Coastguard Worker static std::unique_ptr<RpcTransportCtxFactory> newFactory(RpcSecurity rpcSecurity); 184*38e8c45fSAndroid Build Coastguard Worker 185*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<ProcessSession> createRpcTestSocketServerProcessEtc( 186*38e8c45fSAndroid Build Coastguard Worker const BinderRpcOptions& options); 187*38e8c45fSAndroid Build Coastguard Worker }; 188*38e8c45fSAndroid Build Coastguard Worker 189*38e8c45fSAndroid Build Coastguard Worker } // namespace android 190