Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / system / rados_watch_notify.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2011 New Dream Network
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation.  See file COPYING.
12 *
13 */
14
15 #include "cross_process_sem.h"
16 #include "include/rados/librados.h"
17 #include "st_rados_create_pool.h"
18 #include "st_rados_delete_pool.h"
19 #include "st_rados_delete_objs.h"
20 #include "st_rados_watch.h"
21 #include "st_rados_notify.h"
22 #include "systest_runnable.h"
23 #include "systest_settings.h"
24 #include "include/stringify.h"
25
26 #include <errno.h>
27 #include <pthread.h>
28 #include <semaphore.h>
29 #include <sstream>
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string>
34 #include <time.h>
35 #include <vector>
36 #include <sys/types.h>
37 #include <unistd.h>
38
39 using std::ostringstream;
40 using std::string;
41 using std::vector;
42
43 /*
44  * rados_watch_notify
45  *
46  * This tests watch/notify with pool and object deletion.
47  *
48  * EXPECT:            * notifies to a deleted object or pool are not received
49  *                    * notifies to existing objects are received
50  *
51  * DO NOT EXPECT      * hangs, crashes
52  */
53
54 const char *get_id_str()
55 {
56   return "main";
57 }
58
59 int main(int argc, const char **argv)
60 {
61   std::string pool = "foo." + stringify(getpid());
62   CrossProcessSem *setup_sem = NULL;
63   RETURN1_IF_NONZERO(CrossProcessSem::create(0, &setup_sem));
64   CrossProcessSem *watch_sem = NULL;
65   RETURN1_IF_NONZERO(CrossProcessSem::create(0, &watch_sem));
66   CrossProcessSem *notify_sem = NULL;
67   RETURN1_IF_NONZERO(CrossProcessSem::create(0, &notify_sem));
68
69   // create a pool and an object, watch the object, notify.
70   {
71     StRadosCreatePool r1(argc, argv, NULL, setup_sem, NULL, pool, 1, ".obj");
72     StRadosWatch r2(argc, argv, setup_sem, watch_sem, notify_sem,
73                     1, 0, pool, "0.obj");
74     StRadosNotify r3(argc, argv, setup_sem, watch_sem, notify_sem,
75                      0, pool, "0.obj");
76     StRadosDeletePool r4(argc, argv, notify_sem, NULL, pool);
77     vector<SysTestRunnable*> vec;
78     vec.push_back(&r1);
79     vec.push_back(&r2);
80     vec.push_back(&r3);
81     vec.push_back(&r4);
82     std::string error = SysTestRunnable::run_until_finished(vec);
83     if (!error.empty()) {
84       printf("test1: got error: %s\n", error.c_str());
85       return EXIT_FAILURE;
86     }
87   }
88
89   RETURN1_IF_NONZERO(setup_sem->reinit(0));
90   RETURN1_IF_NONZERO(watch_sem->reinit(0));
91   RETURN1_IF_NONZERO(notify_sem->reinit(0));
92
93   // create a pool and an object, watch a non-existent object,
94   // notify non-existent object.watch
95   pool += ".";
96   {
97     StRadosCreatePool r1(argc, argv, NULL, setup_sem, NULL, pool, 0, ".obj");
98     StRadosWatch r2(argc, argv, setup_sem, watch_sem, notify_sem,
99                     0, -ENOENT, pool, "0.obj");
100     StRadosNotify r3(argc, argv, setup_sem, watch_sem, notify_sem,
101                      -ENOENT, pool, "0.obj");
102     StRadosDeletePool r4(argc, argv, notify_sem, NULL, pool);
103     vector<SysTestRunnable*> vec;
104     vec.push_back(&r1);
105     vec.push_back(&r2);
106     vec.push_back(&r3);
107     vec.push_back(&r4);
108     std::string error = SysTestRunnable::run_until_finished(vec);
109     if (!error.empty()) {
110       printf("test2: got error: %s\n", error.c_str());
111       return EXIT_FAILURE;
112     }
113   }
114
115   RETURN1_IF_NONZERO(setup_sem->reinit(0));
116   RETURN1_IF_NONZERO(watch_sem->reinit(0));
117   RETURN1_IF_NONZERO(notify_sem->reinit(0));
118
119   CrossProcessSem *finished_notifies_sem = NULL;
120   RETURN1_IF_NONZERO(CrossProcessSem::create(0, &finished_notifies_sem));
121   CrossProcessSem *deleted_sem = NULL;
122   RETURN1_IF_NONZERO(CrossProcessSem::create(0, &deleted_sem));
123   CrossProcessSem *second_pool_sem = NULL;
124   RETURN1_IF_NONZERO(CrossProcessSem::create(0, &second_pool_sem));
125
126   // create a pool and an object, watch the object, notify,
127   // then delete the pool.
128   // Create a new pool and write to it to make the osd get the updated map,
129   // then try notifying on the deleted pool.
130   pool += ".";
131   {
132     StRadosCreatePool r1(argc, argv, NULL, setup_sem, NULL, pool, 1, ".obj");
133     StRadosWatch r2(argc, argv, setup_sem, watch_sem, finished_notifies_sem,
134                     1, 0, pool, "0.obj");
135     StRadosNotify r3(argc, argv, setup_sem, watch_sem, notify_sem,
136                      0, pool, "0.obj");
137     StRadosDeletePool r4(argc, argv, notify_sem, deleted_sem, pool);
138     StRadosCreatePool r5(argc, argv, deleted_sem, second_pool_sem, NULL,
139                          "bar", 1, ".obj");
140     StRadosNotify r6(argc, argv, second_pool_sem, NULL, finished_notifies_sem,
141                      0, "bar", "0.obj");
142     StRadosDeletePool r7(argc, argv, finished_notifies_sem, NULL, "bar");
143     vector<SysTestRunnable*> vec;
144     vec.push_back(&r1);
145     vec.push_back(&r2);
146     vec.push_back(&r3);
147     vec.push_back(&r4);
148     vec.push_back(&r5);
149     vec.push_back(&r6);
150     vec.push_back(&r7);
151     std::string error = SysTestRunnable::run_until_finished(vec);
152     if (!error.empty()) {
153       printf("test3: got error: %s\n", error.c_str());
154       return EXIT_FAILURE;
155     }
156   }
157
158   RETURN1_IF_NONZERO(setup_sem->reinit(0));
159   RETURN1_IF_NONZERO(watch_sem->reinit(0));
160   RETURN1_IF_NONZERO(notify_sem->reinit(0));
161   RETURN1_IF_NONZERO(finished_notifies_sem->reinit(0));
162   RETURN1_IF_NONZERO(deleted_sem->reinit(0));
163
164   // create a pool and an object, watch the object, notify,
165   // then delete the object, notify
166   // this test is enabled for the resolution of bug #2339.
167   pool += ".";
168   {
169     StRadosCreatePool r1(argc, argv, NULL, setup_sem, NULL, pool, 1, ".obj");
170     StRadosWatch r2(argc, argv, setup_sem, watch_sem, finished_notifies_sem,
171                     1, 0, pool, "0.obj");
172     StRadosNotify r3(argc, argv, setup_sem, watch_sem, notify_sem,
173                      0, pool, "0.obj");
174     StRadosDeleteObjs r4(argc, argv, notify_sem, deleted_sem, 1, pool, ".obj");
175     StRadosNotify r5(argc, argv, setup_sem, deleted_sem, finished_notifies_sem,
176                      -ENOENT, pool, "0.obj");
177     StRadosDeletePool r6(argc, argv, finished_notifies_sem, NULL, pool);
178
179     vector<SysTestRunnable*> vec;
180     vec.push_back(&r1);
181     vec.push_back(&r2);
182     vec.push_back(&r3);
183     vec.push_back(&r4);
184     vec.push_back(&r5);
185     vec.push_back(&r6);
186     std::string error = SysTestRunnable::run_until_finished(vec);
187     if (!error.empty()) {
188       printf("test4: got error: %s\n", error.c_str());
189       return EXIT_FAILURE;
190     }
191   }
192
193   printf("******* SUCCESS **********\n");
194   return EXIT_SUCCESS;
195 }