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 "SysfsMonitor.h"
18 
19 #include <gtest/gtest.h>
20 #include <utils/StrongPointer.h>
21 
22 #include <sys/socket.h>
23 
24 #include <vector>
25 
26 namespace android {
27 namespace automotive {
28 
29 class SysfsMonitorTest : public ::testing::Test {
30 public:
SetUp()31     void SetUp() override { mSysfsMonitor = sp<SysfsMonitor>::make(); }
TearDown()32     void TearDown() override { mSysfsMonitor = nullptr; }
33 
34 protected:
35     sp<SysfsMonitor> mSysfsMonitor;
36 };
37 
TEST_F(SysfsMonitorTest,TestDuplicateInitialize)38 TEST_F(SysfsMonitorTest, TestDuplicateInitialize) {
39     auto ret = mSysfsMonitor->init([](const std::vector<int32_t>&) {});
40     ASSERT_TRUE(ret.ok()) << "First initialization should be successful: " << ret.error().message();
41     ASSERT_FALSE(mSysfsMonitor->init([](const std::vector<int32_t>&) {}).ok())
42             << "Initialization cannot be done twice";
43 }
44 
TEST_F(SysfsMonitorTest,TestDuplicateRelease)45 TEST_F(SysfsMonitorTest, TestDuplicateRelease) {
46     auto ret = mSysfsMonitor->init([](const std::vector<int32_t>&) {});
47     ASSERT_TRUE(ret.ok()) << "First initialization should be successful: " << ret.error().message();
48     ret = mSysfsMonitor->release();
49     ASSERT_TRUE(ret.ok()) << "Releasing the initialized instance should be successful: "
50                           << ret.error().message();
51     ASSERT_FALSE(mSysfsMonitor->release().ok()) << "Released instance cannot be released";
52 }
53 
TEST_F(SysfsMonitorTest,TestNoInitRelease)54 TEST_F(SysfsMonitorTest, TestNoInitRelease) {
55     ASSERT_FALSE(mSysfsMonitor->release().ok()) << "Uninitailized instance cannot be released";
56 }
57 
TEST_F(SysfsMonitorTest,TestUnregisterNotRegisteredFd)58 TEST_F(SysfsMonitorTest, TestUnregisterNotRegisteredFd) {
59     // A regular file cannot be registered to epoll instance. So, the test is using a socket file.
60     int32_t fd = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
61     mSysfsMonitor->init([](const std::vector<int32_t>&) {});
62 
63     ASSERT_FALSE(mSysfsMonitor->unregisterFd(fd).ok())
64             << "Unregistered file description cannot be unregistered";
65     close(fd);
66 }
67 
TEST_F(SysfsMonitorTest,TestDuplicateRegister)68 TEST_F(SysfsMonitorTest, TestDuplicateRegister) {
69     int32_t fd = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
70     mSysfsMonitor->init([](const std::vector<int32_t>&) {});
71 
72     auto ret = mSysfsMonitor->registerFd(fd);
73     ASSERT_TRUE(ret.ok()) << "Registering a file descriptor first time should be successful: "
74                           << ret.error().message();
75     ASSERT_FALSE(mSysfsMonitor->registerFd(fd).ok())
76             << "Registering a file descriptor twice cannot be done";
77     close(fd);
78 }
79 
TEST_F(SysfsMonitorTest,TestDuplicateUnregister)80 TEST_F(SysfsMonitorTest, TestDuplicateUnregister) {
81     int32_t fd = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
82     mSysfsMonitor->init([](const std::vector<int32_t>&) {});
83 
84     auto ret = mSysfsMonitor->registerFd(fd);
85     ASSERT_TRUE(ret.ok()) << "Registering a file descriptor first time should be successful: "
86                           << ret.error().message();
87     ret = mSysfsMonitor->unregisterFd(fd);
88     ASSERT_TRUE(ret.ok()) << "The registered file descriptor should be unregistered: "
89                           << ret.error().message();
90     ASSERT_FALSE(mSysfsMonitor->unregisterFd(fd).ok())
91             << "Unregistering the unregistered file descriptor cannot be done";
92     close(fd);
93 }
94 
TEST_F(SysfsMonitorTest,TestRegisterInvalidFd)95 TEST_F(SysfsMonitorTest, TestRegisterInvalidFd) {
96     const int32_t invalidFd = -1;
97     ASSERT_FALSE(mSysfsMonitor->registerFd(invalidFd).ok())
98             << "fd(-1) cannot be registered to SysfsMonitor";
99 }
100 
TEST_F(SysfsMonitorTest,TestUnregisterInvalidFd)101 TEST_F(SysfsMonitorTest, TestUnregisterInvalidFd) {
102     const int32_t invalidFd = -1;
103     ASSERT_FALSE(mSysfsMonitor->unregisterFd(invalidFd).ok())
104             << "fd(-1) cannot be given to unregisterFd";
105 }
106 
TEST_F(SysfsMonitorTest,TestRegisterMultipleFds)107 TEST_F(SysfsMonitorTest, TestRegisterMultipleFds) {
108     const int32_t maxFdCount = 10;
109     int32_t fdsToMonitor[maxFdCount + 1];
110 
111     mSysfsMonitor->init([](const std::vector<int32_t>&) {});
112     for (int i = 0; i < maxFdCount; i++) {
113         fdsToMonitor[i] = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
114         auto ret = mSysfsMonitor->registerFd(fdsToMonitor[i]);
115         ASSERT_TRUE(ret.ok()) << "Registering a file descriptor first time should be successful: "
116                               << ret.error().message();
117     }
118     fdsToMonitor[maxFdCount] = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
119     ASSERT_FALSE(mSysfsMonitor->registerFd(fdsToMonitor[maxFdCount]).ok())
120             << "Registering more than " << maxFdCount << " files cannot be done";
121 
122     mSysfsMonitor->release();
123     for (int i = 0; i <= maxFdCount; i++) {
124         close(fdsToMonitor[i]);
125     }
126 }
127 
TEST_F(SysfsMonitorTest,TestObserveWithoutInitialization)128 TEST_F(SysfsMonitorTest, TestObserveWithoutInitialization) {
129     ASSERT_FALSE(mSysfsMonitor->observe().ok()) << "Uninitialized instance cannot observe";
130 }
131 
132 }  // namespace automotive
133 }  // namespace android
134