106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci
1606f6ba60Sopenharmony_ci#include <fcntl.h>
1706f6ba60Sopenharmony_ci#include <gmock/gmock.h>
1806f6ba60Sopenharmony_ci#include <gtest/gtest.h>
1906f6ba60Sopenharmony_ci#include <sys/stat.h>
2006f6ba60Sopenharmony_ci#include <sys/types.h>
2106f6ba60Sopenharmony_ci#include <vector>
2206f6ba60Sopenharmony_ci
2306f6ba60Sopenharmony_ci#include "plugin_manager.h"
2406f6ba60Sopenharmony_ci#include "plugin_watcher.h"
2506f6ba60Sopenharmony_ci
2606f6ba60Sopenharmony_ci#include "logging.h"
2706f6ba60Sopenharmony_ci
2806f6ba60Sopenharmony_ciusing namespace testing::ext;
2906f6ba60Sopenharmony_ci
3006f6ba60Sopenharmony_cinamespace {
3106f6ba60Sopenharmony_ciconstexpr int DEAFULT_FILE_MODE = 0777;
3206f6ba60Sopenharmony_ci
3306f6ba60Sopenharmony_ci#if defined(__i386__) || defined(__x86_64__)
3406f6ba60Sopenharmony_ciconst std::string DEFAULT_TEST_PATH = "./";
3506f6ba60Sopenharmony_ci#else
3606f6ba60Sopenharmony_ciconst std::string DEFAULT_TEST_PATH_1 = "/data/local/tmp/watchertest/1/";
3706f6ba60Sopenharmony_ciconst std::string DEFAULT_TEST_PATH_2 = "/data/local/tmp/watchertest/2/";
3806f6ba60Sopenharmony_ciconst std::string DEFAULT_TEST_PATH_3 = "/data/local/tmp/watchertest/3/";
3906f6ba60Sopenharmony_ciconst std::string NO_EXIST_TEST_PATH = "/data/local/tmp/noexist/";
4006f6ba60Sopenharmony_ci#endif
4106f6ba60Sopenharmony_ci
4206f6ba60Sopenharmony_ciclass PluginWatchTest : public ::testing::Test {
4306f6ba60Sopenharmony_ciprotected:
4406f6ba60Sopenharmony_ci    static constexpr int TEMP_DELAY = 10 * 1000;
4506f6ba60Sopenharmony_ci    static void SetUpTestCase() {}
4606f6ba60Sopenharmony_ci    static void TearDownTestCase() {}
4706f6ba60Sopenharmony_ci
4806f6ba60Sopenharmony_ci    void SetUp() override
4906f6ba60Sopenharmony_ci    {
5006f6ba60Sopenharmony_ci        std::string cmd = "mkdir -p " + DEFAULT_TEST_PATH_1;
5106f6ba60Sopenharmony_ci        system(cmd.c_str());
5206f6ba60Sopenharmony_ci        cmd = "mkdir -p " + DEFAULT_TEST_PATH_2;
5306f6ba60Sopenharmony_ci        system(cmd.c_str());
5406f6ba60Sopenharmony_ci        cmd = "mkdir -p " + DEFAULT_TEST_PATH_3;
5506f6ba60Sopenharmony_ci        system(cmd.c_str());
5606f6ba60Sopenharmony_ci        sort(expectFileList.begin(), expectFileList.end());
5706f6ba60Sopenharmony_ci    }
5806f6ba60Sopenharmony_ci
5906f6ba60Sopenharmony_ci    void TearDown() override
6006f6ba60Sopenharmony_ci    {
6106f6ba60Sopenharmony_ci        cmpFileList.clear();
6206f6ba60Sopenharmony_ci    }
6306f6ba60Sopenharmony_ci
6406f6ba60Sopenharmony_ci    void OnPluginAddedStub(const std::string& path)
6506f6ba60Sopenharmony_ci    {
6606f6ba60Sopenharmony_ci        cmpFileList.push_back(path);
6706f6ba60Sopenharmony_ci        sort(cmpFileList.begin(), cmpFileList.end());
6806f6ba60Sopenharmony_ci    }
6906f6ba60Sopenharmony_ci
7006f6ba60Sopenharmony_ci    void OnPluginRemovedStub(const std::string& path)
7106f6ba60Sopenharmony_ci    {
7206f6ba60Sopenharmony_ci        for (auto iter = cmpFileList.cbegin(); iter != cmpFileList.cend(); iter++) {
7306f6ba60Sopenharmony_ci            if (*iter == path) {
7406f6ba60Sopenharmony_ci                cmpFileList.erase(iter);
7506f6ba60Sopenharmony_ci                break;
7606f6ba60Sopenharmony_ci            }
7706f6ba60Sopenharmony_ci        }
7806f6ba60Sopenharmony_ci    }
7906f6ba60Sopenharmony_ci
8006f6ba60Sopenharmony_ci    void CreateFile(std::string dirPath) const
8106f6ba60Sopenharmony_ci    {
8206f6ba60Sopenharmony_ci        for (auto it : createFileList) {
8306f6ba60Sopenharmony_ci            int fd = creat((dirPath + it).c_str(), DEAFULT_FILE_MODE);
8406f6ba60Sopenharmony_ci            if (fd > 0) {
8506f6ba60Sopenharmony_ci                close(fd);
8606f6ba60Sopenharmony_ci            }
8706f6ba60Sopenharmony_ci        }
8806f6ba60Sopenharmony_ci    }
8906f6ba60Sopenharmony_ci
9006f6ba60Sopenharmony_ci    void AddFile(std::string dirPath) const
9106f6ba60Sopenharmony_ci    {
9206f6ba60Sopenharmony_ci        for (auto it : addFileList) {
9306f6ba60Sopenharmony_ci            int fd = creat((dirPath + it).c_str(), DEAFULT_FILE_MODE);
9406f6ba60Sopenharmony_ci            if (fd < 0) {
9506f6ba60Sopenharmony_ci                return;
9606f6ba60Sopenharmony_ci            }
9706f6ba60Sopenharmony_ci            write(fd, "testcase", 1);
9806f6ba60Sopenharmony_ci            close(fd);
9906f6ba60Sopenharmony_ci        }
10006f6ba60Sopenharmony_ci    }
10106f6ba60Sopenharmony_ci
10206f6ba60Sopenharmony_ci    void DeleteFile(std::string dirPath) const
10306f6ba60Sopenharmony_ci    {
10406f6ba60Sopenharmony_ci        for (auto it : createFileList) {
10506f6ba60Sopenharmony_ci            if (remove((dirPath + it).c_str()) != 0) {
10606f6ba60Sopenharmony_ci                return;
10706f6ba60Sopenharmony_ci            }
10806f6ba60Sopenharmony_ci        }
10906f6ba60Sopenharmony_ci        for (auto it : addFileList) {
11006f6ba60Sopenharmony_ci            if (remove((dirPath + it).c_str()) != 0) {
11106f6ba60Sopenharmony_ci                return;
11206f6ba60Sopenharmony_ci            }
11306f6ba60Sopenharmony_ci        }
11406f6ba60Sopenharmony_ci    }
11506f6ba60Sopenharmony_ci
11606f6ba60Sopenharmony_ci    bool CheckFileList(std::string dirPath) const
11706f6ba60Sopenharmony_ci    {
11806f6ba60Sopenharmony_ci        if (cmpFileList.size() != expectFileList.size()) {
11906f6ba60Sopenharmony_ci            return false;
12006f6ba60Sopenharmony_ci        }
12106f6ba60Sopenharmony_ci
12206f6ba60Sopenharmony_ci        for (size_t i = 0; i < cmpFileList.size(); i++) {
12306f6ba60Sopenharmony_ci            if (cmpFileList.at(i) != (dirPath + expectFileList.at(i))) {
12406f6ba60Sopenharmony_ci                return false;
12506f6ba60Sopenharmony_ci            }
12606f6ba60Sopenharmony_ci        }
12706f6ba60Sopenharmony_ci
12806f6ba60Sopenharmony_ci        return true;
12906f6ba60Sopenharmony_ci    }
13006f6ba60Sopenharmony_ci
13106f6ba60Sopenharmony_ciprivate:
13206f6ba60Sopenharmony_ci    std::vector<std::string> cmpFileList;
13306f6ba60Sopenharmony_ci
13406f6ba60Sopenharmony_ci    const std::vector<std::string> createFileList = {
13506f6ba60Sopenharmony_ci        "lib_6.so", "lib_5.so", "lib_8.so", "lib_4.so", "test1.txt"
13606f6ba60Sopenharmony_ci    };
13706f6ba60Sopenharmony_ci
13806f6ba60Sopenharmony_ci    const std::vector<std::string> addFileList = {
13906f6ba60Sopenharmony_ci        "libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so", "test2.txt"
14006f6ba60Sopenharmony_ci    };
14106f6ba60Sopenharmony_ci
14206f6ba60Sopenharmony_ci    std::vector<std::string> expectFileList = {
14306f6ba60Sopenharmony_ci        "libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so",
14406f6ba60Sopenharmony_ci        "lib_6.so",    "lib_5.so",    "lib_8.so",    "lib_4.so"
14506f6ba60Sopenharmony_ci    };
14606f6ba60Sopenharmony_ci};
14706f6ba60Sopenharmony_ci
14806f6ba60Sopenharmony_ciclass MockPluginWatcher : public PluginWatcher {
14906f6ba60Sopenharmony_cipublic:
15006f6ba60Sopenharmony_ci    explicit MockPluginWatcher(const PluginManagerPtr& pluginManager) : PluginWatcher(pluginManager) {}
15106f6ba60Sopenharmony_ci    ~MockPluginWatcher() = default;
15206f6ba60Sopenharmony_ci    MOCK_METHOD1(OnPluginAdded, void(const std::string&));
15306f6ba60Sopenharmony_ci    MOCK_METHOD1(OnPluginRemoved, void(const std::string&));
15406f6ba60Sopenharmony_ci};
15506f6ba60Sopenharmony_ci
15606f6ba60Sopenharmony_ci/**
15706f6ba60Sopenharmony_ci * @tc.name: plugin
15806f6ba60Sopenharmony_ci * @tc.desc: Monitor single plugin dir.
15906f6ba60Sopenharmony_ci * @tc.type: FUNC
16006f6ba60Sopenharmony_ci */
16106f6ba60Sopenharmony_ciHWTEST_F(PluginWatchTest, SingleWatchDirTest, TestSize.Level1)
16206f6ba60Sopenharmony_ci{
16306f6ba60Sopenharmony_ci    auto pluginManage = std::make_shared<PluginManager>();
16406f6ba60Sopenharmony_ci    MockPluginWatcher watcher(pluginManage);
16506f6ba60Sopenharmony_ci
16606f6ba60Sopenharmony_ci    EXPECT_CALL(watcher, OnPluginAdded(testing::_)).WillRepeatedly(
16706f6ba60Sopenharmony_ci        testing::Invoke(this, &PluginWatchTest::OnPluginAddedStub));
16806f6ba60Sopenharmony_ci    EXPECT_CALL(watcher, OnPluginRemoved(testing::_)).WillRepeatedly(
16906f6ba60Sopenharmony_ci        testing::Invoke(this, &PluginWatchTest::OnPluginRemovedStub));
17006f6ba60Sopenharmony_ci    CreateFile(DEFAULT_TEST_PATH_1);
17106f6ba60Sopenharmony_ci
17206f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_1));
17306f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_1));
17406f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
17506f6ba60Sopenharmony_ci    AddFile(DEFAULT_TEST_PATH_1);
17606f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
17706f6ba60Sopenharmony_ci    EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_1), true);
17806f6ba60Sopenharmony_ci    DeleteFile(DEFAULT_TEST_PATH_1);
17906f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
18006f6ba60Sopenharmony_ci    EXPECT_EQ(cmpFileList.size(), 0);
18106f6ba60Sopenharmony_ci}
18206f6ba60Sopenharmony_ci
18306f6ba60Sopenharmony_ci/**
18406f6ba60Sopenharmony_ci * @tc.name: plugin
18506f6ba60Sopenharmony_ci * @tc.desc: Monitor multi plugin dir.
18606f6ba60Sopenharmony_ci * @tc.type: FUNC
18706f6ba60Sopenharmony_ci */
18806f6ba60Sopenharmony_ciHWTEST_F(PluginWatchTest, MultiWatchDirTest, TestSize.Level1)
18906f6ba60Sopenharmony_ci{
19006f6ba60Sopenharmony_ci    auto pluginManage = std::make_shared<PluginManager>();
19106f6ba60Sopenharmony_ci    MockPluginWatcher watcher(pluginManage);
19206f6ba60Sopenharmony_ci
19306f6ba60Sopenharmony_ci    EXPECT_CALL(watcher, OnPluginAdded(testing::_)).WillRepeatedly(
19406f6ba60Sopenharmony_ci        testing::Invoke(this, &PluginWatchTest::OnPluginAddedStub));
19506f6ba60Sopenharmony_ci    EXPECT_CALL(watcher, OnPluginRemoved(testing::_)).WillRepeatedly(
19606f6ba60Sopenharmony_ci        testing::Invoke(this, &PluginWatchTest::OnPluginRemovedStub));
19706f6ba60Sopenharmony_ci    CreateFile(DEFAULT_TEST_PATH_1);
19806f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_1));
19906f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_1));
20006f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
20106f6ba60Sopenharmony_ci    AddFile(DEFAULT_TEST_PATH_1);
20206f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
20306f6ba60Sopenharmony_ci    EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_1), true);
20406f6ba60Sopenharmony_ci    DeleteFile(DEFAULT_TEST_PATH_1);
20506f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
20606f6ba60Sopenharmony_ci    EXPECT_EQ(cmpFileList.size(), 0);
20706f6ba60Sopenharmony_ci
20806f6ba60Sopenharmony_ci    CreateFile(DEFAULT_TEST_PATH_2);
20906f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_2));
21006f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_2));
21106f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
21206f6ba60Sopenharmony_ci    AddFile(DEFAULT_TEST_PATH_2);
21306f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
21406f6ba60Sopenharmony_ci    EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_2), true);
21506f6ba60Sopenharmony_ci    DeleteFile(DEFAULT_TEST_PATH_2);
21606f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
21706f6ba60Sopenharmony_ci    EXPECT_EQ(cmpFileList.size(), 0);
21806f6ba60Sopenharmony_ci
21906f6ba60Sopenharmony_ci    CreateFile(DEFAULT_TEST_PATH_3);
22006f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_3));
22106f6ba60Sopenharmony_ci    EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_3));
22206f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
22306f6ba60Sopenharmony_ci    AddFile(DEFAULT_TEST_PATH_3);
22406f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
22506f6ba60Sopenharmony_ci    EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_3), true);
22606f6ba60Sopenharmony_ci    DeleteFile(DEFAULT_TEST_PATH_3);
22706f6ba60Sopenharmony_ci    usleep(TEMP_DELAY);
22806f6ba60Sopenharmony_ci    EXPECT_EQ(cmpFileList.size(), 0);
22906f6ba60Sopenharmony_ci}
23006f6ba60Sopenharmony_ci
23106f6ba60Sopenharmony_ci/**
23206f6ba60Sopenharmony_ci * @tc.name: plugin
23306f6ba60Sopenharmony_ci * @tc.desc: Exception test.
23406f6ba60Sopenharmony_ci * @tc.type: FUNC
23506f6ba60Sopenharmony_ci */
23606f6ba60Sopenharmony_ciHWTEST_F(PluginWatchTest, ExceptionTest, TestSize.Level1)
23706f6ba60Sopenharmony_ci{
23806f6ba60Sopenharmony_ci    auto pluginManage = std::make_shared<PluginManager>();
23906f6ba60Sopenharmony_ci    MockPluginWatcher watcher(pluginManage);
24006f6ba60Sopenharmony_ci    EXPECT_FALSE(watcher.ScanPlugins(NO_EXIST_TEST_PATH));
24106f6ba60Sopenharmony_ci    EXPECT_FALSE(watcher.WatchPlugins(NO_EXIST_TEST_PATH));
24206f6ba60Sopenharmony_ci}
24306f6ba60Sopenharmony_ci} // namespace
244