Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / test_stress_watch.cc
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"