• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <fcntl.h>
17 #include <gmock/gmock.h>
18 #include <hwext/gtest-ext.h>
19 #include <hwext/gtest-tag.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <vector>
23 
24 #include "plugin_manager.h"
25 #include "plugin_watcher.h"
26 
27 #include "logging.h"
28 
29 using namespace testing::ext;
30 
31 namespace {
32 constexpr int DEAFULT_FILE_MODE = 0777;
33 
34 #if defined(__i386__) || defined(__x86_64__)
35 const std::string DEFAULT_TEST_PATH = "./";
36 #else
37 const std::string DEFAULT_TEST_PATH_1 = "/data/local/tmp/watchertest/1/";
38 const std::string DEFAULT_TEST_PATH_2 = "/data/local/tmp/watchertest/2/";
39 const std::string DEFAULT_TEST_PATH_3 = "/data/local/tmp/watchertest/3/";
40 const std::string NO_EXIST_TEST_PATH = "/data/local/tmp/noexist/";
41 #endif
42 
43 class PluginWatchTest : public ::testing::Test {
44 protected:
45     static constexpr int TEMP_DELAY = 10 * 1000;
SetUpTestCase()46     static void SetUpTestCase() {}
TearDownTestCase()47     static void TearDownTestCase() {}
48 
SetUp()49     void SetUp() override
50     {
51         std::string cmd = "mkdir -p " + DEFAULT_TEST_PATH_1;
52         system(cmd.c_str());
53         cmd = "mkdir -p " + DEFAULT_TEST_PATH_2;
54         system(cmd.c_str());
55         cmd = "mkdir -p " + DEFAULT_TEST_PATH_3;
56         system(cmd.c_str());
57         sort(expectFileList.begin(), expectFileList.end());
58     }
59 
TearDown()60     void TearDown() override
61     {
62         cmpFileList.clear();
63     }
64 
OnPluginAddedStub(const std::string & path)65     void OnPluginAddedStub(const std::string& path)
66     {
67         cmpFileList.push_back(path);
68         sort(cmpFileList.begin(), cmpFileList.end());
69     }
70 
OnPluginRemovedStub(const std::string & path)71     void OnPluginRemovedStub(const std::string& path)
72     {
73         for (auto iter = cmpFileList.cbegin(); iter != cmpFileList.cend(); iter++) {
74             if (*iter == path) {
75                 cmpFileList.erase(iter);
76                 break;
77             }
78         }
79     }
80 
CreateFile(std::string dirPath) const81     void CreateFile(std::string dirPath) const
82     {
83         for (auto it : createFileList) {
84             int fd = creat((dirPath + it).c_str(), DEAFULT_FILE_MODE);
85             if (fd > 0) {
86                 close(fd);
87             }
88         }
89     }
90 
AddFile(std::string dirPath) const91     void AddFile(std::string dirPath) const
92     {
93         for (auto it : addFileList) {
94             int fd = creat((dirPath + it).c_str(), DEAFULT_FILE_MODE);
95             if (fd < 0) {
96                 return;
97             }
98             write(fd, "testcase", 1);
99             close(fd);
100         }
101     }
102 
DeleteFile(std::string dirPath) const103     void DeleteFile(std::string dirPath) const
104     {
105         for (auto it : createFileList) {
106             if (remove((dirPath + it).c_str()) != 0) {
107                 return;
108             }
109         }
110         for (auto it : addFileList) {
111             if (remove((dirPath + it).c_str()) != 0) {
112                 return;
113             }
114         }
115     }
116 
CheckFileList(std::string dirPath) const117     bool CheckFileList(std::string dirPath) const
118     {
119         if (cmpFileList.size() != expectFileList.size()) {
120             return false;
121         }
122 
123         for (size_t i = 0; i < cmpFileList.size(); i++) {
124             if (cmpFileList.at(i) != (dirPath + expectFileList.at(i))) {
125                 return false;
126             }
127         }
128 
129         return true;
130     }
131 
132 private:
133     std::vector<std::string> cmpFileList;
134 
135     const std::vector<std::string> createFileList = {
136         "lib_6.so", "lib_5.so", "lib_8.so", "lib_4.so", "test1.txt"
137     };
138 
139     const std::vector<std::string> addFileList = {
140         "libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so", "test2.txt"
141     };
142 
143     std::vector<std::string> expectFileList = {
144         "libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so",
145         "lib_6.so",    "lib_5.so",    "lib_8.so",    "lib_4.so"
146     };
147 };
148 
149 class MockPluginWatcher : public PluginWatcher {
150 public:
MockPluginWatcher(const PluginManagerPtr & pluginManager)151     explicit MockPluginWatcher(const PluginManagerPtr& pluginManager) : PluginWatcher(pluginManager) {}
152     ~MockPluginWatcher() = default;
153     MOCK_METHOD1(OnPluginAdded, void(const std::string&));
154     MOCK_METHOD1(OnPluginRemoved, void(const std::string&));
155 };
156 
157 /**
158  * @tc.name: plugin
159  * @tc.desc: Monitor single plugin dir.
160  * @tc.type: FUNC
161  */
162 HWTEST_F(PluginWatchTest, SingleWatchDirTest, TestSize.Level1)
163 {
164     auto pluginManage = std::make_shared<PluginManager>();
165     MockPluginWatcher watcher(pluginManage);
166 
167     EXPECT_CALL(watcher, OnPluginAdded(testing::_)).WillRepeatedly(
168         testing::Invoke(this, &PluginWatchTest::OnPluginAddedStub));
169     EXPECT_CALL(watcher, OnPluginRemoved(testing::_)).WillRepeatedly(
170         testing::Invoke(this, &PluginWatchTest::OnPluginRemovedStub));
171     CreateFile(DEFAULT_TEST_PATH_1);
172 
173     EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_1));
174     EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_1));
175     usleep(TEMP_DELAY);
176     AddFile(DEFAULT_TEST_PATH_1);
177     usleep(TEMP_DELAY);
178     EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_1), true);
179     DeleteFile(DEFAULT_TEST_PATH_1);
180     usleep(TEMP_DELAY);
181     EXPECT_EQ(cmpFileList.size(), 0);
182 }
183 
184 /**
185  * @tc.name: plugin
186  * @tc.desc: Monitor multi plugin dir.
187  * @tc.type: FUNC
188  */
189 HWTEST_F(PluginWatchTest, MultiWatchDirTest, TestSize.Level1)
190 {
191     auto pluginManage = std::make_shared<PluginManager>();
192     MockPluginWatcher watcher(pluginManage);
193 
194     EXPECT_CALL(watcher, OnPluginAdded(testing::_)).WillRepeatedly(
195         testing::Invoke(this, &PluginWatchTest::OnPluginAddedStub));
196     EXPECT_CALL(watcher, OnPluginRemoved(testing::_)).WillRepeatedly(
197         testing::Invoke(this, &PluginWatchTest::OnPluginRemovedStub));
198     CreateFile(DEFAULT_TEST_PATH_1);
199     EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_1));
200     EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_1));
201     usleep(TEMP_DELAY);
202     AddFile(DEFAULT_TEST_PATH_1);
203     usleep(TEMP_DELAY);
204     EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_1), true);
205     DeleteFile(DEFAULT_TEST_PATH_1);
206     usleep(TEMP_DELAY);
207     EXPECT_EQ(cmpFileList.size(), 0);
208 
209     CreateFile(DEFAULT_TEST_PATH_2);
210     EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_2));
211     EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_2));
212     usleep(TEMP_DELAY);
213     AddFile(DEFAULT_TEST_PATH_2);
214     usleep(TEMP_DELAY);
215     EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_2), true);
216     DeleteFile(DEFAULT_TEST_PATH_2);
217     usleep(TEMP_DELAY);
218     EXPECT_EQ(cmpFileList.size(), 0);
219 
220     CreateFile(DEFAULT_TEST_PATH_3);
221     EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_3));
222     EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_3));
223     usleep(TEMP_DELAY);
224     AddFile(DEFAULT_TEST_PATH_3);
225     usleep(TEMP_DELAY);
226     EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_3), true);
227     DeleteFile(DEFAULT_TEST_PATH_3);
228     usleep(TEMP_DELAY);
229     EXPECT_EQ(cmpFileList.size(), 0);
230 }
231 
232 /**
233  * @tc.name: plugin
234  * @tc.desc: Exception test.
235  * @tc.type: FUNC
236  */
237 HWTEST_F(PluginWatchTest, ExceptionTest, TestSize.Level1)
238 {
239     auto pluginManage = std::make_shared<PluginManager>();
240     MockPluginWatcher watcher(pluginManage);
241     EXPECT_FALSE(watcher.ScanPlugins(NO_EXIST_TEST_PATH));
242     EXPECT_FALSE(watcher.WatchPlugins(NO_EXIST_TEST_PATH));
243 }
244 } // namespace
245