Skip to content

Commit 798254d

Browse files
committed
Handle assignment/revocation in consumer mock
1 parent 7484c74 commit 798254d

File tree

5 files changed

+97
-4
lines changed

5 files changed

+97
-4
lines changed

mocking/include/cppkafka/mocking/consumer_mock.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <vector>
55
#include <string>
66
#include <cstdint>
7+
#include <map>
8+
#include <tuple>
79
#include <unordered_set>
810
#include <cppkafka/mocking/handle_mock.h>
911
#include <cppkafka/mocking/configuration_mock.h>
@@ -20,16 +22,31 @@ class ConsumerMock : public HandleMock {
2022
~ConsumerMock();
2123

2224
void subscribe(const std::vector<std::string>& topics);
25+
void set_opaque(void* opaque);
2326
private:
2427
static uint64_t make_consumer_id();
2528

29+
struct TopicPartitionInfo {
30+
int64_t offset;
31+
bool paused;
32+
};
33+
34+
using TopicPartitionId = std::tuple<std::string, int>;
35+
36+
static TopicPartitionId make_id(const TopicPartitionMock& topic_partition);
2637
void on_assignment(std::vector<TopicPartitionMock>& topic_partitions);
2738
void on_revocation(const std::vector<TopicPartitionMock>& topic_partitions);
2839
void on_message(uint64_t offset);
40+
template <typename List>
41+
void handle_rebalance(rd_kafka_resp_err_t type, List& topic_partitions);
42+
void handle_assign(const TopicPartitionMock& topic_partition);
43+
void handle_unassign(const TopicPartitionMock& topic_partition);
2944

3045
ConfigurationMock config_;
3146
const std::string group_id_;
3247
std::unordered_set<std::string> subscribed_topics_;
48+
std::map<TopicPartitionId, TopicPartitionInfo> assigned_partitions_;
49+
void* opaque_;
3350
uint64_t consumer_id_;
3451
};
3552

mocking/include/cppkafka/mocking/topic_partition_mock.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <string>
55
#include <cstdint>
6+
#include <memory>
7+
#include <vector>
68
#include <librdkafka/rdkafka.h>
79

810
namespace cppkafka {
@@ -18,11 +20,18 @@ class TopicPartitionMock {
1820

1921
void set_offset(int64_t offset);
2022
private:
21-
std::string topic_;
22-
int partition_;
23+
const std::string topic_;
24+
const int partition_;
2325
int64_t offset_;
2426
};
2527

28+
using TopicPartitionMockListPtr = std::unique_ptr<rd_kafka_topic_partition_list_t,
29+
decltype(&rd_kafka_topic_partition_list_destroy)>;
30+
TopicPartitionMockListPtr
31+
to_rdkafka_handle(const std::vector<TopicPartitionMock>& topic_partitions);
32+
std::vector<TopicPartitionMock>
33+
from_rdkafka_handle(const rd_kafka_topic_partition_list_t& topic_partitions);
34+
2635
} // mocking
2736
} // cppkafka
2837

mocking/src/api.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ rd_kafka_topic_partition_list_add(rd_kafka_topic_partition_list_t* toppar_list,
201201
output->topic = new char[length + 1];
202202
copy(topic, topic + length, output->topic);
203203
output->partition = partition;
204+
output->offset = RD_KAFKA_OFFSET_INVALID;
204205
return output;
205206
}
206207

mocking/src/consumer_mock.cpp

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ using std::string;
99
using std::move;
1010
using std::bind;
1111
using std::runtime_error;
12+
using std::make_tuple;
1213

1314
namespace cppkafka {
1415
namespace mocking {
@@ -57,16 +58,53 @@ void ConsumerMock::subscribe(const vector<string>& topics) {
5758
}
5859
}
5960

60-
void ConsumerMock::on_assignment(vector<TopicPartitionMock>& topic_partitions) {
61+
void ConsumerMock::set_opaque(void* opaque) {
62+
opaque_ = opaque;
63+
}
6164

65+
ConsumerMock::TopicPartitionId ConsumerMock::make_id(const TopicPartitionMock& topic_partition) {
66+
return make_tuple(topic_partition.get_topic(), topic_partition.get_partition());
6267
}
6368

64-
void ConsumerMock::on_revocation(const vector<TopicPartitionMock>& topic_partitions) {
69+
void ConsumerMock::on_assignment(vector<TopicPartitionMock>& topic_partitions) {
70+
handle_rebalance(RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS, topic_partitions);
71+
for (const TopicPartitionMock& topic_partition : topic_partitions) {
72+
handle_assign(topic_partition);
73+
}
74+
}
6575

76+
void ConsumerMock::on_revocation(const vector<TopicPartitionMock>& topic_partitions) {
77+
handle_rebalance(RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS, topic_partitions);
78+
for (const TopicPartitionMock& topic_partition : topic_partitions) {
79+
handle_unassign(topic_partition);
80+
}
6681
}
6782

6883
void ConsumerMock::on_message(uint64_t offset) {
84+
85+
}
86+
87+
template <typename List>
88+
void ConsumerMock::handle_rebalance(rd_kafka_resp_err_t type, List& topic_partitions) {
89+
auto rebalance_callback = config_.get_rebalance_callback();
90+
if (rebalance_callback) {
91+
auto handle = to_rdkafka_handle(topic_partitions);
92+
rebalance_callback(nullptr, type, handle.get(), opaque_);
93+
}
94+
}
95+
96+
void ConsumerMock::handle_assign(const TopicPartitionMock& topic_partition) {
97+
const auto id = make_id(topic_partition);
98+
if (assigned_partitions_.count(id)) {
99+
return;
100+
}
101+
assigned_partitions_[id] = {
102+
topic_partition.get_offset()
103+
};
104+
}
69105

106+
void ConsumerMock::handle_unassign(const TopicPartitionMock& topic_partition) {
107+
assigned_partitions_.erase(make_id(topic_partition));
70108
}
71109

72110
} // mocking

mocking/src/topic_partition_mock.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
#include <tuple>
12
#include <cppkafka/mocking/topic_partition_mock.h>
23

34
using std::string;
5+
using std::vector;
6+
using std::tie;
7+
using std::unique_ptr;
48

59
namespace cppkafka {
610
namespace mocking {
@@ -26,5 +30,29 @@ void TopicPartitionMock::set_offset(int64_t offset) {
2630
offset_ = offset;
2731
}
2832

33+
TopicPartitionMockListPtr to_rdkafka_handle(const vector<TopicPartitionMock>& topic_partitions){
34+
const size_t count = topic_partitions.size();
35+
TopicPartitionMockListPtr output{rd_kafka_topic_partition_list_new(count),
36+
&rd_kafka_topic_partition_list_destroy};
37+
for (const TopicPartitionMock& topic_partition : topic_partitions) {
38+
auto* ptr = rd_kafka_topic_partition_list_add(output.get(),
39+
topic_partition.get_topic().data(),
40+
topic_partition.get_partition());
41+
ptr->offset = topic_partition.get_offset();
42+
}
43+
return output;
44+
}
45+
46+
vector<TopicPartitionMock>
47+
from_rdkafka_handle(const rd_kafka_topic_partition_list_t& topic_partitions){
48+
vector<TopicPartitionMock> output;
49+
for (int i = 0; i < topic_partitions.cnt; ++i) {
50+
const auto& topic_partition = topic_partitions.elems[i];
51+
output.emplace_back(topic_partition.topic, topic_partition.partition,
52+
topic_partition.offset);
53+
}
54+
return output;
55+
}
56+
2957
} // mocking
3058
} // cppkafka

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy