20
20
#include < gtest/gtest.h>
21
21
22
22
#include < thread>
23
+ #include < unordered_set>
23
24
24
25
#include " include/pulsar/Client.h"
25
26
#include " lib/LogUtils.h"
@@ -35,16 +36,36 @@ bool checkTime() {
35
36
const static auto start = std::chrono::high_resolution_clock::now ();
36
37
auto end = std::chrono::high_resolution_clock::now ();
37
38
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count ();
38
- return duration < 180 * 1000 ;
39
+ return duration < 300 * 1000 ;
39
40
}
40
41
41
42
TEST (ExtensibleLoadManagerTest, testPubSubWhileUnloading) {
42
- const static std::string adminUrl = " http://localhost:8080/" ;
43
- const static std::string topicName =
44
- " persistent://public/unload-test/topic-1" + std::to_string (time (NULL ));
43
+ const static std::string blueAdminUrl = " http://localhost:8080/" ;
44
+ const static std::string greenAdminUrl = " http://localhost:8081/" ;
45
+ const static std::string topicNameSuffix = std::to_string (time (NULL ));
46
+ const static std::string topicName = " persistent://public/unload-test/topic-" + topicNameSuffix;
45
47
46
48
ASSERT_TRUE (waitUntil (std::chrono::seconds (60 ), [&] {
47
- std::string url = adminUrl + " admin/v2/namespaces/public/unload-test?bundles=1" ;
49
+ std::string url = blueAdminUrl + " admin/v2/clusters/cluster-a/migrate?migrated=false" ;
50
+ int res = makePostRequest (url, R"(
51
+ {
52
+ "serviceUrl": "http://localhost:8081",
53
+ "serviceUrlTls":"https://localhost:8085",
54
+ "brokerServiceUrl": "pulsar://localhost:6651",
55
+ "brokerServiceUrlTls": "pulsar+ssl://localhost:6655"
56
+ })" );
57
+ LOG_INFO (" res:" << res);
58
+ return res == 200 ;
59
+ }));
60
+
61
+ ASSERT_TRUE (waitUntil (std::chrono::seconds (60 ), [&] {
62
+ std::string url = blueAdminUrl + " admin/v2/namespaces/public/unload-test?bundles=1" ;
63
+ int res = makePutRequest (url, " " );
64
+ return res == 204 || res == 409 ;
65
+ }));
66
+
67
+ ASSERT_TRUE (waitUntil (std::chrono::seconds (60 ), [&] {
68
+ std::string url = greenAdminUrl + " admin/v2/namespaces/public/unload-test?bundles=1" ;
48
69
int res = makePutRequest (url, " " );
49
70
return res == 204 || res == 409 ;
50
71
}));
@@ -58,24 +79,25 @@ TEST(ExtensibleLoadManagerTest, testPubSubWhileUnloading) {
58
79
Result consumerResult = client.subscribe (topicName, " sub" , consumer);
59
80
ASSERT_EQ (consumerResult, ResultOk);
60
81
61
- Semaphore firstUnloadSemaphore (0 );
62
- Semaphore secondUnloadSemaphore (0 );
63
- Semaphore halfPubWaitSemaphore (0 );
64
- const int msgCount = 10 ;
65
- int produced = 0 ;
82
+ Semaphore unloadSemaphore (0 );
83
+ Semaphore pubWaitSemaphore (0 );
84
+ Semaphore migrationSemaphore (0 );
85
+
86
+ const int msgCount = 20 ;
87
+ SynchronizedHashMap<int , int > producedMsgs;
66
88
auto produce = [&]() {
67
89
int i = 0 ;
68
90
while (i < msgCount && checkTime ()) {
69
- if (i == 3 ) {
70
- firstUnloadSemaphore .acquire ();
91
+ if (i == 3 || i == 8 || i == 17 ) {
92
+ unloadSemaphore .acquire ();
71
93
}
72
94
73
- if (i == 5 ) {
74
- halfPubWaitSemaphore .release ();
95
+ if (i == 5 || i == 15 ) {
96
+ pubWaitSemaphore .release ();
75
97
}
76
98
77
- if (i == 8 ) {
78
- secondUnloadSemaphore .acquire ();
99
+ if (i == 12 ) {
100
+ migrationSemaphore .acquire ();
79
101
}
80
102
81
103
std::string content = std::to_string (i);
@@ -86,45 +108,42 @@ TEST(ExtensibleLoadManagerTest, testPubSubWhileUnloading) {
86
108
return sendResult == ResultOk;
87
109
}));
88
110
89
- LOG_INFO (" produced index :" << i);
90
- produced++ ;
111
+ LOG_INFO (" produced i :" << i);
112
+ producedMsgs. emplace (i, i) ;
91
113
i++;
92
114
}
93
115
LOG_INFO (" producer finished" );
94
116
};
95
-
96
- int consumed = 0 ;
117
+ std::atomic< bool > stopConsumer ( false );
118
+ SynchronizedHashMap< int , int > consumedMsgs ;
97
119
auto consume = [&]() {
98
120
Message receivedMsg;
99
- int i = 0 ;
100
- while (i < msgCount && checkTime ()) {
101
- ASSERT_TRUE (waitUntil (std::chrono::seconds (60 ), [&] {
102
- Result receiveResult =
103
- consumer.receive (receivedMsg, 1000 ); // Assumed that we wait 1000 ms for each message
104
- return receiveResult == ResultOk;
105
- }));
106
- LOG_INFO (" received index:" << i);
107
-
108
- int id = std::stoi (receivedMsg.getDataAsString ());
109
- if (id < i) {
121
+ while (checkTime ()) {
122
+ if (stopConsumer && producedMsgs.size () == msgCount && consumedMsgs.size () == msgCount) {
123
+ break ;
124
+ }
125
+ Result receiveResult =
126
+ consumer.receive (receivedMsg, 1000 ); // Assumed that we wait 1000 ms for each message
127
+ if (receiveResult != ResultOk) {
110
128
continue ;
111
129
}
130
+ int i = std::stoi (receivedMsg.getDataAsString ());
131
+ LOG_INFO (" received i:" << i);
112
132
ASSERT_TRUE (waitUntil (std::chrono::seconds (60 ), [&] {
113
133
Result ackResult = consumer.acknowledge (receivedMsg);
114
134
return ackResult == ResultOk;
115
135
}));
116
- LOG_INFO (" acked index:" << i);
117
-
118
- consumed++;
119
- i++;
136
+ LOG_INFO (" acked i:" << i);
137
+ consumedMsgs.emplace (i, i);
120
138
}
121
139
LOG_INFO (" consumer finished" );
122
140
};
123
141
124
142
std::thread produceThread (produce);
125
143
std::thread consumeThread (consume);
126
144
127
- auto unload = [&] {
145
+ auto unload = [&](bool migrated) {
146
+ const std::string &adminUrl = migrated ? greenAdminUrl : blueAdminUrl;
128
147
auto clientImplPtr = PulsarFriend::getClientImplPtr (client);
129
148
auto &consumerImpl = PulsarFriend::getConsumerImpl (consumer);
130
149
auto &producerImpl = PulsarFriend::getProducerImpl (producer);
@@ -135,15 +154,17 @@ TEST(ExtensibleLoadManagerTest, testPubSubWhileUnloading) {
135
154
ASSERT_TRUE (waitUntil (std::chrono::seconds (30 ),
136
155
[&] { return consumerImpl.isConnected () && producerImpl.isConnected (); }));
137
156
138
- std::string url = adminUrl + " lookup/v2/topic/persistent/public/unload-test/topic-1" ;
157
+ std::string url =
158
+ adminUrl + " lookup/v2/topic/persistent/public/unload-test/topic" + topicNameSuffix;
139
159
std::string responseDataBeforeUnload;
140
160
int res = makeGetRequest (url, responseDataBeforeUnload);
141
161
if (res != 200 ) {
142
162
continue ;
143
163
}
144
- destinationBroker = responseDataBeforeUnload.find (" broker-2" ) == std::string::npos
145
- ? " broker-2:8080"
146
- : " broker-1:8080" ;
164
+ std::string prefix = migrated ? " green-" : " " ;
165
+ destinationBroker =
166
+ prefix + (responseDataBeforeUnload.find (" broker-2" ) == std::string::npos ? " broker-2:8080"
167
+ : " broker-1:8080" );
147
168
lookupCountBeforeUnload = clientImplPtr->getLookupCount ();
148
169
ASSERT_TRUE (lookupCountBeforeUnload > 0 );
149
170
@@ -163,31 +184,69 @@ TEST(ExtensibleLoadManagerTest, testPubSubWhileUnloading) {
163
184
[&] { return consumerImpl.isConnected () && producerImpl.isConnected (); }));
164
185
std::string responseDataAfterUnload;
165
186
ASSERT_TRUE (waitUntil (std::chrono::seconds (60 ), [&] {
166
- url = adminUrl + " lookup/v2/topic/persistent/public/unload-test/topic-1 " ;
187
+ url = adminUrl + " lookup/v2/topic/persistent/public/unload-test/topic" + topicNameSuffix ;
167
188
res = makeGetRequest (url, responseDataAfterUnload);
168
189
return res == 200 && responseDataAfterUnload.find (destinationBroker) != std::string::npos;
169
190
}));
170
191
LOG_INFO (" after lookup responseData:" << responseDataAfterUnload << " ,res:" << res);
171
192
172
193
auto lookupCountAfterUnload = clientImplPtr->getLookupCount ();
173
- ASSERT_EQ (lookupCountBeforeUnload, lookupCountAfterUnload);
194
+ if (lookupCountBeforeUnload != lookupCountAfterUnload) {
195
+ continue ;
196
+ }
174
197
break ;
175
198
}
176
199
};
177
- LOG_INFO (" starting first unload" );
178
- unload ();
179
- firstUnloadSemaphore .release ();
180
- halfPubWaitSemaphore .acquire ();
181
- LOG_INFO (" starting second unload" );
182
- unload ();
183
- secondUnloadSemaphore .release ();
200
+ LOG_INFO (" #### starting first unload #### " );
201
+ unload (false );
202
+ unloadSemaphore .release ();
203
+ pubWaitSemaphore .acquire ();
204
+ LOG_INFO (" #### starting second unload #### " );
205
+ unload (false );
206
+ unloadSemaphore .release ();
184
207
185
- produceThread.join ();
208
+ LOG_INFO (" #### migrating the cluster ####" );
209
+ migrationSemaphore.release ();
210
+ ASSERT_TRUE (waitUntil (std::chrono::seconds (60 ), [&] {
211
+ std::string url = blueAdminUrl + " admin/v2/clusters/cluster-a/migrate?migrated=true" ;
212
+ int res = makePostRequest (url, R"( {
213
+ "serviceUrl": "http://localhost:8081",
214
+ "serviceUrlTls":"https://localhost:8085",
215
+ "brokerServiceUrl": "pulsar://localhost:6651",
216
+ "brokerServiceUrlTls": "pulsar+ssl://localhost:6655"
217
+ })" );
218
+ LOG_INFO (" res:" << res);
219
+ return res == 200 ;
220
+ }));
221
+ ASSERT_TRUE (waitUntil (std::chrono::seconds (130 ), [&] {
222
+ auto &consumerImpl = PulsarFriend::getConsumerImpl (consumer);
223
+ auto &producerImpl = PulsarFriend::getProducerImpl (producer);
224
+ auto consumerConnAddress = PulsarFriend::getConnectionPhysicalAddress (consumerImpl);
225
+ auto producerConnAddress = PulsarFriend::getConnectionPhysicalAddress (producerImpl);
226
+ return consumerImpl.isConnected () && producerImpl.isConnected () &&
227
+ consumerConnAddress.find (" 6651" ) != std::string::npos &&
228
+ producerConnAddress.find (" 6651" ) != std::string::npos;
229
+ }));
230
+ pubWaitSemaphore.acquire ();
231
+ LOG_INFO (" #### starting third unload after migration ####" );
232
+ unload (true );
233
+ unloadSemaphore.release ();
234
+
235
+ stopConsumer = true ;
186
236
consumeThread.join ();
187
- ASSERT_EQ (consumed, msgCount);
188
- ASSERT_EQ (produced, msgCount);
189
- ASSERT_TRUE (checkTime ()) << " timed out" ;
237
+ produceThread.join ();
238
+ ASSERT_EQ (producedMsgs.size (), msgCount);
239
+ ASSERT_EQ (consumedMsgs.size (), msgCount);
240
+ for (int i = 0 ; i < msgCount; i++) {
241
+ producedMsgs.remove (i);
242
+ consumedMsgs.remove (i);
243
+ }
244
+ ASSERT_EQ (producedMsgs.size (), 0 );
245
+ ASSERT_EQ (consumedMsgs.size (), 0 );
246
+
190
247
client.close ();
248
+
249
+ ASSERT_TRUE (checkTime ()) << " timed out" ;
191
250
}
192
251
193
252
int main (int argc, char *argv[]) {
0 commit comments