]>
Commit | Line | Data |
---|---|---|
1 | #include "include/rados/librados.h" | |
2 | #include "include/rados/librados.hpp" | |
3 | #include "include/utime.h" | |
4 | #include "common/Thread.h" | |
5 | #include "common/Clock.h" | |
6 | #include "test/librados/test.h" | |
7 | ||
8 | #include "gtest/gtest.h" | |
9 | #include <semaphore.h> | |
10 | #include <errno.h> | |
11 | #include <map> | |
12 | #include <sstream> | |
13 | #include <iostream> | |
14 | #include <string> | |
15 | #include <atomic> | |
16 | ||
17 | #include "test/librados/TestCase.h" | |
18 | ||
19 | ||
20 | using namespace librados; | |
21 | using std::map; | |
22 | using std::ostringstream; | |
23 | using std::string; | |
24 | ||
25 | static sem_t *sem; | |
26 | static std::atomic<bool> stop_flag = { false }; | |
27 | ||
28 | class WatchNotifyTestCtx : public WatchCtx | |
29 | { | |
30 | public: | |
31 | void notify(uint8_t opcode, uint64_t ver, bufferlist& bl) override | |
32 | { | |
33 | sem_post(sem); | |
34 | } | |
35 | }; | |
36 | ||
37 | #pragma GCC diagnostic ignored "-Wpragmas" | |
38 | #pragma GCC diagnostic push | |
39 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
40 | ||
41 | struct WatcherUnwatcher : public Thread { | |
42 | string pool; | |
43 | explicit WatcherUnwatcher(string& _pool) : pool(_pool) {} | |
44 | ||
45 | void *entry() override { | |
46 | Rados cluster; | |
47 | connect_cluster_pp(cluster); | |
48 | while (!stop_flag) { | |
49 | IoCtx ioctx; | |
50 | cluster.ioctx_create(pool.c_str(), ioctx); | |
51 | ||
52 | uint64_t handle; | |
53 | WatchNotifyTestCtx watch_ctx; | |
54 | int r = ioctx.watch("foo", 0, &handle, &watch_ctx); | |
55 | if (r == 0) | |
56 | ioctx.unwatch("foo", handle); | |
57 | ioctx.close(); | |
58 | } | |
59 | return NULL; | |
60 | } | |
61 | }; | |
62 | ||
63 | typedef RadosTestParamPP WatchStress; | |
64 | ||
65 | INSTANTIATE_TEST_CASE_P(WatchStressTests, WatchStress, | |
66 | ::testing::Values("", "cache")); | |
67 | ||
68 | TEST_P(WatchStress, Stress1) { | |
69 | ASSERT_NE(SEM_FAILED, (sem = sem_open("test_stress_watch", O_CREAT, 0644, 0))); | |
70 | Rados ncluster; | |
71 | std::string pool_name = get_temp_pool_name(); | |
72 | ASSERT_EQ("", create_one_pool_pp(pool_name, ncluster)); | |
73 | IoCtx nioctx; | |
74 | ncluster.ioctx_create(pool_name.c_str(), nioctx); | |
75 | WatchNotifyTestCtx ctx; | |
76 | ||
77 | WatcherUnwatcher *thr = new WatcherUnwatcher(pool_name); | |
78 | thr->create("watcher_unwatch"); | |
79 | ASSERT_EQ(0, nioctx.create("foo", false)); | |
80 | ||
81 | for (unsigned i = 0; i < 75; ++i) { | |
82 | std::cerr << "Iteration " << i << std::endl; | |
83 | uint64_t handle; | |
84 | Rados cluster; | |
85 | IoCtx ioctx; | |
86 | WatchNotifyTestCtx ctx; | |
87 | ||
88 | connect_cluster_pp(cluster); | |
89 | cluster.ioctx_create(pool_name.c_str(), ioctx); | |
90 | ASSERT_EQ(0, ioctx.watch("foo", 0, &handle, &ctx)); | |
91 | ||
92 | bool do_blacklist = i % 2; | |
93 | if (do_blacklist) { | |
94 | cluster.test_blacklist_self(true); | |
95 | std::cerr << "blacklisted" << std::endl; | |
96 | sleep(1); | |
97 | } | |
98 | ||
99 | bufferlist bl2; | |
100 | ASSERT_EQ(0, nioctx.notify("foo", 0, bl2)); | |
101 | ||
102 | if (do_blacklist) { | |
103 | sleep(1); // Give a change to see an incorrect notify | |
104 | } else { | |
105 | TestAlarm alarm; | |
106 | sem_wait(sem); | |
107 | } | |
108 | ||
109 | if (do_blacklist) { | |
110 | cluster.test_blacklist_self(false); | |
111 | } | |
112 | ||
113 | ioctx.unwatch("foo", handle); | |
114 | ioctx.close(); | |
115 | } | |
116 | stop_flag = true; | |
117 | thr->join(); | |
118 | nioctx.close(); | |
119 | ASSERT_EQ(0, destroy_one_pool_pp(pool_name, ncluster)); | |
120 | sem_close(sem); | |
121 | } | |
122 | ||
123 | #pragma GCC diagnostic pop | |
124 | #pragma GCC diagnostic warning "-Wpragmas" |