Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

722 Zeilen
26 KiB

  1. #include <gtest/gtest.h>
  2. #include <cppamqp.h>
  3. #include "mock.h"
  4. using namespace ::testing;
  5. using namespace ::cppamqp;
  6. using StrictAmqpMock = StrictMock<AmqpMock>;
  7. amqp_envelope_t DefaultEnvelope {
  8. /* .channel */ 3,
  9. /* .consumer_tag */ { 15, const_cast<char*>("my_consumer_tag") },
  10. /* .delivery_tag */ 12345678,
  11. /* .redelivered */ true,
  12. /* .exchange */ { 11, const_cast<char*>("my_exchange") },
  13. /* .routing_key */ { 14, const_cast<char*>("my_routing_key") },
  14. /* .message */ {
  15. /* .properties */ {
  16. /* ._flags */ 0,
  17. /* .content_type */ { 0, nullptr },
  18. /* .content_encoding */ { 0, nullptr },
  19. /* .headers */ { 0, nullptr },
  20. /* .delivery_mode */ 0,
  21. /* .priority */ 0,
  22. /* .correlation_id */ { 0, nullptr },
  23. /* .reply_to */ { 0, nullptr },
  24. /* .expiration */ { 0, nullptr },
  25. /* .message_id */ { 0, nullptr },
  26. /* .timestamp */ 0,
  27. /* .type */ { 0, nullptr },
  28. /* .user_id */ { 0, nullptr },
  29. /* .app_id */ { 0, nullptr },
  30. /* .cluster_id */ { 0, nullptr },
  31. },
  32. /* .body */ { 19, const_cast<char*>("this_is_the_message") },
  33. /* .pool */ {
  34. /* .pagesize */ 0,
  35. /* .pages */ { 0, nullptr },
  36. /* .large_blocks */ { 0, nullptr },
  37. /* .next_page */ 0,
  38. /* .alloc_block */ nullptr,
  39. /* .alloc_used */ 0
  40. }
  41. }
  42. };
  43. bool operator ==(const timeval& a, const timeval& b)
  44. { return a.tv_sec == b.tv_sec && a.tv_usec == b.tv_usec; }
  45. MATCHER_P(BytesEq, data, "")
  46. {
  47. if ( data == nullptr
  48. && arg.len == 0)
  49. return true;
  50. std::string d(data);
  51. return arg.len == d.size()
  52. && memcmp(arg.bytes, d.data(), arg.len) == 0;
  53. }
  54. TEST(AmqpTest, Connection_connect_newConnectionFailed)
  55. {
  56. StrictAmqpMock mock;
  57. InSequence seq;
  58. EXPECT_CALL(mock, amqp_new_connection())
  59. .WillOnce(Return(nullptr));
  60. connection con;
  61. EXPECT_THROW(con.tcp_connect("localhost", 1234), cppamqp::exception);
  62. }
  63. TEST(AmqpTest, Connection_connect_newSocketFailed)
  64. {
  65. StrictAmqpMock mock;
  66. InSequence seq;
  67. EXPECT_CALL(mock, amqp_new_connection())
  68. .WillOnce(Return(reinterpret_cast<amqp_connection_state_t>(1)));
  69. EXPECT_CALL(mock, amqp_tcp_socket_new(reinterpret_cast<amqp_connection_state_t>(1)))
  70. .WillOnce(Return(nullptr));
  71. EXPECT_CALL(mock, amqp_destroy_connection(reinterpret_cast<amqp_connection_state_t>(1)))
  72. .WillOnce(Return(0));
  73. connection con;
  74. EXPECT_THROW(con.tcp_connect("localhost", 1234), cppamqp::exception);
  75. }
  76. TEST(AmqpTest, Connection_connect_openSocketFailed)
  77. {
  78. StrictAmqpMock mock;
  79. InSequence seq;
  80. EXPECT_CALL(mock, amqp_new_connection())
  81. .WillOnce(Return(reinterpret_cast<amqp_connection_state_t>(1)));
  82. EXPECT_CALL(mock, amqp_tcp_socket_new(reinterpret_cast<amqp_connection_state_t>(1)))
  83. .WillOnce(Return(reinterpret_cast<amqp_socket_t*>(2)));
  84. EXPECT_CALL(mock, amqp_socket_open(reinterpret_cast<amqp_socket_t*>(2), StrEq("localhost"), 1234))
  85. .WillOnce(Return(666));
  86. EXPECT_CALL(mock, amqp_error_string2(666))
  87. .WillOnce(Return("error from hell >:D"));
  88. EXPECT_CALL(mock, amqp_destroy_connection(reinterpret_cast<amqp_connection_state_t>(1)))
  89. .WillOnce(Return(0));
  90. connection con;
  91. EXPECT_THROW(con.tcp_connect("localhost", 1234), cppamqp::exception);
  92. }
  93. TEST(AmqpTest, Connection_connect_success)
  94. {
  95. StrictAmqpMock mock;
  96. InSequence seq;
  97. EXPECT_CALL(mock, amqp_new_connection())
  98. .WillOnce(Return(reinterpret_cast<amqp_connection_state_t>(1)));
  99. EXPECT_CALL(mock, amqp_tcp_socket_new(reinterpret_cast<amqp_connection_state_t>(1)))
  100. .WillOnce(Return(reinterpret_cast<amqp_socket_t*>(2)));
  101. EXPECT_CALL(mock, amqp_socket_open(reinterpret_cast<amqp_socket_t*>(2), StrEq("localhost"), 1234))
  102. .WillOnce(Return(0));
  103. EXPECT_CALL(mock, amqp_connection_close(reinterpret_cast<amqp_connection_state_t>(1), 200))
  104. .WillOnce(Return(AmqpMock::defaultRpcReply));
  105. EXPECT_CALL(mock, amqp_destroy_connection(reinterpret_cast<amqp_connection_state_t>(1)))
  106. .WillOnce(Return(0));
  107. connection con;
  108. EXPECT_NO_THROW(con.tcp_connect("localhost", 1234));
  109. }
  110. TEST(AmqpTest, Connection_loginPlain_failed)
  111. {
  112. connection con;
  113. con.tcp_connect("localhost", 1234);
  114. StrictAmqpMock mock;
  115. InSequence seq;
  116. EXPECT_CALL(mock, amqp_login_plain(AmqpMock::defaultConnectionState, StrEq("vhost"), 200, 131072, 100, AMQP_SASL_METHOD_PLAIN, StrEq("username"), StrEq("password")))
  117. .WillOnce(Return(amqp_rpc_reply_t {
  118. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  119. { 0, nullptr },
  120. 666 }));
  121. EXPECT_CALL(mock, amqp_error_string2(666))
  122. .WillOnce(Return("error from hell >:D"));
  123. EXPECT_THROW(con.login_plain("username", "password", "vhost", 100, 200), cppamqp::exception);
  124. }
  125. TEST(AmqpTest, Connection_loginPlain_success)
  126. {
  127. connection con;
  128. con.tcp_connect("localhost", 1234);
  129. StrictAmqpMock mock;
  130. InSequence seq;
  131. EXPECT_CALL(mock, amqp_login_plain(AmqpMock::defaultConnectionState, StrEq("vhost"), 200, 131072, 100, AMQP_SASL_METHOD_PLAIN, StrEq("username"), StrEq("password")))
  132. .WillOnce(Return(AmqpMock::defaultRpcReply));
  133. EXPECT_NO_THROW(con.login_plain("username", "password", "vhost", 100, 200));
  134. }
  135. TEST(AmqpTest, Connection_openChannel_failed)
  136. {
  137. std::string channelId("test_channel");
  138. amqp_channel_open_ok_t channelOk { {
  139. channelId.size(),
  140. const_cast<char*>(channelId.c_str())
  141. } };
  142. connection con;
  143. con.tcp_connect("localhost", 1234);
  144. StrictAmqpMock mock;
  145. InSequence seq;
  146. EXPECT_CALL(mock, amqp_channel_open(AmqpMock::defaultConnectionState, 3))
  147. .WillOnce(Return(&channelOk));
  148. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  149. .WillOnce(Return(amqp_rpc_reply_t {
  150. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  151. { 0, nullptr },
  152. 666 }));
  153. EXPECT_CALL(mock, amqp_error_string2(666))
  154. .WillOnce(Return("error from hell >:D"));
  155. EXPECT_THROW(con.open_channel(3), cppamqp::exception);
  156. }
  157. TEST(AmqpTest, Connection_openChannel_success)
  158. {
  159. std::string channelId("test_channel");
  160. amqp_channel_open_ok_t channelOk { {
  161. channelId.size(),
  162. const_cast<char*>(channelId.c_str())
  163. } };
  164. connection con;
  165. con.tcp_connect("localhost", 1234);
  166. StrictAmqpMock mock;
  167. InSequence seq;
  168. EXPECT_CALL(mock, amqp_channel_open(AmqpMock::defaultConnectionState, 3))
  169. .WillOnce(Return(&channelOk));
  170. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  171. .WillOnce(Return(AmqpMock::defaultRpcReply));
  172. EXPECT_CALL(mock, amqp_channel_close(AmqpMock::defaultConnectionState, 3, AMQP_REPLY_SUCCESS))
  173. .WillOnce(Return(AmqpMock::defaultRpcReply));
  174. EXPECT_NO_THROW(con.open_channel(3));
  175. }
  176. TEST(AmqpTest, Connection_consumeMessage_success)
  177. {
  178. connection con;
  179. con.tcp_connect("localhost", 1234);
  180. StrictAmqpMock mock;
  181. InSequence seq;
  182. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  183. .Times(1);
  184. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  185. .WillOnce(DoAll(SetArgPointee<1>(DefaultEnvelope), Return(AmqpMock::defaultRpcReply)));
  186. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  187. .Times(1);
  188. auto mr = con.consume_message();
  189. EXPECT_EQ(consume_result_type::success, mr.type);
  190. EXPECT_EQ(std::string("this_is_the_message"), mr.message.body);
  191. EXPECT_EQ(3, mr.channel);
  192. EXPECT_EQ(std::string("my_consumer_tag"), mr.consumer_tag);
  193. EXPECT_EQ(12345678, mr.delivery_tag);
  194. EXPECT_EQ(true, mr.redelivered);
  195. EXPECT_EQ(std::string("my_exchange"), mr.exchange);
  196. EXPECT_EQ(std::string("my_routing_key"), mr.routing_key);
  197. }
  198. TEST(AmqpTest, Connection_consumeMessage_nonLibraryError)
  199. {
  200. connection con;
  201. con.tcp_connect("localhost", 1234);
  202. StrictAmqpMock mock;
  203. InSequence seq;
  204. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  205. .Times(1);
  206. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  207. .WillOnce(
  208. DoAll(SetArgPointee<1>(DefaultEnvelope),
  209. Return(amqp_rpc_reply_t {
  210. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_SERVER_EXCEPTION),
  211. { 0, nullptr },
  212. 666 })));
  213. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  214. .Times(1);
  215. EXPECT_THROW(con.consume_message(), cppamqp::exception);
  216. }
  217. TEST(AmqpTest, Connection_consumeMessage_nonUnexpectedState)
  218. {
  219. connection con;
  220. con.tcp_connect("localhost", 1234);
  221. StrictAmqpMock mock;
  222. InSequence seq;
  223. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  224. .Times(1);
  225. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  226. .WillOnce(
  227. DoAll(SetArgPointee<1>(DefaultEnvelope),
  228. Return(amqp_rpc_reply_t {
  229. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  230. { 0, nullptr },
  231. 666 })));
  232. EXPECT_CALL(mock, amqp_error_string2(666))
  233. .WillOnce(Return("error from hell >:D"));
  234. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  235. .Times(1);
  236. EXPECT_THROW(con.consume_message(), cppamqp::exception);
  237. }
  238. TEST(AmqpTest, Connection_consumeMessage_waitFrameError)
  239. {
  240. connection con;
  241. con.tcp_connect("localhost", 1234);
  242. StrictAmqpMock mock;
  243. InSequence seq;
  244. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  245. .Times(1);
  246. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  247. .WillOnce(DoAll(
  248. SetArgPointee<1>(DefaultEnvelope),
  249. Return(amqp_rpc_reply_t {
  250. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  251. { 0, nullptr },
  252. AMQP_STATUS_UNEXPECTED_STATE })));
  253. EXPECT_CALL(mock, amqp_simple_wait_frame_noblock(AmqpMock::defaultConnectionState, NotNull(), Pointee(timeval { 0, 0 })))
  254. .WillOnce(Return(666));
  255. EXPECT_CALL(mock, amqp_error_string2(666))
  256. .WillOnce(Return("error from hell >:D"));
  257. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  258. .Times(1);
  259. EXPECT_THROW(con.consume_message(), cppamqp::exception);
  260. }
  261. TEST(AmqpTest, Connection_consumeMessage_noMethodFrame)
  262. {
  263. amqp_frame_t frame {
  264. /* .frame_type */ AMQP_FRAME_HEADER,
  265. /* .channel */ 3,
  266. /* .payload */ { { 0, nullptr } }
  267. };
  268. connection con;
  269. con.tcp_connect("localhost", 1234);
  270. StrictAmqpMock mock;
  271. InSequence seq;
  272. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  273. .Times(1);
  274. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  275. .WillOnce(DoAll(
  276. SetArgPointee<1>(DefaultEnvelope),
  277. Return(amqp_rpc_reply_t {
  278. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  279. { 0, nullptr },
  280. AMQP_STATUS_UNEXPECTED_STATE })));
  281. EXPECT_CALL(mock, amqp_simple_wait_frame_noblock(AmqpMock::defaultConnectionState, NotNull(), Pointee(timeval { 0, 0 })))
  282. .WillOnce(DoAll(
  283. SetArgPointee<1>(frame),
  284. Return(0)));
  285. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  286. .Times(1);
  287. EXPECT_THROW(con.consume_message(), cppamqp::exception);
  288. }
  289. TEST(AmqpTest, Connection_consumeMessage_ackMessage)
  290. {
  291. amqp_frame_t frame {
  292. /* .frame_type */ AMQP_FRAME_METHOD,
  293. /* .channel */ 3,
  294. /* .payload */ { { AMQP_BASIC_ACK_METHOD, nullptr } }
  295. };
  296. connection con;
  297. con.tcp_connect("localhost", 1234);
  298. StrictAmqpMock mock;
  299. InSequence seq;
  300. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  301. .Times(1);
  302. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  303. .WillOnce(DoAll(
  304. SetArgPointee<1>(DefaultEnvelope),
  305. Return(amqp_rpc_reply_t {
  306. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  307. { 0, nullptr },
  308. AMQP_STATUS_UNEXPECTED_STATE })));
  309. EXPECT_CALL(mock, amqp_simple_wait_frame_noblock(AmqpMock::defaultConnectionState, NotNull(), Pointee(timeval { 0, 0 })))
  310. .WillOnce(DoAll(
  311. SetArgPointee<1>(frame),
  312. Return(0)));
  313. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  314. .Times(1);
  315. auto mr = con.consume_message();
  316. EXPECT_EQ(consume_result_type::acknowledge, mr.type);
  317. }
  318. TEST(AmqpTest, Connection_consumeMessage_channelClosedMessage)
  319. {
  320. amqp_frame_t frame {
  321. /* .frame_type */ AMQP_FRAME_METHOD,
  322. /* .channel */ 3,
  323. /* .payload */ { { AMQP_CHANNEL_CLOSE_METHOD, nullptr } }
  324. };
  325. connection con;
  326. con.tcp_connect("localhost", 1234);
  327. StrictAmqpMock mock;
  328. InSequence seq;
  329. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  330. .Times(1);
  331. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  332. .WillOnce(DoAll(
  333. SetArgPointee<1>(DefaultEnvelope),
  334. Return(amqp_rpc_reply_t {
  335. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  336. { 0, nullptr },
  337. AMQP_STATUS_UNEXPECTED_STATE })));
  338. EXPECT_CALL(mock, amqp_simple_wait_frame_noblock(AmqpMock::defaultConnectionState, NotNull(), Pointee(timeval { 0, 0 })))
  339. .WillOnce(DoAll(
  340. SetArgPointee<1>(frame),
  341. Return(0)));
  342. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  343. .Times(1);
  344. EXPECT_THROW(con.consume_message(), cppamqp::exception);
  345. }
  346. TEST(AmqpTest, Connection_consumeMessage_connectionClosedMessage)
  347. {
  348. amqp_frame_t frame {
  349. /* .frame_type */ AMQP_FRAME_METHOD,
  350. /* .channel */ 3,
  351. /* .payload */ { { AMQP_CONNECTION_CLOSE_METHOD, nullptr } }
  352. };
  353. connection con;
  354. con.tcp_connect("localhost", 1234);
  355. StrictAmqpMock mock;
  356. InSequence seq;
  357. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  358. .Times(1);
  359. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  360. .WillOnce(DoAll(
  361. SetArgPointee<1>(DefaultEnvelope),
  362. Return(amqp_rpc_reply_t {
  363. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  364. { 0, nullptr },
  365. AMQP_STATUS_UNEXPECTED_STATE })));
  366. EXPECT_CALL(mock, amqp_simple_wait_frame_noblock(AmqpMock::defaultConnectionState, NotNull(), Pointee(timeval { 0, 0 })))
  367. .WillOnce(DoAll(
  368. SetArgPointee<1>(frame),
  369. Return(0)));
  370. EXPECT_CALL(mock, amqp_destroy_connection(AmqpMock::defaultConnectionState))
  371. .WillOnce(Return(0));
  372. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  373. .Times(1);
  374. auto mr = con.consume_message();
  375. EXPECT_EQ(consume_result_type::connection_closed_by_peer, mr.type);
  376. }
  377. TEST(AmqpTest, Connection_consumeMessage_returnToSender)
  378. {
  379. amqp_frame_t frame {
  380. /* .frame_type */ AMQP_FRAME_METHOD,
  381. /* .channel */ 3,
  382. /* .payload */ { { AMQP_BASIC_RETURN_METHOD, nullptr } }
  383. };
  384. connection con;
  385. con.tcp_connect("localhost", 1234);
  386. StrictAmqpMock mock;
  387. InSequence seq;
  388. EXPECT_CALL(mock, amqp_maybe_release_buffers(AmqpMock::defaultConnectionState))
  389. .Times(1);
  390. EXPECT_CALL(mock, amqp_consume_message(AmqpMock::defaultConnectionState, NotNull(), nullptr, 0))
  391. .WillOnce(DoAll(
  392. SetArgPointee<1>(DefaultEnvelope),
  393. Return(amqp_rpc_reply_t {
  394. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  395. { 0, nullptr },
  396. AMQP_STATUS_UNEXPECTED_STATE })));
  397. EXPECT_CALL(mock, amqp_simple_wait_frame_noblock(AmqpMock::defaultConnectionState, NotNull(), Pointee(timeval { 0, 0 })))
  398. .WillOnce(DoAll(
  399. SetArgPointee<1>(frame),
  400. Return(0)));
  401. EXPECT_CALL(mock, amqp_read_message(AmqpMock::defaultConnectionState, 3, NotNull(), 0))
  402. .WillOnce(DoAll(
  403. SetArgPointee<2>(DefaultEnvelope.message),
  404. Return(AmqpMock::defaultRpcReply)));
  405. EXPECT_CALL(mock, amqp_destroy_message(NotNull()))
  406. .Times(1);
  407. EXPECT_CALL(mock, amqp_destroy_envelope(NotNull()))
  408. .Times(1);
  409. auto mr = con.consume_message();
  410. EXPECT_EQ(consume_result_type::could_not_deliver_return_to_sender, mr.type);
  411. EXPECT_EQ(std::string("this_is_the_message"), mr.message.body);
  412. }
  413. TEST(AmqpTest, Connection_close_success)
  414. {
  415. connection con;
  416. con.tcp_connect("localhost", 1234);
  417. StrictAmqpMock mock;
  418. InSequence seq;
  419. EXPECT_CALL(mock, amqp_connection_close(AmqpMock::defaultConnectionState, 123))
  420. .WillOnce(Return(AmqpMock::defaultRpcReply));
  421. EXPECT_CALL(mock, amqp_destroy_connection(AmqpMock::defaultConnectionState))
  422. .WillOnce(Return(0));
  423. con.close(123);
  424. }
  425. TEST(AmqpTest, Connection_closeForced_success)
  426. {
  427. connection con;
  428. con.tcp_connect("localhost", 1234);
  429. StrictAmqpMock mock;
  430. InSequence seq;
  431. EXPECT_CALL(mock, amqp_destroy_connection(AmqpMock::defaultConnectionState))
  432. .WillOnce(Return(0));
  433. con.close(123, true);
  434. }
  435. TEST(AmqpTest, Channel_declareQueue_declareFailed)
  436. {
  437. connection con;
  438. con.tcp_connect("localhost", 1234);
  439. channel channel = con.open_channel(3);
  440. StrictAmqpMock mock;
  441. InSequence seq;
  442. EXPECT_CALL(mock, amqp_queue_declare(AmqpMock::defaultConnectionState, 3, BytesEq("test_queue"), false, true, false, true, _))
  443. .WillOnce(Return(nullptr));
  444. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  445. .WillOnce(Return(AmqpMock::defaultRpcReply));
  446. EXPECT_THROW(channel.declare_queue("test_queue", queue_flags({ queue_flag::durable, queue_flag::auto_delete })), cppamqp::exception);
  447. }
  448. TEST(AmqpTest, Channel_declareQueue_rpcReplyError)
  449. {
  450. connection con;
  451. con.tcp_connect("localhost", 1234);
  452. channel channel = con.open_channel(3);
  453. StrictAmqpMock mock;
  454. InSequence seq;
  455. EXPECT_CALL(mock, amqp_queue_declare(AmqpMock::defaultConnectionState, 3, BytesEq("test_queue"), true, false, false, true, _))
  456. .WillOnce(Return(nullptr));
  457. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  458. .WillOnce(Return(amqp_rpc_reply_t {
  459. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  460. { 0, nullptr },
  461. 666 }));
  462. EXPECT_CALL(mock, amqp_error_string2(666))
  463. .WillOnce(Return("error from hell >:D"));
  464. EXPECT_THROW(channel.declare_queue("test_queue", queue_flags({ queue_flag::passive, queue_flag::auto_delete })), cppamqp::exception);
  465. }
  466. TEST(AmqpTest, Channel_declareQueue_success)
  467. {
  468. std::string name("blub");
  469. amqp_queue_declare_ok_t queueDeclareOk {
  470. { name.size(), const_cast<char*>(name.data()) },
  471. 123,
  472. 456
  473. };
  474. connection con;
  475. con.tcp_connect("localhost", 1234);
  476. channel channel = con.open_channel(3);
  477. StrictAmqpMock mock;
  478. InSequence seq;
  479. EXPECT_CALL(mock, amqp_queue_declare(AmqpMock::defaultConnectionState, 3, BytesEq("test_queue"), true, false, true, false, _))
  480. .WillOnce(Return(&queueDeclareOk));
  481. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  482. .WillOnce(Return(AmqpMock::defaultRpcReply));
  483. auto qDecl = channel.declare_queue("test_queue", queue_flags({ queue_flag::passive, queue_flag::exclusive }));
  484. EXPECT_EQ(name, qDecl.name);
  485. EXPECT_EQ(123, qDecl.message_count);
  486. EXPECT_EQ(456, qDecl.consumer_count);
  487. }
  488. TEST(AmqpTest, Channel_bindQueue_rpcReplyError)
  489. {
  490. amqp_queue_bind_ok_t dummy { 0 };
  491. connection con;
  492. con.tcp_connect("localhost", 1234);
  493. channel channel = con.open_channel(3);
  494. StrictAmqpMock mock;
  495. InSequence seq;
  496. EXPECT_CALL(mock, amqp_queue_bind(AmqpMock::defaultConnectionState, 3, BytesEq("test_queue"), BytesEq("my_exchange"), BytesEq("the_routing_key"), _))
  497. .WillOnce(Return(&dummy));
  498. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  499. .WillOnce(Return(amqp_rpc_reply_t {
  500. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  501. { 0, nullptr },
  502. 666 }));
  503. EXPECT_CALL(mock, amqp_error_string2(666))
  504. .WillOnce(Return("error from hell >:D"));
  505. EXPECT_THROW(channel.bind_queue("test_queue", "my_exchange", "the_routing_key"), cppamqp::exception);
  506. }
  507. TEST(AmqpTest, Channel_bindQueue_success)
  508. {
  509. amqp_queue_bind_ok_t dummy { 0 };
  510. connection con;
  511. con.tcp_connect("localhost", 1234);
  512. channel channel = con.open_channel(3);
  513. StrictAmqpMock mock;
  514. InSequence seq;
  515. EXPECT_CALL(mock, amqp_queue_bind(AmqpMock::defaultConnectionState, 3, BytesEq("test_queue"), BytesEq("my_exchange"), BytesEq("the_routing_key"), _))
  516. .WillOnce(Return(&dummy));
  517. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  518. .WillOnce(Return(AmqpMock::defaultRpcReply));
  519. EXPECT_NO_THROW(channel.bind_queue("test_queue", "my_exchange", "the_routing_key"));
  520. }
  521. TEST(AmqpTest, Channel_publish_failed)
  522. {
  523. connection con;
  524. con.tcp_connect("localhost", 1234);
  525. channel channel = con.open_channel(3);
  526. StrictAmqpMock mock;
  527. InSequence seq;
  528. EXPECT_CALL(mock, amqp_basic_publish(AmqpMock::defaultConnectionState, 3, BytesEq("my_exchange"), BytesEq("my_routing_key"), false, true, nullptr, BytesEq("the_message")))
  529. .WillOnce(Return(666));
  530. EXPECT_CALL(mock, amqp_error_string2(666))
  531. .WillOnce(Return("error from hell >:D"));
  532. EXPECT_THROW(channel.publish("my_exchange", "my_routing_key", publish_flags({ publish_flag::immediate }), "the_message", nullptr), cppamqp::exception);
  533. }
  534. TEST(AmqpTest, Channel_publish_success)
  535. {
  536. connection con;
  537. con.tcp_connect("localhost", 1234);
  538. channel channel = con.open_channel(3);
  539. StrictAmqpMock mock;
  540. InSequence seq;
  541. EXPECT_CALL(mock, amqp_basic_publish(AmqpMock::defaultConnectionState, 3, BytesEq("my_exchange"), BytesEq("my_routing_key"), true, false, NotNull(), BytesEq("the_message")))
  542. .WillOnce(Return(0));
  543. publish_options po;
  544. EXPECT_NO_THROW(channel.publish("my_exchange", "my_routing_key", publish_flags({ publish_flag::mandatory }), "the_message", &po));
  545. }
  546. TEST(AmqpTest, Channel_consume_consumeFailed)
  547. {
  548. connection con;
  549. con.tcp_connect("localhost", 1234);
  550. channel channel = con.open_channel(3);
  551. StrictAmqpMock mock;
  552. InSequence seq;
  553. EXPECT_CALL(mock, amqp_basic_consume(AmqpMock::defaultConnectionState, 3, BytesEq("my_queue"), BytesEq("my_consumer_tag"), true, false, false, _))
  554. .WillOnce(Return(nullptr));
  555. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  556. .WillOnce(Return(AmqpMock::defaultRpcReply));
  557. EXPECT_THROW(channel.consume("my_queue", "my_consumer_tag", consume_flags(consume_flag::no_local)), cppamqp::exception);
  558. }
  559. TEST(AmqpTest, Channel_consume_rpcReplyError)
  560. {
  561. connection con;
  562. con.tcp_connect("localhost", 1234);
  563. channel channel = con.open_channel(3);
  564. amqp_basic_consume_ok_t consumeOk { { 7, const_cast<char*>("new_tag") } };
  565. StrictAmqpMock mock;
  566. InSequence seq;
  567. EXPECT_CALL(mock, amqp_basic_consume(AmqpMock::defaultConnectionState, 3, BytesEq("my_queue"), BytesEq("my_consumer_tag"), false, true, false, _))
  568. .WillOnce(Return(&consumeOk));
  569. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  570. .WillOnce(Return(amqp_rpc_reply_t {
  571. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  572. { 0, nullptr },
  573. 666 }));
  574. EXPECT_CALL(mock, amqp_error_string2(666))
  575. .WillOnce(Return("error from hell >:D"));
  576. EXPECT_THROW(channel.consume("my_queue", "my_consumer_tag", consume_flags(consume_flag::no_ack)), cppamqp::exception);
  577. }
  578. TEST(AmqpTest, Channel_consume_success)
  579. {
  580. connection con;
  581. con.tcp_connect("localhost", 1234);
  582. channel channel = con.open_channel(3);
  583. amqp_basic_consume_ok_t consumeOk { { 7, const_cast<char*>("new_tag") } };
  584. StrictAmqpMock mock;
  585. InSequence seq;
  586. EXPECT_CALL(mock, amqp_basic_consume(AmqpMock::defaultConnectionState, 3, BytesEq("my_queue"), BytesEq("my_consumer_tag"), false, false, true, _))
  587. .WillOnce(Return(&consumeOk));
  588. EXPECT_CALL(mock, amqp_get_rpc_reply(AmqpMock::defaultConnectionState))
  589. .WillOnce(Return(AmqpMock::defaultRpcReply));
  590. auto tag = channel.consume("my_queue", "my_consumer_tag", consume_flags(consume_flag::exclusive));
  591. EXPECT_EQ(std::string("new_tag"), tag);
  592. }
  593. TEST(AmqpTest, Channel_close_failed)
  594. {
  595. connection con;
  596. con.tcp_connect("localhost", 1234);
  597. channel channel = con.open_channel(3);
  598. StrictAmqpMock mock;
  599. InSequence seq;
  600. EXPECT_CALL(mock, amqp_channel_close(AmqpMock::defaultConnectionState, 3, 500))
  601. .WillOnce(Return(amqp_rpc_reply_t {
  602. static_cast<amqp_response_type_enum>(AMQP_RESPONSE_LIBRARY_EXCEPTION),
  603. { 0, nullptr },
  604. 666 }));
  605. EXPECT_CALL(mock, amqp_error_string2(666))
  606. .WillOnce(Return("error from hell >:D"));
  607. EXPECT_THROW(channel.close(500), cppamqp::exception);
  608. }
  609. TEST(AmqpTest, Channel_close_success)
  610. {
  611. connection con;
  612. con.tcp_connect("localhost", 1234);
  613. channel channel = con.open_channel(3);
  614. StrictAmqpMock mock;
  615. InSequence seq;
  616. EXPECT_CALL(mock, amqp_channel_close(AmqpMock::defaultConnectionState, 3, 200))
  617. .WillOnce(Return(AmqpMock::defaultRpcReply));
  618. EXPECT_NO_THROW(channel.close(200));
  619. }