blob: 721fbfe1e13a9efa23b4885a0c28897f28031e04 [file] [log] [blame]
Andrei Homescu96834632022-10-14 00:49:49 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <gtest/gtest.h>
20
21#include "binderRpcTestCommon.h"
22
23#define EXPECT_OK(status) \
24 do { \
25 android::binder::Status stat = (status); \
26 EXPECT_TRUE(stat.isOk()) << stat; \
27 } while (false)
28
29namespace android {
30
31// Abstract base class with a virtual destructor that handles the
32// ownership of a process session for BinderRpcTestSession below
33class ProcessSession {
34public:
35 struct SessionInfo {
36 sp<RpcSession> session;
37 sp<IBinder> root;
38 };
39
40 // client session objects associated with other process
41 // each one represents a separate session
42 std::vector<SessionInfo> sessions;
43
44 virtual ~ProcessSession() = 0;
45
46 // If the process exits with a status, run the given callback on that value.
47 virtual void setCustomExitStatusCheck(std::function<void(int wstatus)> f) = 0;
48
49 // Kill the process. Avoid if possible. Shutdown gracefully via an RPC instead.
50 virtual void terminate() = 0;
51};
52
53// Process session where the process hosts IBinderRpcTest, the server used
54// for most testing here
55struct BinderRpcTestProcessSession {
56 std::unique_ptr<ProcessSession> proc;
57
58 // pre-fetched root object (for first session)
59 sp<IBinder> rootBinder;
60
61 // pre-casted root object (for first session)
62 sp<IBinderRpcTest> rootIface;
63
64 // whether session should be invalidated by end of run
65 bool expectAlreadyShutdown = false;
66
67 BinderRpcTestProcessSession(BinderRpcTestProcessSession&&) = default;
68 ~BinderRpcTestProcessSession() {
69 if (!expectAlreadyShutdown) {
70 EXPECT_NE(nullptr, rootIface);
71 if (rootIface == nullptr) return;
72
73 std::vector<int32_t> remoteCounts;
74 // calling over any sessions counts across all sessions
75 EXPECT_OK(rootIface->countBinders(&remoteCounts));
76 EXPECT_EQ(remoteCounts.size(), proc->sessions.size());
77 for (auto remoteCount : remoteCounts) {
78 EXPECT_EQ(remoteCount, 1);
79 }
80
81 // even though it is on another thread, shutdown races with
82 // the transaction reply being written
83 if (auto status = rootIface->scheduleShutdown(); !status.isOk()) {
84 EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
85 }
86 }
87
88 rootIface = nullptr;
89 rootBinder = nullptr;
90 }
91};
92
93class BinderRpc : public ::testing::TestWithParam<
94 std::tuple<SocketType, RpcSecurity, uint32_t, uint32_t, bool, bool>> {
95public:
96 SocketType socketType() const { return std::get<0>(GetParam()); }
97 RpcSecurity rpcSecurity() const { return std::get<1>(GetParam()); }
98 uint32_t clientVersion() const { return std::get<2>(GetParam()); }
99 uint32_t serverVersion() const { return std::get<3>(GetParam()); }
100 bool serverSingleThreaded() const { return std::get<4>(GetParam()); }
101 bool noKernel() const { return std::get<5>(GetParam()); }
102
103 bool clientOrServerSingleThreaded() const {
104 return !kEnableRpcThreads || serverSingleThreaded();
105 }
106
107 // Whether the test params support sending FDs in parcels.
108 bool supportsFdTransport() const {
109 return clientVersion() >= 1 && serverVersion() >= 1 && rpcSecurity() != RpcSecurity::TLS &&
110 (socketType() == SocketType::PRECONNECTED || socketType() == SocketType::UNIX ||
111 socketType() == SocketType::UNIX_BOOTSTRAP);
112 }
113
114 void SetUp() override {
115 if (socketType() == SocketType::UNIX_BOOTSTRAP && rpcSecurity() == RpcSecurity::TLS) {
116 GTEST_SKIP() << "Unix bootstrap not supported over a TLS transport";
117 }
118 }
119
120 BinderRpcTestProcessSession createRpcTestSocketServerProcess(const BinderRpcOptions& options) {
121 BinderRpcTestProcessSession ret{
122 .proc = createRpcTestSocketServerProcessEtc(options),
123 };
124
125 ret.rootBinder = ret.proc->sessions.empty() ? nullptr : ret.proc->sessions.at(0).root;
126 ret.rootIface = interface_cast<IBinderRpcTest>(ret.rootBinder);
127
128 return ret;
129 }
130
131 static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info);
132
133protected:
134 std::unique_ptr<ProcessSession> createRpcTestSocketServerProcessEtc(
135 const BinderRpcOptions& options);
136};
137
138} // namespace android