|
18 | 18 | */ |
19 | 19 | #include <gtest/gtest.h> |
20 | 20 | #include <pulsar/Client.h> |
| 21 | +#include <pulsar/ClientConfiguration.h> |
21 | 22 | #include <pulsar/Reader.h> |
22 | 23 | #include <time.h> |
23 | 24 |
|
@@ -955,5 +956,50 @@ TEST_F(ReaderSeekTest, testSeekInclusiveChunkMessage) { |
955 | 956 | assertStartMessageId(false, secondMsgId); |
956 | 957 | } |
957 | 958 |
|
| 959 | +// Regression test for segfault when Reader is used with messageListenerThreads=0. |
| 960 | +// Verifies ExecutorServiceProvider(0) does not cause undefined behavior and |
| 961 | +// ConsumerImpl::messageReceived does not dereference null listenerExecutor_. |
| 962 | +TEST(ReaderTest, testReaderWithZeroMessageListenerThreads) { |
| 963 | + ClientConfiguration clientConf; |
| 964 | + clientConf.setMessageListenerThreads(0); |
| 965 | + Client client(serviceUrl, clientConf); |
| 966 | + |
| 967 | + const std::string topicName = |
| 968 | + "testReaderWithZeroMessageListenerThreads-" + std::to_string(time(nullptr)); |
| 969 | + |
| 970 | + Producer producer; |
| 971 | + ASSERT_EQ(ResultOk, client.createProducer(topicName, producer)); |
| 972 | + |
| 973 | + ReaderConfiguration readerConf; |
| 974 | + Reader reader; |
| 975 | + ASSERT_EQ(ResultOk, client.createReader(topicName, MessageId::earliest(), readerConf, reader)); |
| 976 | + |
| 977 | + constexpr int numMessages = 5; |
| 978 | + for (int i = 0; i < numMessages; i++) { |
| 979 | + Message msg = MessageBuilder().setContent("msg-" + std::to_string(i)).build(); |
| 980 | + ASSERT_EQ(ResultOk, producer.send(msg)); |
| 981 | + } |
| 982 | + |
| 983 | + int received = 0; |
| 984 | + for (int i = 0; i < numMessages + 2; i++) { |
| 985 | + bool hasMessageAvailable = false; |
| 986 | + ASSERT_EQ(ResultOk, reader.hasMessageAvailable(hasMessageAvailable)); |
| 987 | + if (!hasMessageAvailable) { |
| 988 | + break; |
| 989 | + } |
| 990 | + Message msg; |
| 991 | + Result res = reader.readNext(msg, 3000); |
| 992 | + ASSERT_EQ(ResultOk, res) << "readNext failed at iteration " << i; |
| 993 | + std::string content = msg.getDataAsString(); |
| 994 | + EXPECT_EQ("msg-" + std::to_string(received), content); |
| 995 | + ++received; |
| 996 | + } |
| 997 | + EXPECT_EQ(received, numMessages); |
| 998 | + |
| 999 | + producer.close(); |
| 1000 | + reader.close(); |
| 1001 | + client.close(); |
| 1002 | +} |
| 1003 | + |
958 | 1004 | INSTANTIATE_TEST_SUITE_P(Pulsar, ReaderTest, ::testing::Values(true, false)); |
959 | 1005 | INSTANTIATE_TEST_SUITE_P(Pulsar, ReaderSeekTest, ::testing::Values(true, false)); |
0 commit comments