1 /*
2 * Copyright (C) 2021 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 #include <android-base/unique_fd.h>
18 #include <binder/IPCThreadState.h>
19 #include <gtest/gtest.h>
20 #include <poll.h>
21 #include <trusty/metrics/metrics.h>
22 #include <trusty/tipc.h>
23
24 #define TIPC_DEV "/dev/trusty-ipc-dev0"
25 #define CRASHER_PORT "com.android.trusty.metrics.test.crasher"
26
27 namespace android {
28 namespace trusty {
29 namespace metrics {
30
31 using android::base::unique_fd;
32
TriggerCrash()33 static void TriggerCrash() {
34 size_t num_retries = 3;
35 int fd = -1;
36
37 for (size_t i = 0; i < num_retries; i++) {
38 /* It's possible to time out waiting for crasher TA to restart. */
39 fd = tipc_connect(TIPC_DEV, CRASHER_PORT);
40 if (fd >= 0) {
41 break;
42 }
43 }
44
45 unique_fd crasher(fd);
46 ASSERT_GE(crasher, 0);
47
48 int msg = 0;
49 int rc = write(crasher, &msg, sizeof(msg));
50 ASSERT_EQ(rc, sizeof(msg));
51 }
52
53 class TrustyMetricsTest : public TrustyMetrics, public ::testing::Test {
54 public:
TrustyMetricsTest()55 TrustyMetricsTest() : TrustyMetrics(TIPC_DEV) {}
56
HandleCrash(const std::string & app_id)57 virtual void HandleCrash(const std::string& app_id) override { crashed_app_ = app_id; }
58
HandleEventDrop()59 virtual void HandleEventDrop() override { event_drop_count_++; }
60
SetUp()61 virtual void SetUp() override {
62 auto ret = Open();
63 ASSERT_TRUE(ret.ok()) << ret.error();
64 }
65
WaitForAndHandleEvent()66 void WaitForAndHandleEvent() {
67 auto ret = WaitForEvent(30000 /* 30 second timeout */);
68 ASSERT_TRUE(ret.ok()) << ret.error();
69
70 ret = HandleEvent();
71 ASSERT_TRUE(ret.ok()) << ret.error();
72 }
73
74 std::string crashed_app_;
75 size_t event_drop_count_;
76 };
77
TEST_F(TrustyMetricsTest,Crash)78 TEST_F(TrustyMetricsTest, Crash) {
79 TriggerCrash();
80 WaitForAndHandleEvent();
81
82 /* Check that correct TA crashed. */
83 ASSERT_EQ(crashed_app_, "36f5b435-5bd3-4526-8b76-200e3a7e79f3:crasher");
84 }
85
TEST_F(TrustyMetricsTest,PollSet)86 TEST_F(TrustyMetricsTest, PollSet) {
87 int binder_fd;
88 int rc = IPCThreadState::self()->setupPolling(&binder_fd);
89 ASSERT_EQ(rc, 0);
90 ASSERT_GE(binder_fd, 0);
91
92 TriggerCrash();
93
94 struct pollfd pfds[] = {
95 {
96 .fd = binder_fd,
97 .events = POLLIN,
98 },
99 {
100 .fd = GetRawFd(),
101 .events = POLLIN,
102 },
103 };
104
105 rc = poll(pfds, 2, 30000 /* 30 second timeout */);
106 /* We expect one event on the metrics fd. */
107 ASSERT_EQ(rc, 1);
108 ASSERT_TRUE(pfds[1].revents & POLLIN);
109
110 auto ret = HandleEvent();
111 ASSERT_TRUE(ret.ok()) << ret.error();
112
113 /* Check that correct TA crashed. */
114 ASSERT_EQ(crashed_app_, "36f5b435-5bd3-4526-8b76-200e3a7e79f3:crasher");
115 }
116
TEST_F(TrustyMetricsTest,EventDrop)117 TEST_F(TrustyMetricsTest, EventDrop) {
118 /* We know the size of the internal event queue is less than this. */
119 size_t num_events = 3;
120
121 ASSERT_EQ(event_drop_count_, 0);
122
123 for (auto i = 0; i < num_events; i++) {
124 TriggerCrash();
125 }
126
127 for (auto i = 0; i < num_events; i++) {
128 WaitForAndHandleEvent();
129 if (event_drop_count_ > 0) {
130 break;
131 }
132 }
133
134 ASSERT_EQ(event_drop_count_, 1);
135 }
136
137 } // namespace metrics
138 } // namespace trusty
139 } // namespace android
140