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