blob: c99d68aacf5c41d581644e8362c5c9d67e190944 [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 {
Andrei Homescu68a55612022-08-02 01:25:15 +0000109 if (socketType() == SocketType::TIPC) {
110 // Trusty does not support file descriptors yet
111 return false;
112 }
Andrei Homescu96834632022-10-14 00:49:49 +0000113 return clientVersion() >= 1 && serverVersion() >= 1 && rpcSecurity() != RpcSecurity::TLS &&
114 (socketType() == SocketType::PRECONNECTED || socketType() == SocketType::UNIX ||
Alice Wang893a9912022-10-24 10:44:09 +0000115 socketType() == SocketType::UNIX_BOOTSTRAP ||
116 socketType() == SocketType::UNIX_RAW);
Andrei Homescu96834632022-10-14 00:49:49 +0000117 }
118
119 void SetUp() override {
120 if (socketType() == SocketType::UNIX_BOOTSTRAP && rpcSecurity() == RpcSecurity::TLS) {
121 GTEST_SKIP() << "Unix bootstrap not supported over a TLS transport";
122 }
123 }
124
125 BinderRpcTestProcessSession createRpcTestSocketServerProcess(const BinderRpcOptions& options) {
126 BinderRpcTestProcessSession ret{
127 .proc = createRpcTestSocketServerProcessEtc(options),
128 };
129
130 ret.rootBinder = ret.proc->sessions.empty() ? nullptr : ret.proc->sessions.at(0).root;
131 ret.rootIface = interface_cast<IBinderRpcTest>(ret.rootBinder);
132
133 return ret;
134 }
135
136 static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info);
137
138protected:
139 std::unique_ptr<ProcessSession> createRpcTestSocketServerProcessEtc(
140 const BinderRpcOptions& options);
141};
142
143} // namespace android