]>
Commit | Line | Data |
---|---|---|
f6b5b4d7 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "test/librbd/test_mock_fixture.h" | |
5 | #include "test/librbd/test_support.h" | |
6 | #include "include/rbd_types.h" | |
7 | #include "common/ceph_mutex.h" | |
8 | #include "librbd/ConfigWatcher.h" | |
9 | #include "gtest/gtest.h" | |
10 | #include "gmock/gmock.h" | |
11 | #include <list> | |
12 | ||
13 | namespace librbd { | |
14 | namespace { | |
15 | ||
16 | struct MockTestImageCtx : public MockImageCtx { | |
17 | MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) { | |
18 | } | |
19 | }; | |
20 | ||
21 | } // anonymous namespace | |
22 | } // namespace librbd | |
23 | ||
24 | #include "librbd/ConfigWatcher.cc" | |
25 | ||
26 | namespace librbd { | |
27 | ||
28 | using ::testing::Invoke; | |
29 | ||
30 | class TestMockConfigWatcher : public TestMockFixture { | |
31 | public: | |
32 | typedef ConfigWatcher<MockTestImageCtx> MockConfigWatcher; | |
33 | ||
34 | librbd::ImageCtx *m_image_ctx; | |
35 | ||
36 | ceph::mutex m_lock = ceph::make_mutex("m_lock"); | |
37 | ceph::condition_variable m_cv; | |
38 | bool m_refreshed = false; | |
39 | ||
40 | void SetUp() override { | |
41 | TestMockFixture::SetUp(); | |
42 | ||
43 | ASSERT_EQ(0, open_image(m_image_name, &m_image_ctx)); | |
44 | } | |
45 | ||
46 | void expect_update_notification(MockTestImageCtx& mock_image_ctx) { | |
47 | EXPECT_CALL(*mock_image_ctx.state, handle_update_notification()) | |
48 | .WillOnce(Invoke([this]() { | |
49 | std::unique_lock locker{m_lock}; | |
50 | m_refreshed = true; | |
51 | m_cv.notify_all(); | |
52 | })); | |
53 | } | |
54 | ||
55 | void wait_for_update_notification() { | |
56 | std::unique_lock locker{m_lock}; | |
57 | m_cv.wait(locker, [this] { | |
58 | if (m_refreshed) { | |
59 | m_refreshed = false; | |
60 | return true; | |
61 | } | |
62 | return false; | |
63 | }); | |
64 | } | |
65 | }; | |
66 | ||
67 | TEST_F(TestMockConfigWatcher, GlobalConfig) { | |
68 | MockTestImageCtx mock_image_ctx(*m_image_ctx); | |
69 | ||
70 | MockConfigWatcher mock_config_watcher(mock_image_ctx); | |
71 | mock_config_watcher.init(); | |
72 | ||
73 | expect_update_notification(mock_image_ctx); | |
74 | mock_image_ctx.cct->_conf.set_val("rbd_cache", "false"); | |
75 | mock_image_ctx.cct->_conf.set_val("rbd_cache", "true"); | |
76 | mock_image_ctx.cct->_conf.apply_changes(nullptr); | |
77 | wait_for_update_notification(); | |
78 | ||
79 | mock_config_watcher.shut_down(); | |
80 | } | |
81 | ||
82 | TEST_F(TestMockConfigWatcher, IgnoreOverriddenGlobalConfig) { | |
83 | MockTestImageCtx mock_image_ctx(*m_image_ctx); | |
84 | ||
85 | MockConfigWatcher mock_config_watcher(mock_image_ctx); | |
86 | mock_config_watcher.init(); | |
87 | ||
88 | EXPECT_CALL(*mock_image_ctx.state, handle_update_notification()) | |
89 | .Times(0); | |
90 | mock_image_ctx.config_overrides.insert("rbd_cache"); | |
91 | mock_image_ctx.cct->_conf.set_val("rbd_cache", "false"); | |
92 | mock_image_ctx.cct->_conf.set_val("rbd_cache", "true"); | |
93 | mock_image_ctx.cct->_conf.apply_changes(nullptr); | |
94 | ||
95 | mock_config_watcher.shut_down(); | |
96 | ||
97 | ASSERT_FALSE(m_refreshed); | |
98 | } | |
99 | ||
100 | } // namespace librbd |