@platformatic/rdkafka 4.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/bench/seed.sh +0 -0
- package/binding.gyp +8 -1
- package/ci/prepublish.js +0 -1
- package/config.d.ts +126 -10
- package/configure +0 -0
- package/deps/librdkafka/.semaphore/run-all-tests.yml +77 -0
- package/deps/librdkafka/.semaphore/semaphore-integration.yml +250 -0
- package/deps/librdkafka/.semaphore/semaphore.yml +67 -44
- package/deps/librdkafka/.semaphore/verify-linux-packages.yml +41 -0
- package/deps/librdkafka/CHANGELOG.md +471 -1
- package/deps/librdkafka/CONFIGURATION.md +29 -9
- package/deps/librdkafka/INTRODUCTION.md +909 -601
- package/deps/librdkafka/LICENSES.txt +592 -1
- package/deps/librdkafka/Makefile +2 -1
- package/deps/librdkafka/_mkltmpuuWEwa.c +13 -0
- package/deps/librdkafka/configure +0 -0
- package/deps/librdkafka/debian/rules +0 -0
- package/deps/librdkafka/dev-conf.sh +0 -0
- package/deps/librdkafka/examples/consumer.c +18 -8
- package/deps/librdkafka/examples/describe_consumer_groups.c +25 -6
- package/deps/librdkafka/examples/incremental_alter_configs.c +4 -5
- package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +26 -42
- package/deps/librdkafka/examples/openssl_engine_example.cpp +3 -4
- package/deps/librdkafka/examples/producer.cpp +2 -2
- package/deps/librdkafka/examples/user_scram.c +4 -5
- package/deps/librdkafka/examples/win_ssl_cert_store.cpp +4 -3
- package/deps/librdkafka/lds-gen.py +0 -0
- package/deps/librdkafka/mklove/Makefile.base +0 -0
- package/deps/librdkafka/packaging/RELEASE.md +8 -0
- package/deps/librdkafka/packaging/alpine/build-alpine.sh +0 -0
- package/deps/librdkafka/packaging/cp/README.md +4 -1
- package/deps/librdkafka/packaging/cp/check_features.c +12 -4
- package/deps/librdkafka/packaging/cp/verify-deb.sh +6 -6
- package/deps/librdkafka/packaging/cp/verify-packages.sh +52 -31
- package/deps/librdkafka/packaging/cp/verify-rpm.sh +6 -13
- package/deps/librdkafka/packaging/debian/rules +0 -0
- package/deps/librdkafka/packaging/get_version.py +0 -0
- package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +0 -0
- package/deps/librdkafka/packaging/mingw-w64/{travis-before-install.sh → export-variables.sh} +0 -7
- package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +1 -1
- package/deps/librdkafka/packaging/nuget/artifact.py +0 -0
- package/deps/librdkafka/packaging/nuget/cleanup-s3.py +0 -0
- package/deps/librdkafka/packaging/nuget/nuget.sh +0 -0
- package/deps/librdkafka/packaging/nuget/packaging.py +0 -0
- package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +0 -0
- package/deps/librdkafka/packaging/nuget/release.py +0 -0
- package/deps/librdkafka/packaging/nuget/requirements.txt +3 -3
- package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +0 -0
- package/deps/librdkafka/packaging/rpm/tests/run-test.sh +0 -0
- package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +3 -1
- package/deps/librdkafka/packaging/tools/build-deb-package.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-debian.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-manylinux.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +0 -0
- package/deps/librdkafka/packaging/tools/distro-build.sh +0 -0
- package/deps/librdkafka/packaging/tools/gh-release-checksums.py +0 -0
- package/deps/librdkafka/packaging/tools/rdutcoverage.sh +0 -0
- package/deps/librdkafka/packaging/tools/run-in-docker.sh +28 -0
- package/deps/librdkafka/packaging/tools/run-integration-tests.sh +31 -0
- package/deps/librdkafka/packaging/tools/run-style-check.sh +4 -0
- package/deps/librdkafka/packaging/tools/style-format.sh +6 -5
- package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
- package/deps/librdkafka/service.yml +154 -0
- package/deps/librdkafka/src/generate_proto.sh +0 -0
- package/deps/librdkafka/src/rd.h +145 -2
- package/deps/librdkafka/src/rdaddr.h +6 -7
- package/deps/librdkafka/src/rdatomic.h +15 -11
- package/deps/librdkafka/src/rdavg.h +3 -2
- package/deps/librdkafka/src/rdbase64.c +33 -2
- package/deps/librdkafka/src/rdbase64.h +2 -0
- package/deps/librdkafka/src/rdendian.h +10 -9
- package/deps/librdkafka/src/rdhttp.c +418 -100
- package/deps/librdkafka/src/rdhttp.h +23 -5
- package/deps/librdkafka/src/rdkafka.c +299 -145
- package/deps/librdkafka/src/rdkafka.h +89 -6
- package/deps/librdkafka/src/rdkafka_admin.c +482 -105
- package/deps/librdkafka/src/rdkafka_admin.h +42 -0
- package/deps/librdkafka/src/rdkafka_broker.c +463 -312
- package/deps/librdkafka/src/rdkafka_broker.h +68 -10
- package/deps/librdkafka/src/rdkafka_buf.c +8 -5
- package/deps/librdkafka/src/rdkafka_buf.h +4 -3
- package/deps/librdkafka/src/rdkafka_cert.c +25 -1
- package/deps/librdkafka/src/rdkafka_cert.h +4 -3
- package/deps/librdkafka/src/rdkafka_cgrp.c +468 -143
- package/deps/librdkafka/src/rdkafka_cgrp.h +36 -2
- package/deps/librdkafka/src/rdkafka_conf.c +526 -102
- package/deps/librdkafka/src/rdkafka_conf.h +68 -4
- package/deps/librdkafka/src/rdkafka_feature.c +472 -35
- package/deps/librdkafka/src/rdkafka_feature.h +2 -0
- package/deps/librdkafka/src/rdkafka_fetcher.c +22 -2
- package/deps/librdkafka/src/rdkafka_fetcher.h +2 -2
- package/deps/librdkafka/src/rdkafka_int.h +84 -46
- package/deps/librdkafka/src/rdkafka_metadata.c +221 -136
- package/deps/librdkafka/src/rdkafka_metadata.h +15 -11
- package/deps/librdkafka/src/rdkafka_metadata_cache.c +279 -73
- package/deps/librdkafka/src/rdkafka_mock.c +795 -19
- package/deps/librdkafka/src/rdkafka_mock.h +119 -0
- package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1298 -132
- package/deps/librdkafka/src/rdkafka_mock_handlers.c +345 -49
- package/deps/librdkafka/src/rdkafka_mock_int.h +180 -61
- package/deps/librdkafka/src/rdkafka_msg.c +35 -19
- package/deps/librdkafka/src/rdkafka_msg.h +3 -3
- package/deps/librdkafka/src/rdkafka_msgset_writer.c +14 -10
- package/deps/librdkafka/src/rdkafka_offset.c +33 -5
- package/deps/librdkafka/src/rdkafka_op.c +1 -1
- package/deps/librdkafka/src/rdkafka_op.h +45 -21
- package/deps/librdkafka/src/rdkafka_partition.c +118 -23
- package/deps/librdkafka/src/rdkafka_partition.h +16 -7
- package/deps/librdkafka/src/rdkafka_proto.h +4 -1
- package/deps/librdkafka/src/rdkafka_protocol.h +1 -0
- package/deps/librdkafka/src/rdkafka_queue.c +125 -48
- package/deps/librdkafka/src/rdkafka_queue.h +19 -0
- package/deps/librdkafka/src/rdkafka_range_assignor.c +1 -1
- package/deps/librdkafka/src/rdkafka_request.c +336 -64
- package/deps/librdkafka/src/rdkafka_request.h +24 -1
- package/deps/librdkafka/src/rdkafka_sasl.c +5 -3
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +14 -10
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1166 -89
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +13 -3
- package/deps/librdkafka/src/rdkafka_sasl_plain.c +3 -3
- package/deps/librdkafka/src/rdkafka_sasl_scram.c +4 -3
- package/deps/librdkafka/src/rdkafka_ssl.c +306 -81
- package/deps/librdkafka/src/rdkafka_ssl.h +22 -0
- package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4 -0
- package/deps/librdkafka/src/rdkafka_telemetry.c +80 -23
- package/deps/librdkafka/src/rdkafka_telemetry_encode.c +5 -1
- package/deps/librdkafka/src/rdkafka_telemetry_encode.h +20 -20
- package/deps/librdkafka/src/rdkafka_topic.c +220 -137
- package/deps/librdkafka/src/rdkafka_topic.h +14 -8
- package/deps/librdkafka/src/rdkafka_transport.c +59 -47
- package/deps/librdkafka/src/rdkafka_transport.h +5 -0
- package/deps/librdkafka/src/rdkafka_txnmgr.c +6 -1
- package/deps/librdkafka/src/rdmap.c +6 -1
- package/deps/librdkafka/src/rdrand.c +11 -1
- package/deps/librdkafka/src/rdtime.h +48 -17
- package/deps/librdkafka/src/rdunittest.c +42 -25
- package/deps/librdkafka/src/rdunittest.h +2 -0
- package/deps/librdkafka/src/rdwin32.h +1 -1
- package/deps/librdkafka/src/regexp.c +47 -42
- package/deps/librdkafka/src/tinycthread_extra.c +45 -21
- package/deps/librdkafka/src/tinycthread_extra.h +7 -3
- package/deps/librdkafka/src-cpp/rdkafkacpp.h +28 -2
- package/deps/librdkafka/tests/0001-multiobj.c +4 -0
- package/deps/librdkafka/tests/0004-conf.c +103 -36
- package/deps/librdkafka/tests/0009-mock_cluster.c +1 -0
- package/deps/librdkafka/tests/0011-produce_batch.c +2 -1
- package/deps/librdkafka/tests/0016-client_swname.c +18 -3
- package/deps/librdkafka/tests/0017-compression.c +6 -8
- package/deps/librdkafka/tests/0018-cgrp_term.c +8 -3
- package/deps/librdkafka/tests/0021-rkt_destroy.c +1 -0
- package/deps/librdkafka/tests/0022-consume_batch.c +4 -1
- package/deps/librdkafka/tests/0026-consume_pause.c +12 -14
- package/deps/librdkafka/tests/0028-long_topicnames.c +1 -1
- package/deps/librdkafka/tests/0029-assign_offset.c +6 -8
- package/deps/librdkafka/tests/0030-offset_commit.c +2 -2
- package/deps/librdkafka/tests/0033-regex_subscribe.c +33 -17
- package/deps/librdkafka/tests/0034-offset_reset.c +25 -4
- package/deps/librdkafka/tests/0036-partial_fetch.c +1 -0
- package/deps/librdkafka/tests/0038-performance.c +1 -0
- package/deps/librdkafka/tests/0040-io_event.c +11 -5
- package/deps/librdkafka/tests/0041-fetch_max_bytes.c +1 -0
- package/deps/librdkafka/tests/0044-partition_cnt.c +3 -2
- package/deps/librdkafka/tests/0045-subscribe_update.c +284 -20
- package/deps/librdkafka/tests/0047-partial_buf_tmout.c +1 -0
- package/deps/librdkafka/tests/0048-partitioner.c +1 -1
- package/deps/librdkafka/tests/0050-subscribe_adds.c +1 -0
- package/deps/librdkafka/tests/0051-assign_adds.c +1 -0
- package/deps/librdkafka/tests/0052-msg_timestamps.c +22 -4
- package/deps/librdkafka/tests/0053-stats_cb.cpp +12 -20
- package/deps/librdkafka/tests/0055-producer_latency.c +176 -3
- package/deps/librdkafka/tests/0056-balanced_group_mt.c +6 -2
- package/deps/librdkafka/tests/0058-log.cpp +3 -3
- package/deps/librdkafka/tests/0059-bsearch.cpp +8 -4
- package/deps/librdkafka/tests/0061-consumer_lag.cpp +25 -5
- package/deps/librdkafka/tests/0067-empty_topic.cpp +3 -0
- package/deps/librdkafka/tests/0068-produce_timeout.c +21 -23
- package/deps/librdkafka/tests/0069-consumer_add_parts.c +3 -7
- package/deps/librdkafka/tests/0075-retry.c +38 -1
- package/deps/librdkafka/tests/0076-produce_retry.c +2 -0
- package/deps/librdkafka/tests/0077-compaction.c +8 -2
- package/deps/librdkafka/tests/0080-admin_ut.c +34 -4
- package/deps/librdkafka/tests/0081-admin.c +455 -155
- package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +4 -0
- package/deps/librdkafka/tests/0083-cb_event.c +8 -3
- package/deps/librdkafka/tests/0084-destroy_flags.c +14 -18
- package/deps/librdkafka/tests/0085-headers.cpp +4 -0
- package/deps/librdkafka/tests/0086-purge.c +40 -7
- package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +1 -1
- package/deps/librdkafka/tests/0089-max_poll_interval.c +12 -7
- package/deps/librdkafka/tests/0090-idempotence.c +1 -2
- package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +5 -7
- package/deps/librdkafka/tests/0092-mixed_msgver.c +6 -0
- package/deps/librdkafka/tests/0093-holb.c +8 -5
- package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +1 -0
- package/deps/librdkafka/tests/0097-ssl_verify.cpp +262 -70
- package/deps/librdkafka/tests/0098-consumer-txn.cpp +16 -16
- package/deps/librdkafka/tests/0099-commit_metadata.c +1 -1
- package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +1 -1
- package/deps/librdkafka/tests/0102-static_group_rebalance.c +317 -16
- package/deps/librdkafka/tests/0103-transactions.c +7 -7
- package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +1 -0
- package/deps/librdkafka/tests/0105-transactions_mock.c +18 -11
- package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +35 -14
- package/deps/librdkafka/tests/0107-topic_recreate.c +2 -2
- package/deps/librdkafka/tests/0109-auto_create_topics.cpp +86 -26
- package/deps/librdkafka/tests/0110-batch_size.cpp +1 -2
- package/deps/librdkafka/tests/0112-assign_unknown_part.c +3 -14
- package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +248 -104
- package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +3 -3
- package/deps/librdkafka/tests/0115-producer_auth.cpp +4 -1
- package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +7 -5
- package/deps/librdkafka/tests/0117-mock_errors.c +15 -5
- package/deps/librdkafka/tests/0118-commit_rebalance.c +41 -8
- package/deps/librdkafka/tests/0119-consumer_auth.cpp +20 -1
- package/deps/librdkafka/tests/0120-asymmetric_subscription.c +8 -3
- package/deps/librdkafka/tests/0125-immediate_flush.c +1 -1
- package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +323 -8
- package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +1 -0
- package/deps/librdkafka/tests/0132-strategy_ordering.c +12 -4
- package/deps/librdkafka/tests/0133-ssl_keys.c +28 -6
- package/deps/librdkafka/tests/0137-barrier_batch_consume.c +24 -14
- package/deps/librdkafka/tests/0139-offset_validation_mock.c +510 -2
- package/deps/librdkafka/tests/0140-commit_metadata.cpp +1 -1
- package/deps/librdkafka/tests/0142-reauthentication.c +37 -17
- package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +39 -40
- package/deps/librdkafka/tests/0146-metadata_mock.c +76 -15
- package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +952 -0
- package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +563 -0
- package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
- package/deps/librdkafka/tests/0150-telemetry_mock.c +9 -6
- package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
- package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
- package/deps/librdkafka/tests/0153-memberid.c +128 -0
- package/deps/librdkafka/tests/CMakeLists.txt +6 -0
- package/deps/librdkafka/tests/LibrdkafkaTestApp.py +34 -9
- package/deps/librdkafka/tests/autotest.sh +0 -0
- package/deps/librdkafka/tests/broker_version_tests.py +0 -0
- package/deps/librdkafka/tests/buildbox.sh +0 -0
- package/deps/librdkafka/tests/cleanup-checker-tests.sh +0 -0
- package/deps/librdkafka/tests/cluster_testing.py +0 -0
- package/deps/librdkafka/tests/delete-test-topics.sh +0 -0
- package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +42 -101
- package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.key +41 -29
- package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +112 -37
- package/deps/librdkafka/tests/gen-ssl-certs.sh +0 -0
- package/deps/librdkafka/tests/interactive_broker_version.py +0 -0
- package/deps/librdkafka/tests/java/Makefile +2 -1
- package/deps/librdkafka/tests/java/run-class.sh +0 -0
- package/deps/librdkafka/tests/lz4_manual_test.sh +0 -0
- package/deps/librdkafka/tests/multi-broker-version-test.sh +0 -0
- package/deps/librdkafka/tests/parse-refcnt.sh +0 -0
- package/deps/librdkafka/tests/performance_plot.py +0 -0
- package/deps/librdkafka/tests/requirements.txt +1 -1
- package/deps/librdkafka/tests/run-all-tests.sh +79 -0
- package/deps/librdkafka/tests/run-consumer-tests.sh +0 -0
- package/deps/librdkafka/tests/run-producer-tests.sh +0 -0
- package/deps/librdkafka/tests/run-test-batches.py +157 -0
- package/deps/librdkafka/tests/run-test.sh +0 -0
- package/deps/librdkafka/tests/sasl_test.py +0 -0
- package/deps/librdkafka/tests/test.c +478 -18
- package/deps/librdkafka/tests/test.h +62 -13
- package/deps/librdkafka/tests/testcpp.cpp +6 -1
- package/deps/librdkafka/tests/testcpp.h +30 -2
- package/deps/librdkafka/tests/testshared.h +16 -2
- package/deps/librdkafka/tests/tools/stats/graph.py +0 -0
- package/deps/librdkafka/tests/tools/stats/to_csv.py +1 -1
- package/deps/librdkafka/tests/trivup/trivup-0.14.0.tar.gz +0 -0
- package/deps/librdkafka/tests/until-fail.sh +0 -0
- package/deps/librdkafka/tests/xxxx-metadata.cpp +1 -1
- package/deps/librdkafka/vcpkg.json +1 -1
- package/deps/librdkafka/win32/setup-msys2.ps1 +24 -8
- package/deps/librdkafka/win32/setup-vcpkg.ps1 +28 -6
- package/deps/librdkafka/win32/tests/tests.vcxproj +6 -0
- package/deps/librdkafka/win32/wingetopt.h +5 -4
- package/errors.d.ts +27 -1
- package/lib/error.js +29 -3
- package/make_docs.sh +0 -0
- package/package.json +11 -11
- package/run_docker.sh +0 -0
- package/src/callbacks.cc +6 -9
- package/src/callbacks.h +1 -5
- package/test/kafka-consumer-worker.js +10 -7
- package/test/kafka-consumer.spec.js +32 -21
- package/ci/update-version.js +0 -123
- package/deps/librdkafka/.semaphore/project.yml +0 -43
- package/deps/librdkafka/.semaphore/project_public.yml +0 -20
- package/deps/librdkafka/win32/install-openssl.ps1 +0 -33
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
#include "rdkafka_mock_int.h"
|
|
40
40
|
#include "rdkafka_transport_int.h"
|
|
41
41
|
#include "rdkafka_mock.h"
|
|
42
|
+
#include "rdunittest.h"
|
|
43
|
+
|
|
42
44
|
#include <stdarg.h>
|
|
43
45
|
|
|
44
46
|
typedef struct rd_kafka_mock_request_s rd_kafka_mock_request_t;
|
|
@@ -47,6 +49,8 @@ static void rd_kafka_mock_cluster_destroy0(rd_kafka_mock_cluster_t *mcluster);
|
|
|
47
49
|
static rd_kafka_mock_request_t *
|
|
48
50
|
rd_kafka_mock_request_new(int32_t id, int16_t api_key, int64_t timestamp_us);
|
|
49
51
|
static void rd_kafka_mock_request_free(void *element);
|
|
52
|
+
static void rd_kafka_mock_coord_remove(rd_kafka_mock_cluster_t *mcluster,
|
|
53
|
+
int32_t broker_id);
|
|
50
54
|
|
|
51
55
|
static rd_kafka_mock_broker_t *
|
|
52
56
|
rd_kafka_mock_broker_find(const rd_kafka_mock_cluster_t *mcluster,
|
|
@@ -435,16 +439,22 @@ rd_kafka_mock_partition_assign_replicas(rd_kafka_mock_partition_t *mpart,
|
|
|
435
439
|
int replica_cnt = RD_MIN(replication_factor, mcluster->broker_cnt);
|
|
436
440
|
rd_kafka_mock_broker_t *mrkb;
|
|
437
441
|
int i = 0;
|
|
438
|
-
int first_replica
|
|
439
|
-
(mpart->id * replication_factor) % mcluster->broker_cnt;
|
|
442
|
+
int first_replica;
|
|
440
443
|
int skipped = 0;
|
|
441
444
|
|
|
442
445
|
if (mpart->replicas)
|
|
443
446
|
rd_free(mpart->replicas);
|
|
444
447
|
|
|
445
|
-
mpart->replicas =
|
|
448
|
+
mpart->replicas = replica_cnt
|
|
449
|
+
? rd_calloc(replica_cnt, sizeof(*mpart->replicas))
|
|
450
|
+
: NULL;
|
|
446
451
|
mpart->replica_cnt = replica_cnt;
|
|
452
|
+
if (replica_cnt == 0) {
|
|
453
|
+
rd_kafka_mock_partition_set_leader0(mpart, NULL);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
447
456
|
|
|
457
|
+
first_replica = (mpart->id * replication_factor) % mcluster->broker_cnt;
|
|
448
458
|
|
|
449
459
|
/* Use a predictable, determininistic order on a per-topic basis.
|
|
450
460
|
*
|
|
@@ -918,6 +928,23 @@ static void rd_kafka_mock_cluster_io_add(rd_kafka_mock_cluster_t *mcluster,
|
|
|
918
928
|
mcluster->fd_cnt++;
|
|
919
929
|
}
|
|
920
930
|
|
|
931
|
+
/**
|
|
932
|
+
* @brief Reassign partition replicas to broker, after deleting or
|
|
933
|
+
* adding a new one.
|
|
934
|
+
*/
|
|
935
|
+
static void
|
|
936
|
+
rd_kafka_mock_cluster_reassign_partitions(rd_kafka_mock_cluster_t *mcluster) {
|
|
937
|
+
rd_kafka_mock_topic_t *mtopic;
|
|
938
|
+
TAILQ_FOREACH(mtopic, &mcluster->topics, link) {
|
|
939
|
+
int i;
|
|
940
|
+
for (i = 0; i < mtopic->partition_cnt; i++) {
|
|
941
|
+
rd_kafka_mock_partition_t *mpart =
|
|
942
|
+
&mtopic->partitions[i];
|
|
943
|
+
rd_kafka_mock_partition_assign_replicas(
|
|
944
|
+
mpart, mpart->replica_cnt);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
921
948
|
|
|
922
949
|
static void rd_kafka_mock_connection_close(rd_kafka_mock_connection_t *mconn,
|
|
923
950
|
const char *reason) {
|
|
@@ -1335,8 +1362,14 @@ static void rd_kafka_mock_connection_io(rd_kafka_mock_cluster_t *mcluster,
|
|
|
1335
1362
|
}
|
|
1336
1363
|
}
|
|
1337
1364
|
|
|
1338
|
-
if (events &
|
|
1339
|
-
rd_kafka_mock_connection_close(mconn,
|
|
1365
|
+
if (events & POLLERR) {
|
|
1366
|
+
rd_kafka_mock_connection_close(mconn,
|
|
1367
|
+
"Disconnected: "
|
|
1368
|
+
"Error condition");
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
if (events & POLLHUP) {
|
|
1372
|
+
rd_kafka_mock_connection_close(mconn, "Disconnected: Hang up");
|
|
1340
1373
|
return;
|
|
1341
1374
|
}
|
|
1342
1375
|
|
|
@@ -1564,6 +1597,8 @@ static void rd_kafka_mock_broker_destroy(rd_kafka_mock_broker_t *mrkb) {
|
|
|
1564
1597
|
if (mrkb->rack)
|
|
1565
1598
|
rd_free(mrkb->rack);
|
|
1566
1599
|
|
|
1600
|
+
rd_kafka_mock_coord_remove(mrkb->cluster, mrkb->id);
|
|
1601
|
+
|
|
1567
1602
|
TAILQ_REMOVE(&mrkb->cluster->brokers, mrkb, link);
|
|
1568
1603
|
mrkb->cluster->broker_cnt--;
|
|
1569
1604
|
|
|
@@ -1571,6 +1606,30 @@ static void rd_kafka_mock_broker_destroy(rd_kafka_mock_broker_t *mrkb) {
|
|
|
1571
1606
|
}
|
|
1572
1607
|
|
|
1573
1608
|
|
|
1609
|
+
rd_kafka_resp_err_t
|
|
1610
|
+
rd_kafka_mock_broker_decommission(rd_kafka_mock_cluster_t *mcluster,
|
|
1611
|
+
int32_t broker_id) {
|
|
1612
|
+
rd_kafka_op_t *rko = rd_kafka_op_new(RD_KAFKA_OP_MOCK);
|
|
1613
|
+
|
|
1614
|
+
rko->rko_u.mock.broker_id = broker_id;
|
|
1615
|
+
rko->rko_u.mock.cmd = RD_KAFKA_MOCK_CMD_BROKER_DECOMMISSION;
|
|
1616
|
+
|
|
1617
|
+
return rd_kafka_op_err_destroy(
|
|
1618
|
+
rd_kafka_op_req(mcluster->ops, rko, RD_POLL_INFINITE));
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
rd_kafka_resp_err_t rd_kafka_mock_broker_add(rd_kafka_mock_cluster_t *mcluster,
|
|
1622
|
+
int32_t broker_id) {
|
|
1623
|
+
rd_kafka_op_t *rko = rd_kafka_op_new(RD_KAFKA_OP_MOCK);
|
|
1624
|
+
|
|
1625
|
+
rko->rko_u.mock.broker_id = broker_id;
|
|
1626
|
+
rko->rko_u.mock.cmd = RD_KAFKA_MOCK_CMD_BROKER_ADD;
|
|
1627
|
+
|
|
1628
|
+
return rd_kafka_op_err_destroy(
|
|
1629
|
+
rd_kafka_op_req(mcluster->ops, rko, RD_POLL_INFINITE));
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
|
|
1574
1633
|
/**
|
|
1575
1634
|
* @brief Starts listening on the mock broker socket.
|
|
1576
1635
|
*
|
|
@@ -1664,16 +1723,28 @@ static int rd_kafka_mock_broker_new_listener(rd_kafka_mock_cluster_t *mcluster,
|
|
|
1664
1723
|
|
|
1665
1724
|
|
|
1666
1725
|
static rd_kafka_mock_broker_t *
|
|
1667
|
-
rd_kafka_mock_broker_new(rd_kafka_mock_cluster_t *mcluster,
|
|
1726
|
+
rd_kafka_mock_broker_new(rd_kafka_mock_cluster_t *mcluster,
|
|
1727
|
+
int32_t broker_id,
|
|
1728
|
+
rd_kafka_resp_err_t *err) {
|
|
1668
1729
|
rd_kafka_mock_broker_t *mrkb;
|
|
1669
1730
|
rd_socket_t listen_s;
|
|
1670
1731
|
struct sockaddr_in sin = {
|
|
1671
1732
|
.sin_family = AF_INET,
|
|
1672
1733
|
.sin_addr = {.s_addr = htonl(INADDR_LOOPBACK)}};
|
|
1673
1734
|
|
|
1735
|
+
if (rd_kafka_mock_broker_find(mcluster, broker_id)) {
|
|
1736
|
+
if (err)
|
|
1737
|
+
*err = RD_KAFKA_RESP_ERR__INVALID_ARG;
|
|
1738
|
+
/* A broker with this id already exists. */
|
|
1739
|
+
return NULL;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1674
1742
|
listen_s = rd_kafka_mock_broker_new_listener(mcluster, &sin);
|
|
1675
|
-
if (listen_s == -1)
|
|
1743
|
+
if (listen_s == -1) {
|
|
1744
|
+
if (err)
|
|
1745
|
+
*err = RD_KAFKA_RESP_ERR__TRANSPORT;
|
|
1676
1746
|
return NULL;
|
|
1747
|
+
}
|
|
1677
1748
|
|
|
1678
1749
|
/*
|
|
1679
1750
|
* Create mock broker object
|
|
@@ -1698,6 +1769,8 @@ rd_kafka_mock_broker_new(rd_kafka_mock_cluster_t *mcluster, int32_t broker_id) {
|
|
|
1698
1769
|
|
|
1699
1770
|
if (rd_kafka_mock_broker_start_listener(mrkb) == -1) {
|
|
1700
1771
|
rd_kafka_mock_broker_destroy(mrkb);
|
|
1772
|
+
if (err)
|
|
1773
|
+
*err = RD_KAFKA_RESP_ERR__TRANSPORT;
|
|
1701
1774
|
return NULL;
|
|
1702
1775
|
}
|
|
1703
1776
|
|
|
@@ -1806,6 +1879,20 @@ rd_kafka_mock_coord_set(rd_kafka_mock_cluster_t *mcluster,
|
|
|
1806
1879
|
return mcoord;
|
|
1807
1880
|
}
|
|
1808
1881
|
|
|
1882
|
+
/**
|
|
1883
|
+
* @brief Remove coordinator by broker id.
|
|
1884
|
+
*/
|
|
1885
|
+
void rd_kafka_mock_coord_remove(rd_kafka_mock_cluster_t *mcluster,
|
|
1886
|
+
int32_t broker_id) {
|
|
1887
|
+
rd_kafka_mock_coord_t *mcoord, *tmp;
|
|
1888
|
+
|
|
1889
|
+
TAILQ_FOREACH_SAFE(mcoord, &mcluster->coords, link, tmp) {
|
|
1890
|
+
if (mcoord->broker_id == broker_id) {
|
|
1891
|
+
rd_kafka_mock_coord_destroy(mcluster, mcoord);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1809
1896
|
|
|
1810
1897
|
/**
|
|
1811
1898
|
* @brief Remove and return the next error, or RD_KAFKA_RESP_ERR_NO_ERROR
|
|
@@ -2205,6 +2292,31 @@ rd_kafka_mock_broker_set_rack(rd_kafka_mock_cluster_t *mcluster,
|
|
|
2205
2292
|
rd_kafka_op_req(mcluster->ops, rko, RD_POLL_INFINITE));
|
|
2206
2293
|
}
|
|
2207
2294
|
|
|
2295
|
+
void rd_kafka_mock_broker_set_host_port(rd_kafka_mock_cluster_t *cluster,
|
|
2296
|
+
int32_t broker_id,
|
|
2297
|
+
const char *host,
|
|
2298
|
+
int port) {
|
|
2299
|
+
rd_kafka_mock_broker_t *mrkb;
|
|
2300
|
+
|
|
2301
|
+
mtx_lock(&cluster->lock);
|
|
2302
|
+
TAILQ_FOREACH(mrkb, &cluster->brokers, link) {
|
|
2303
|
+
if (mrkb->id == broker_id) {
|
|
2304
|
+
rd_kafka_dbg(
|
|
2305
|
+
cluster->rk, MOCK, "MOCK",
|
|
2306
|
+
"Broker %" PRId32
|
|
2307
|
+
": Setting advertised listener from %s:%d to %s:%d",
|
|
2308
|
+
broker_id, mrkb->advertised_listener, mrkb->port,
|
|
2309
|
+
host, port);
|
|
2310
|
+
rd_snprintf(mrkb->advertised_listener,
|
|
2311
|
+
sizeof(mrkb->advertised_listener), "%s",
|
|
2312
|
+
host);
|
|
2313
|
+
mrkb->port = port;
|
|
2314
|
+
break;
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
mtx_unlock(&cluster->lock);
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2208
2320
|
rd_kafka_resp_err_t
|
|
2209
2321
|
rd_kafka_mock_coordinator_set(rd_kafka_mock_cluster_t *mcluster,
|
|
2210
2322
|
const char *key_type,
|
|
@@ -2326,6 +2438,11 @@ rd_kafka_mock_broker_cmd(rd_kafka_mock_cluster_t *mcluster,
|
|
|
2326
2438
|
mrkb->rack = NULL;
|
|
2327
2439
|
break;
|
|
2328
2440
|
|
|
2441
|
+
case RD_KAFKA_MOCK_CMD_BROKER_DECOMMISSION:
|
|
2442
|
+
rd_kafka_mock_broker_destroy(mrkb);
|
|
2443
|
+
rd_kafka_mock_cluster_reassign_partitions(mcluster);
|
|
2444
|
+
break;
|
|
2445
|
+
|
|
2329
2446
|
default:
|
|
2330
2447
|
RD_BUG("Unhandled mock cmd %d", rko->rko_u.mock.cmd);
|
|
2331
2448
|
break;
|
|
@@ -2380,6 +2497,7 @@ rd_kafka_mock_cluster_cmd(rd_kafka_mock_cluster_t *mcluster,
|
|
|
2380
2497
|
rd_kafka_mock_partition_t *mpart;
|
|
2381
2498
|
rd_kafka_mock_broker_t *mrkb;
|
|
2382
2499
|
size_t i;
|
|
2500
|
+
rd_kafka_resp_err_t err;
|
|
2383
2501
|
|
|
2384
2502
|
switch (rko->rko_u.mock.cmd) {
|
|
2385
2503
|
case RD_KAFKA_MOCK_CMD_TOPIC_CREATE:
|
|
@@ -2490,8 +2608,16 @@ rd_kafka_mock_cluster_cmd(rd_kafka_mock_cluster_t *mcluster,
|
|
|
2490
2608
|
case RD_KAFKA_MOCK_CMD_BROKER_SET_UPDOWN:
|
|
2491
2609
|
case RD_KAFKA_MOCK_CMD_BROKER_SET_RTT:
|
|
2492
2610
|
case RD_KAFKA_MOCK_CMD_BROKER_SET_RACK:
|
|
2611
|
+
case RD_KAFKA_MOCK_CMD_BROKER_DECOMMISSION:
|
|
2493
2612
|
return rd_kafka_mock_brokers_cmd(mcluster, rko);
|
|
2494
2613
|
|
|
2614
|
+
case RD_KAFKA_MOCK_CMD_BROKER_ADD:
|
|
2615
|
+
if (!rd_kafka_mock_broker_new(mcluster,
|
|
2616
|
+
rko->rko_u.mock.broker_id, &err))
|
|
2617
|
+
return err;
|
|
2618
|
+
|
|
2619
|
+
rd_kafka_mock_cluster_reassign_partitions(mcluster);
|
|
2620
|
+
break;
|
|
2495
2621
|
case RD_KAFKA_MOCK_CMD_COORD_SET:
|
|
2496
2622
|
if (!rd_kafka_mock_coord_set(mcluster, rko->rko_u.mock.name,
|
|
2497
2623
|
rko->rko_u.mock.str,
|
|
@@ -2578,7 +2704,8 @@ rd_kafka_mock_cluster_op_serve(rd_kafka_t *rk,
|
|
|
2578
2704
|
static void rd_kafka_mock_cluster_destroy0(rd_kafka_mock_cluster_t *mcluster) {
|
|
2579
2705
|
rd_kafka_mock_topic_t *mtopic;
|
|
2580
2706
|
rd_kafka_mock_broker_t *mrkb;
|
|
2581
|
-
|
|
2707
|
+
rd_kafka_mock_cgrp_classic_t *mcgrp_classic;
|
|
2708
|
+
rd_kafka_mock_cgrp_consumer_t *mcgrp_consumer;
|
|
2582
2709
|
rd_kafka_mock_coord_t *mcoord;
|
|
2583
2710
|
rd_kafka_mock_error_stack_t *errstack;
|
|
2584
2711
|
thrd_t dummy_rkb_thread;
|
|
@@ -2591,8 +2718,11 @@ static void rd_kafka_mock_cluster_destroy0(rd_kafka_mock_cluster_t *mcluster) {
|
|
|
2591
2718
|
while ((mrkb = TAILQ_FIRST(&mcluster->brokers)))
|
|
2592
2719
|
rd_kafka_mock_broker_destroy(mrkb);
|
|
2593
2720
|
|
|
2594
|
-
while ((
|
|
2595
|
-
|
|
2721
|
+
while ((mcgrp_classic = TAILQ_FIRST(&mcluster->cgrps_classic)))
|
|
2722
|
+
rd_kafka_mock_cgrp_classic_destroy(mcgrp_classic);
|
|
2723
|
+
|
|
2724
|
+
while ((mcgrp_consumer = TAILQ_FIRST(&mcluster->cgrps_consumer)))
|
|
2725
|
+
rd_kafka_mock_cgrp_consumer_destroy(mcgrp_consumer);
|
|
2596
2726
|
|
|
2597
2727
|
while ((mcoord = TAILQ_FIRST(&mcluster->coords)))
|
|
2598
2728
|
rd_kafka_mock_coord_destroy(mcluster, mcoord);
|
|
@@ -2606,16 +2736,16 @@ static void rd_kafka_mock_cluster_destroy0(rd_kafka_mock_cluster_t *mcluster) {
|
|
|
2606
2736
|
|
|
2607
2737
|
rd_list_destroy(&mcluster->request_list);
|
|
2608
2738
|
|
|
2739
|
+
dummy_rkb_thread = mcluster->dummy_rkb->rkb_thread;
|
|
2740
|
+
|
|
2609
2741
|
/*
|
|
2610
|
-
* Destroy dummy broker
|
|
2742
|
+
* Destroy dummy broker.
|
|
2743
|
+
* WARNING: This is last time we can read
|
|
2744
|
+
* from dummy_rkb in this thread!
|
|
2611
2745
|
*/
|
|
2612
2746
|
rd_kafka_q_enq(mcluster->dummy_rkb->rkb_ops,
|
|
2613
2747
|
rd_kafka_op_new(RD_KAFKA_OP_TERMINATE));
|
|
2614
2748
|
|
|
2615
|
-
dummy_rkb_thread = mcluster->dummy_rkb->rkb_thread;
|
|
2616
|
-
|
|
2617
|
-
rd_kafka_broker_destroy(mcluster->dummy_rkb);
|
|
2618
|
-
|
|
2619
2749
|
if (thrd_join(dummy_rkb_thread, &ret) != thrd_success)
|
|
2620
2750
|
rd_assert(!*"failed to join mock dummy broker thread");
|
|
2621
2751
|
|
|
@@ -2688,7 +2818,7 @@ rd_kafka_mock_cluster_t *rd_kafka_mock_cluster_new(rd_kafka_t *rk,
|
|
|
2688
2818
|
TAILQ_INIT(&mcluster->brokers);
|
|
2689
2819
|
|
|
2690
2820
|
for (i = 1; i <= broker_cnt; i++) {
|
|
2691
|
-
if (!(mrkb = rd_kafka_mock_broker_new(mcluster, i))) {
|
|
2821
|
+
if (!(mrkb = rd_kafka_mock_broker_new(mcluster, i, NULL))) {
|
|
2692
2822
|
rd_kafka_mock_cluster_destroy(mcluster);
|
|
2693
2823
|
return NULL;
|
|
2694
2824
|
}
|
|
@@ -2702,10 +2832,14 @@ rd_kafka_mock_cluster_t *rd_kafka_mock_cluster_new(rd_kafka_t *rk,
|
|
|
2702
2832
|
TAILQ_INIT(&mcluster->topics);
|
|
2703
2833
|
mcluster->defaults.partition_cnt = 4;
|
|
2704
2834
|
mcluster->defaults.replication_factor = RD_MIN(3, broker_cnt);
|
|
2705
|
-
mcluster->defaults.group_initial_rebalance_delay_ms
|
|
2706
|
-
mcluster->track_requests
|
|
2835
|
+
mcluster->defaults.group_initial_rebalance_delay_ms = 3000;
|
|
2836
|
+
mcluster->track_requests = rd_false;
|
|
2837
|
+
mcluster->defaults.group_consumer_session_timeout_ms = 30000;
|
|
2838
|
+
mcluster->defaults.group_consumer_heartbeat_interval_ms = 3000;
|
|
2839
|
+
|
|
2840
|
+
TAILQ_INIT(&mcluster->cgrps_classic);
|
|
2707
2841
|
|
|
2708
|
-
TAILQ_INIT(&mcluster->
|
|
2842
|
+
TAILQ_INIT(&mcluster->cgrps_consumer);
|
|
2709
2843
|
|
|
2710
2844
|
TAILQ_INIT(&mcluster->coords);
|
|
2711
2845
|
|
|
@@ -2883,3 +3017,645 @@ int16_t rd_kafka_mock_request_api_key(rd_kafka_mock_request_t *mreq) {
|
|
|
2883
3017
|
rd_ts_t rd_kafka_mock_request_timestamp(rd_kafka_mock_request_t *mreq) {
|
|
2884
3018
|
return mreq->timestamp;
|
|
2885
3019
|
}
|
|
3020
|
+
|
|
3021
|
+
/* Unit tests */
|
|
3022
|
+
|
|
3023
|
+
/**
|
|
3024
|
+
* @brief Create a topic-partition list with vararg arguments.
|
|
3025
|
+
*
|
|
3026
|
+
* @param cnt Number of topic-partitions.
|
|
3027
|
+
* @param ...vararg is a tuple of:
|
|
3028
|
+
* const char *topic_name
|
|
3029
|
+
* int32_t partition
|
|
3030
|
+
*
|
|
3031
|
+
* @remark The returned pointer ownership is transferred to the caller.
|
|
3032
|
+
*/
|
|
3033
|
+
static rd_kafka_topic_partition_list_t *ut_topic_partitions(int cnt, ...) {
|
|
3034
|
+
va_list ap;
|
|
3035
|
+
const char *topic_name;
|
|
3036
|
+
int i = 0;
|
|
3037
|
+
|
|
3038
|
+
rd_kafka_topic_partition_list_t *rktparlist =
|
|
3039
|
+
rd_kafka_topic_partition_list_new(cnt);
|
|
3040
|
+
va_start(ap, cnt);
|
|
3041
|
+
while (i < cnt) {
|
|
3042
|
+
topic_name = va_arg(ap, const char *);
|
|
3043
|
+
int32_t partition = va_arg(ap, int32_t);
|
|
3044
|
+
|
|
3045
|
+
rd_kafka_topic_partition_list_add(rktparlist, topic_name,
|
|
3046
|
+
partition);
|
|
3047
|
+
i++;
|
|
3048
|
+
}
|
|
3049
|
+
va_end(ap);
|
|
3050
|
+
|
|
3051
|
+
return rktparlist;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
3054
|
+
/**
|
|
3055
|
+
* @brief Assert \p expected partition list is equal to \p actual.
|
|
3056
|
+
*
|
|
3057
|
+
* @param expected Expected partition list.
|
|
3058
|
+
* @param actual Actual partition list.
|
|
3059
|
+
* @return Comparation result.
|
|
3060
|
+
*/
|
|
3061
|
+
static int ut_assert_topic_partitions(rd_kafka_topic_partition_list_t *expected,
|
|
3062
|
+
rd_kafka_topic_partition_list_t *actual) {
|
|
3063
|
+
rd_bool_t equal;
|
|
3064
|
+
char expected_str[256] = "";
|
|
3065
|
+
char actual_str[256] = "";
|
|
3066
|
+
|
|
3067
|
+
if (expected)
|
|
3068
|
+
RD_UT_ASSERT(actual, "list should be not-NULL, but it's NULL");
|
|
3069
|
+
else
|
|
3070
|
+
RD_UT_ASSERT(!actual, "list should be NULL, but it's not-NULL");
|
|
3071
|
+
|
|
3072
|
+
|
|
3073
|
+
if (!expected)
|
|
3074
|
+
return 0;
|
|
3075
|
+
|
|
3076
|
+
equal = !rd_kafka_topic_partition_list_cmp(
|
|
3077
|
+
actual, expected, rd_kafka_topic_partition_cmp);
|
|
3078
|
+
|
|
3079
|
+
if (!equal) {
|
|
3080
|
+
rd_kafka_topic_partition_list_str(expected, expected_str,
|
|
3081
|
+
sizeof(expected_str),
|
|
3082
|
+
RD_KAFKA_FMT_F_NO_ERR);
|
|
3083
|
+
rd_kafka_topic_partition_list_str(actual, actual_str,
|
|
3084
|
+
sizeof(actual_str),
|
|
3085
|
+
RD_KAFKA_FMT_F_NO_ERR);
|
|
3086
|
+
}
|
|
3087
|
+
|
|
3088
|
+
RD_UT_ASSERT(equal, "list should be equal. Expected: %s, got: %s",
|
|
3089
|
+
expected_str, actual_str);
|
|
3090
|
+
return 0;
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
/**
|
|
3094
|
+
* @struct Fixture used for testing next assignment calculation.
|
|
3095
|
+
*/
|
|
3096
|
+
struct cgrp_consumer_member_next_assignment_fixture {
|
|
3097
|
+
/** Current member epoch (after calling next assignment). */
|
|
3098
|
+
int32_t current_member_epoch;
|
|
3099
|
+
/** Current consumer assignment, if changed. */
|
|
3100
|
+
rd_kafka_topic_partition_list_t *current_assignment;
|
|
3101
|
+
/** Returned assignment, if expected. */
|
|
3102
|
+
rd_kafka_topic_partition_list_t *returned_assignment;
|
|
3103
|
+
/** Target assignment, if changed. */
|
|
3104
|
+
rd_kafka_topic_partition_list_t *target_assignment;
|
|
3105
|
+
/** Should simulate a disconnection and reconnection. */
|
|
3106
|
+
rd_bool_t reconnected;
|
|
3107
|
+
/** Should simulate a session time out. */
|
|
3108
|
+
rd_bool_t session_timed_out;
|
|
3109
|
+
/** Comment to log. */
|
|
3110
|
+
const char *comment;
|
|
3111
|
+
};
|
|
3112
|
+
|
|
3113
|
+
/**
|
|
3114
|
+
* @brief Test next assignment calculation using passed \p fixtures.
|
|
3115
|
+
* using a new cluster with a topic with name \p topic and
|
|
3116
|
+
* \p partitions partitions.
|
|
3117
|
+
*
|
|
3118
|
+
* @param topic Topic name to create.
|
|
3119
|
+
* @param partitions Topic partition.
|
|
3120
|
+
* @param fixtures Array of fixtures for this test.
|
|
3121
|
+
* @param fixtures_cnt Number of elements in \p fixtures.
|
|
3122
|
+
* @return Number of occurred errors.
|
|
3123
|
+
*/
|
|
3124
|
+
static int ut_cgrp_consumer_member_next_assignment0(
|
|
3125
|
+
const char *topic,
|
|
3126
|
+
int partitions,
|
|
3127
|
+
struct cgrp_consumer_member_next_assignment_fixture *fixtures,
|
|
3128
|
+
size_t fixtures_cnt) {
|
|
3129
|
+
int failures = 0;
|
|
3130
|
+
int32_t current_member_epoch = 0;
|
|
3131
|
+
size_t i;
|
|
3132
|
+
rd_kafka_t *rk;
|
|
3133
|
+
rd_kafka_mock_cluster_t *mcluster;
|
|
3134
|
+
static rd_kafka_mock_topic_t *mtopic;
|
|
3135
|
+
rd_kafka_mock_cgrp_consumer_t *mcgrp;
|
|
3136
|
+
rd_kafka_mock_cgrp_consumer_member_t *member;
|
|
3137
|
+
char errstr[512];
|
|
3138
|
+
rd_kafkap_str_t GroupId = {.str = "group", .len = 5};
|
|
3139
|
+
rd_kafkap_str_t MemberId = {.str = "A", .len = 1};
|
|
3140
|
+
rd_kafkap_str_t InstanceId = {.len = -1};
|
|
3141
|
+
rd_kafkap_str_t SubscribedTopic = {.str = topic, .len = strlen(topic)};
|
|
3142
|
+
rd_kafkap_str_t SubscribedTopicRegex = RD_KAFKAP_STR_INITIALIZER_EMPTY;
|
|
3143
|
+
struct rd_kafka_mock_connection_s *conn =
|
|
3144
|
+
(struct rd_kafka_mock_connection_s
|
|
3145
|
+
*)1; /* fake connection instance */
|
|
3146
|
+
|
|
3147
|
+
rk = rd_kafka_new(RD_KAFKA_CONSUMER, NULL, errstr, sizeof(errstr));
|
|
3148
|
+
mcluster = rd_kafka_mock_cluster_new(rk, 1);
|
|
3149
|
+
mcgrp = rd_kafka_mock_cgrp_consumer_get(mcluster, &GroupId);
|
|
3150
|
+
member = rd_kafka_mock_cgrp_consumer_member_add(
|
|
3151
|
+
mcgrp, conn, &MemberId, &InstanceId, &SubscribedTopic, 1,
|
|
3152
|
+
&SubscribedTopicRegex);
|
|
3153
|
+
mtopic = rd_kafka_mock_topic_new(mcluster, topic, partitions, 1);
|
|
3154
|
+
|
|
3155
|
+
for (i = 0; i < fixtures_cnt; i++) {
|
|
3156
|
+
int j;
|
|
3157
|
+
rd_kafka_topic_partition_list_t *current_assignment,
|
|
3158
|
+
*member_target_assignment, *next_assignment,
|
|
3159
|
+
*returned_assignment;
|
|
3160
|
+
|
|
3161
|
+
RD_UT_SAY("test fixture %" PRIusz ": %s", i,
|
|
3162
|
+
fixtures[i].comment);
|
|
3163
|
+
|
|
3164
|
+
if (fixtures[i].session_timed_out) {
|
|
3165
|
+
rd_kafka_mock_cgrp_consumer_member_leave(mcgrp, member,
|
|
3166
|
+
rd_false);
|
|
3167
|
+
member = rd_kafka_mock_cgrp_consumer_member_add(
|
|
3168
|
+
mcgrp, conn, &MemberId, &InstanceId,
|
|
3169
|
+
&SubscribedTopic, 1, &SubscribedTopicRegex);
|
|
3170
|
+
}
|
|
3171
|
+
|
|
3172
|
+
if (fixtures[i].reconnected) {
|
|
3173
|
+
rd_kafka_mock_cgrps_connection_closed(mcluster, conn);
|
|
3174
|
+
conn++;
|
|
3175
|
+
member = rd_kafka_mock_cgrp_consumer_member_add(
|
|
3176
|
+
mcgrp, conn, &MemberId, &InstanceId,
|
|
3177
|
+
&SubscribedTopic, 1, &SubscribedTopicRegex);
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
member_target_assignment = fixtures[i].target_assignment;
|
|
3181
|
+
if (member_target_assignment) {
|
|
3182
|
+
rd_kafka_mock_cgrp_consumer_target_assignment_t
|
|
3183
|
+
*target_assignment;
|
|
3184
|
+
|
|
3185
|
+
target_assignment =
|
|
3186
|
+
rd_kafka_mock_cgrp_consumer_target_assignment_new(
|
|
3187
|
+
(char **)&MemberId.str, 1,
|
|
3188
|
+
&member_target_assignment);
|
|
3189
|
+
|
|
3190
|
+
rd_kafka_mock_cgrp_consumer_target_assignment(
|
|
3191
|
+
mcluster, GroupId.str, target_assignment);
|
|
3192
|
+
rd_kafka_mock_cgrp_consumer_target_assignment_destroy(
|
|
3193
|
+
target_assignment);
|
|
3194
|
+
rd_kafka_topic_partition_list_destroy(
|
|
3195
|
+
member_target_assignment);
|
|
3196
|
+
}
|
|
3197
|
+
|
|
3198
|
+
current_assignment = fixtures[i].current_assignment;
|
|
3199
|
+
if (current_assignment) {
|
|
3200
|
+
/* Set topic id */
|
|
3201
|
+
for (j = 0; j < current_assignment->cnt; j++) {
|
|
3202
|
+
rd_kafka_topic_partition_set_topic_id(
|
|
3203
|
+
¤t_assignment->elems[j], mtopic->id);
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3207
|
+
next_assignment =
|
|
3208
|
+
rd_kafka_mock_cgrp_consumer_member_next_assignment(
|
|
3209
|
+
member, current_assignment, ¤t_member_epoch);
|
|
3210
|
+
RD_IF_FREE(current_assignment,
|
|
3211
|
+
rd_kafka_topic_partition_list_destroy);
|
|
3212
|
+
RD_UT_ASSERT(
|
|
3213
|
+
current_member_epoch == fixtures[i].current_member_epoch,
|
|
3214
|
+
"current member epoch after call. Expected: %" PRId32
|
|
3215
|
+
", got: %" PRId32,
|
|
3216
|
+
fixtures[i].current_member_epoch, current_member_epoch);
|
|
3217
|
+
|
|
3218
|
+
returned_assignment = fixtures[i].returned_assignment;
|
|
3219
|
+
failures += ut_assert_topic_partitions(returned_assignment,
|
|
3220
|
+
next_assignment);
|
|
3221
|
+
|
|
3222
|
+
RD_IF_FREE(next_assignment,
|
|
3223
|
+
rd_kafka_topic_partition_list_destroy);
|
|
3224
|
+
RD_IF_FREE(returned_assignment,
|
|
3225
|
+
rd_kafka_topic_partition_list_destroy);
|
|
3226
|
+
}
|
|
3227
|
+
|
|
3228
|
+
rd_kafka_mock_cluster_destroy(mcluster);
|
|
3229
|
+
rd_kafka_destroy(rk);
|
|
3230
|
+
return failures;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
/**
|
|
3234
|
+
* @brief Test case where multiple revocations are acked.
|
|
3235
|
+
* Only when they're acked member epoch is bumped
|
|
3236
|
+
* and a new partition is returned to the member.
|
|
3237
|
+
*
|
|
3238
|
+
* @return Number of occurred errors.
|
|
3239
|
+
*/
|
|
3240
|
+
static int ut_cgrp_consumer_member_next_assignment1(void) {
|
|
3241
|
+
RD_UT_SAY("Case 1: multiple revocations acked");
|
|
3242
|
+
|
|
3243
|
+
const char *topic = "topic";
|
|
3244
|
+
struct cgrp_consumer_member_next_assignment_fixture fixtures[] = {
|
|
3245
|
+
{
|
|
3246
|
+
.comment = "Target+Returned assignment 0,1,2. Epoch 0 -> 3",
|
|
3247
|
+
.current_member_epoch = 3,
|
|
3248
|
+
.current_assignment = NULL,
|
|
3249
|
+
.target_assignment =
|
|
3250
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3251
|
+
.returned_assignment =
|
|
3252
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3253
|
+
},
|
|
3254
|
+
{
|
|
3255
|
+
.comment = "Current assignment empty",
|
|
3256
|
+
.current_member_epoch = 3,
|
|
3257
|
+
.current_assignment = ut_topic_partitions(0),
|
|
3258
|
+
.returned_assignment = NULL,
|
|
3259
|
+
},
|
|
3260
|
+
{
|
|
3261
|
+
.comment = "Empty heartbeat",
|
|
3262
|
+
.current_member_epoch = 3,
|
|
3263
|
+
.current_assignment = NULL,
|
|
3264
|
+
.returned_assignment = NULL,
|
|
3265
|
+
},
|
|
3266
|
+
{
|
|
3267
|
+
.comment = "Current assignment 0",
|
|
3268
|
+
.current_member_epoch = 3,
|
|
3269
|
+
.current_assignment = ut_topic_partitions(1, topic, 0),
|
|
3270
|
+
.returned_assignment = NULL,
|
|
3271
|
+
},
|
|
3272
|
+
{
|
|
3273
|
+
.comment = "Empty heartbeat",
|
|
3274
|
+
.current_member_epoch = 3,
|
|
3275
|
+
.current_assignment = NULL,
|
|
3276
|
+
.returned_assignment = NULL,
|
|
3277
|
+
},
|
|
3278
|
+
{
|
|
3279
|
+
.comment = "Current assignment 0,1",
|
|
3280
|
+
.current_member_epoch = 3,
|
|
3281
|
+
.current_assignment =
|
|
3282
|
+
ut_topic_partitions(2, topic, 0, topic, 1),
|
|
3283
|
+
.returned_assignment = NULL,
|
|
3284
|
+
},
|
|
3285
|
+
{
|
|
3286
|
+
.comment = "Empty heartbeat",
|
|
3287
|
+
.current_member_epoch = 3,
|
|
3288
|
+
.current_assignment = NULL,
|
|
3289
|
+
.returned_assignment = NULL,
|
|
3290
|
+
},
|
|
3291
|
+
{
|
|
3292
|
+
.comment = "Current assignment 0,1,2",
|
|
3293
|
+
.current_member_epoch = 3,
|
|
3294
|
+
.current_assignment =
|
|
3295
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3296
|
+
.returned_assignment = NULL,
|
|
3297
|
+
},
|
|
3298
|
+
{
|
|
3299
|
+
.comment = "Target assignment 0,1,3. Returned assignment 0,1",
|
|
3300
|
+
.current_member_epoch = 3,
|
|
3301
|
+
.target_assignment =
|
|
3302
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 3),
|
|
3303
|
+
.current_assignment = NULL,
|
|
3304
|
+
.returned_assignment =
|
|
3305
|
+
ut_topic_partitions(2, topic, 0, topic, 1),
|
|
3306
|
+
},
|
|
3307
|
+
{
|
|
3308
|
+
.comment = "Target assignment 0,3. Returned assignment 0",
|
|
3309
|
+
.current_member_epoch = 3,
|
|
3310
|
+
.target_assignment = ut_topic_partitions(2, topic, 0, topic, 3),
|
|
3311
|
+
.current_assignment = NULL,
|
|
3312
|
+
.returned_assignment = ut_topic_partitions(1, topic, 0),
|
|
3313
|
+
},
|
|
3314
|
+
{
|
|
3315
|
+
.comment = "Empty heartbeat",
|
|
3316
|
+
.current_member_epoch = 3,
|
|
3317
|
+
.current_assignment = NULL,
|
|
3318
|
+
.returned_assignment = NULL,
|
|
3319
|
+
},
|
|
3320
|
+
{
|
|
3321
|
+
.comment = "Current assignment 0,1",
|
|
3322
|
+
.current_member_epoch = 3,
|
|
3323
|
+
.current_assignment =
|
|
3324
|
+
ut_topic_partitions(2, topic, 0, topic, 1),
|
|
3325
|
+
.returned_assignment = NULL,
|
|
3326
|
+
},
|
|
3327
|
+
{
|
|
3328
|
+
.comment = "Empty heartbeat",
|
|
3329
|
+
.current_member_epoch = 3,
|
|
3330
|
+
.current_assignment = NULL,
|
|
3331
|
+
.returned_assignment = NULL,
|
|
3332
|
+
},
|
|
3333
|
+
{
|
|
3334
|
+
.comment = "Current assignment 0. Returned assignment 0,3. "
|
|
3335
|
+
"Epoch 3 -> 5",
|
|
3336
|
+
.current_member_epoch = 5,
|
|
3337
|
+
.current_assignment = ut_topic_partitions(1, topic, 0),
|
|
3338
|
+
.returned_assignment =
|
|
3339
|
+
ut_topic_partitions(2, topic, 0, topic, 3),
|
|
3340
|
+
},
|
|
3341
|
+
{
|
|
3342
|
+
.comment = "Empty heartbeat",
|
|
3343
|
+
.current_member_epoch = 5,
|
|
3344
|
+
.current_assignment = NULL,
|
|
3345
|
+
.returned_assignment = NULL,
|
|
3346
|
+
},
|
|
3347
|
+
{
|
|
3348
|
+
.comment = "Current assignment 0,3",
|
|
3349
|
+
.current_member_epoch = 5,
|
|
3350
|
+
.current_assignment =
|
|
3351
|
+
ut_topic_partitions(2, topic, 0, topic, 3),
|
|
3352
|
+
.returned_assignment = NULL,
|
|
3353
|
+
},
|
|
3354
|
+
};
|
|
3355
|
+
return ut_cgrp_consumer_member_next_assignment0(
|
|
3356
|
+
topic, 4, fixtures, RD_ARRAY_SIZE(fixtures));
|
|
3357
|
+
}
|
|
3358
|
+
|
|
3359
|
+
/**
|
|
3360
|
+
* @brief Test case where multiple revocations happen.
|
|
3361
|
+
* Only the first revocation is acked and after that
|
|
3362
|
+
* there's a reassignment and epoch bump.
|
|
3363
|
+
*
|
|
3364
|
+
* @return Number of occurred errors.
|
|
3365
|
+
*/
|
|
3366
|
+
static int ut_cgrp_consumer_member_next_assignment2(void) {
|
|
3367
|
+
RD_UT_SAY(
|
|
3368
|
+
"Case 2: reassignment of revoked partition, partial revocation "
|
|
3369
|
+
"acknowledge");
|
|
3370
|
+
|
|
3371
|
+
const char *topic = "topic";
|
|
3372
|
+
struct cgrp_consumer_member_next_assignment_fixture fixtures[] = {
|
|
3373
|
+
{
|
|
3374
|
+
.comment = "Target+Returned assignment 0,1,2. Epoch 0 -> 3",
|
|
3375
|
+
.current_member_epoch = 3,
|
|
3376
|
+
.current_assignment = NULL,
|
|
3377
|
+
.target_assignment =
|
|
3378
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3379
|
+
.returned_assignment =
|
|
3380
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3381
|
+
},
|
|
3382
|
+
{
|
|
3383
|
+
.comment = "Current assignment 0,1,2",
|
|
3384
|
+
.current_member_epoch = 3,
|
|
3385
|
+
.current_assignment =
|
|
3386
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3387
|
+
.returned_assignment = NULL,
|
|
3388
|
+
},
|
|
3389
|
+
{
|
|
3390
|
+
.comment = "Target assignment 0,1,3. Returned assignment 0,1",
|
|
3391
|
+
.current_member_epoch = 3,
|
|
3392
|
+
.target_assignment =
|
|
3393
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 3),
|
|
3394
|
+
.current_assignment = NULL,
|
|
3395
|
+
.returned_assignment =
|
|
3396
|
+
ut_topic_partitions(2, topic, 0, topic, 1),
|
|
3397
|
+
},
|
|
3398
|
+
{
|
|
3399
|
+
.comment = "Target assignment 0,3. Returned assignment 0",
|
|
3400
|
+
.current_member_epoch = 3,
|
|
3401
|
+
.target_assignment = ut_topic_partitions(2, topic, 0, topic, 3),
|
|
3402
|
+
.current_assignment = NULL,
|
|
3403
|
+
.returned_assignment = ut_topic_partitions(1, topic, 0),
|
|
3404
|
+
},
|
|
3405
|
+
{
|
|
3406
|
+
.comment = "Empty heartbeat",
|
|
3407
|
+
.current_member_epoch = 3,
|
|
3408
|
+
.current_assignment = NULL,
|
|
3409
|
+
.returned_assignment = NULL,
|
|
3410
|
+
},
|
|
3411
|
+
{
|
|
3412
|
+
.comment = "Current assignment 0,1",
|
|
3413
|
+
.current_member_epoch = 3,
|
|
3414
|
+
.current_assignment =
|
|
3415
|
+
ut_topic_partitions(2, topic, 0, topic, 1),
|
|
3416
|
+
.returned_assignment = NULL,
|
|
3417
|
+
},
|
|
3418
|
+
{
|
|
3419
|
+
.comment = "Empty heartbeat",
|
|
3420
|
+
.current_member_epoch = 3,
|
|
3421
|
+
.current_assignment = NULL,
|
|
3422
|
+
.returned_assignment = NULL,
|
|
3423
|
+
},
|
|
3424
|
+
{
|
|
3425
|
+
.comment = "Target+Returned assignment 0,1,3. Epoch 3 -> 6",
|
|
3426
|
+
.current_member_epoch = 6,
|
|
3427
|
+
.target_assignment =
|
|
3428
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 3),
|
|
3429
|
+
.current_assignment = NULL,
|
|
3430
|
+
.returned_assignment =
|
|
3431
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 3),
|
|
3432
|
+
},
|
|
3433
|
+
{
|
|
3434
|
+
.comment = "Empty heartbeat",
|
|
3435
|
+
.current_member_epoch = 6,
|
|
3436
|
+
.current_assignment = NULL,
|
|
3437
|
+
.returned_assignment = NULL,
|
|
3438
|
+
},
|
|
3439
|
+
{
|
|
3440
|
+
.comment = "Current assignment 0,1,3",
|
|
3441
|
+
.current_member_epoch = 6,
|
|
3442
|
+
.current_assignment =
|
|
3443
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 3),
|
|
3444
|
+
.returned_assignment = NULL,
|
|
3445
|
+
},
|
|
3446
|
+
};
|
|
3447
|
+
return ut_cgrp_consumer_member_next_assignment0(
|
|
3448
|
+
topic, 4, fixtures, RD_ARRAY_SIZE(fixtures));
|
|
3449
|
+
}
|
|
3450
|
+
|
|
3451
|
+
/**
|
|
3452
|
+
* @brief Test case where multiple revocations happen.
|
|
3453
|
+
* They aren't acked but then a
|
|
3454
|
+
* reassignment of all the revoked partition happens, bumping the epoch.
|
|
3455
|
+
*
|
|
3456
|
+
* @return Number of occurred errors.
|
|
3457
|
+
*/
|
|
3458
|
+
static int ut_cgrp_consumer_member_next_assignment3(void) {
|
|
3459
|
+
RD_UT_SAY(
|
|
3460
|
+
"Case 3: reassignment of revoked partition and new partition, no "
|
|
3461
|
+
"revocation acknowledge");
|
|
3462
|
+
|
|
3463
|
+
const char *topic = "topic";
|
|
3464
|
+
struct cgrp_consumer_member_next_assignment_fixture fixtures[] = {
|
|
3465
|
+
{
|
|
3466
|
+
.comment = "Target+Returned assignment 0,1,2. Epoch 0 -> 3",
|
|
3467
|
+
.current_member_epoch = 3,
|
|
3468
|
+
.current_assignment = NULL,
|
|
3469
|
+
.target_assignment =
|
|
3470
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3471
|
+
.returned_assignment =
|
|
3472
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3473
|
+
},
|
|
3474
|
+
{
|
|
3475
|
+
.comment = "Current assignment 0,1,2",
|
|
3476
|
+
.current_member_epoch = 3,
|
|
3477
|
+
.current_assignment =
|
|
3478
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3479
|
+
.returned_assignment = NULL,
|
|
3480
|
+
},
|
|
3481
|
+
{
|
|
3482
|
+
.comment = "Target assignment 0,1,3. Returned assignment 0,1",
|
|
3483
|
+
.current_member_epoch = 3,
|
|
3484
|
+
.target_assignment =
|
|
3485
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 3),
|
|
3486
|
+
.current_assignment = NULL,
|
|
3487
|
+
.returned_assignment =
|
|
3488
|
+
ut_topic_partitions(2, topic, 0, topic, 1),
|
|
3489
|
+
},
|
|
3490
|
+
{
|
|
3491
|
+
.comment = "Target assignment 0,3. Returned assignment 0",
|
|
3492
|
+
.current_member_epoch = 3,
|
|
3493
|
+
.target_assignment = ut_topic_partitions(2, topic, 0, topic, 3),
|
|
3494
|
+
.current_assignment = NULL,
|
|
3495
|
+
.returned_assignment = ut_topic_partitions(1, topic, 0),
|
|
3496
|
+
},
|
|
3497
|
+
{
|
|
3498
|
+
.comment = "Empty heartbeat",
|
|
3499
|
+
.current_member_epoch = 3,
|
|
3500
|
+
.current_assignment = NULL,
|
|
3501
|
+
.returned_assignment = NULL,
|
|
3502
|
+
},
|
|
3503
|
+
{
|
|
3504
|
+
.comment = "Target+Returned assignment 0,1,2,3. Epoch 3 -> 6",
|
|
3505
|
+
.current_member_epoch = 6,
|
|
3506
|
+
.target_assignment = ut_topic_partitions(
|
|
3507
|
+
3, topic, 0, topic, 1, topic, 2, topic, 3, NULL),
|
|
3508
|
+
.returned_assignment = ut_topic_partitions(
|
|
3509
|
+
3, topic, 0, topic, 1, topic, 2, topic, 3, NULL),
|
|
3510
|
+
},
|
|
3511
|
+
{
|
|
3512
|
+
.comment = "Empty heartbeat",
|
|
3513
|
+
.current_member_epoch = 6,
|
|
3514
|
+
.current_assignment = NULL,
|
|
3515
|
+
.returned_assignment = NULL,
|
|
3516
|
+
},
|
|
3517
|
+
{
|
|
3518
|
+
.comment = "Current assignment 0,1,2,3",
|
|
3519
|
+
.current_member_epoch = 6,
|
|
3520
|
+
.current_assignment = ut_topic_partitions(
|
|
3521
|
+
3, topic, 0, topic, 1, topic, 2, topic, 3, NULL),
|
|
3522
|
+
.returned_assignment = NULL,
|
|
3523
|
+
},
|
|
3524
|
+
};
|
|
3525
|
+
return ut_cgrp_consumer_member_next_assignment0(
|
|
3526
|
+
topic, 4, fixtures, RD_ARRAY_SIZE(fixtures));
|
|
3527
|
+
}
|
|
3528
|
+
|
|
3529
|
+
/**
|
|
3530
|
+
* @brief Test case where a disconnection happens and after that
|
|
3531
|
+
* the client send its assignment again, with same member epoch,
|
|
3532
|
+
* and receives back the returned assignment, even if the same.
|
|
3533
|
+
*
|
|
3534
|
+
* @return Number of occurred errors.
|
|
3535
|
+
*/
|
|
3536
|
+
static int ut_cgrp_consumer_member_next_assignment4(void) {
|
|
3537
|
+
RD_UT_SAY("Case 4: reconciliation after disconnection");
|
|
3538
|
+
|
|
3539
|
+
const char *topic = "topic";
|
|
3540
|
+
struct cgrp_consumer_member_next_assignment_fixture fixtures[] = {
|
|
3541
|
+
{
|
|
3542
|
+
.comment = "Target+Returned assignment 0,1,2. Epoch 0 -> 3",
|
|
3543
|
+
.current_member_epoch = 3,
|
|
3544
|
+
.current_assignment = NULL,
|
|
3545
|
+
.target_assignment =
|
|
3546
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3547
|
+
.returned_assignment =
|
|
3548
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3549
|
+
},
|
|
3550
|
+
{
|
|
3551
|
+
.comment = "Current assignment empty",
|
|
3552
|
+
.current_member_epoch = 3,
|
|
3553
|
+
.current_assignment = ut_topic_partitions(0),
|
|
3554
|
+
.returned_assignment = NULL,
|
|
3555
|
+
},
|
|
3556
|
+
{
|
|
3557
|
+
.comment = "Disconnected, resends current assignment. Returns "
|
|
3558
|
+
"assignment again",
|
|
3559
|
+
.reconnected = rd_true,
|
|
3560
|
+
.current_member_epoch = 3,
|
|
3561
|
+
.current_assignment = ut_topic_partitions(0),
|
|
3562
|
+
.returned_assignment =
|
|
3563
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3564
|
+
},
|
|
3565
|
+
{
|
|
3566
|
+
.comment = "Empty heartbeat",
|
|
3567
|
+
.current_member_epoch = 3,
|
|
3568
|
+
.current_assignment = NULL,
|
|
3569
|
+
.returned_assignment = NULL,
|
|
3570
|
+
},
|
|
3571
|
+
{
|
|
3572
|
+
.comment = "Current assignment 0,1,2",
|
|
3573
|
+
.current_member_epoch = 3,
|
|
3574
|
+
.current_assignment =
|
|
3575
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3576
|
+
.returned_assignment = NULL,
|
|
3577
|
+
},
|
|
3578
|
+
};
|
|
3579
|
+
return ut_cgrp_consumer_member_next_assignment0(
|
|
3580
|
+
topic, 3, fixtures, RD_ARRAY_SIZE(fixtures));
|
|
3581
|
+
}
|
|
3582
|
+
|
|
3583
|
+
/**
|
|
3584
|
+
* @brief Test case where a session timeout happens and then
|
|
3585
|
+
* the client receives a FENCED_MEMBER_EPOCH error,
|
|
3586
|
+
* revokes all of its partitions and rejoins with epoch 0.
|
|
3587
|
+
*
|
|
3588
|
+
* @return Number of occurred errors.
|
|
3589
|
+
*/
|
|
3590
|
+
static int ut_cgrp_consumer_member_next_assignment5(void) {
|
|
3591
|
+
RD_UT_SAY("Case 5: fenced consumer");
|
|
3592
|
+
|
|
3593
|
+
const char *topic = "topic";
|
|
3594
|
+
struct cgrp_consumer_member_next_assignment_fixture fixtures[] = {
|
|
3595
|
+
{
|
|
3596
|
+
.comment = "Target+Returned assignment 0,1,2. Epoch 0 -> 3",
|
|
3597
|
+
.current_member_epoch = 3,
|
|
3598
|
+
.current_assignment = NULL,
|
|
3599
|
+
.target_assignment =
|
|
3600
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3601
|
+
.returned_assignment =
|
|
3602
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3603
|
+
},
|
|
3604
|
+
{
|
|
3605
|
+
.comment = "Session times out, receives FENCED_MEMBER_EPOCH. "
|
|
3606
|
+
"Epoch 3 -> 0",
|
|
3607
|
+
.session_timed_out = rd_true,
|
|
3608
|
+
.current_member_epoch = -1,
|
|
3609
|
+
.current_assignment = NULL,
|
|
3610
|
+
.returned_assignment = NULL,
|
|
3611
|
+
},
|
|
3612
|
+
{
|
|
3613
|
+
.comment = "Target+Returned assignment 0,1,2. Epoch 0 -> 6",
|
|
3614
|
+
.target_assignment =
|
|
3615
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3616
|
+
.current_member_epoch = 4,
|
|
3617
|
+
.current_assignment = NULL,
|
|
3618
|
+
.returned_assignment =
|
|
3619
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3620
|
+
},
|
|
3621
|
+
{
|
|
3622
|
+
.comment = "Current assignment 0,1,2",
|
|
3623
|
+
.current_member_epoch = 4,
|
|
3624
|
+
.current_assignment =
|
|
3625
|
+
ut_topic_partitions(3, topic, 0, topic, 1, topic, 2),
|
|
3626
|
+
.returned_assignment = NULL,
|
|
3627
|
+
},
|
|
3628
|
+
};
|
|
3629
|
+
return ut_cgrp_consumer_member_next_assignment0(
|
|
3630
|
+
topic, 3, fixtures, RD_ARRAY_SIZE(fixtures));
|
|
3631
|
+
}
|
|
3632
|
+
|
|
3633
|
+
/**
|
|
3634
|
+
* @brief Test all next assignment calculation cases,
|
|
3635
|
+
* for KIP-848 consumer group type and collect
|
|
3636
|
+
* number of errors.
|
|
3637
|
+
*
|
|
3638
|
+
* @return Number of occurred errors.
|
|
3639
|
+
*/
|
|
3640
|
+
static int ut_cgrp_consumer_member_next_assignment(void) {
|
|
3641
|
+
RD_UT_BEGIN();
|
|
3642
|
+
int failures = 0;
|
|
3643
|
+
|
|
3644
|
+
failures += ut_cgrp_consumer_member_next_assignment1();
|
|
3645
|
+
failures += ut_cgrp_consumer_member_next_assignment2();
|
|
3646
|
+
failures += ut_cgrp_consumer_member_next_assignment3();
|
|
3647
|
+
failures += ut_cgrp_consumer_member_next_assignment4();
|
|
3648
|
+
failures += ut_cgrp_consumer_member_next_assignment5();
|
|
3649
|
+
|
|
3650
|
+
RD_UT_ASSERT(!failures, "some tests failed");
|
|
3651
|
+
RD_UT_PASS();
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
/**
|
|
3655
|
+
* @brief Mock cluster unit tests
|
|
3656
|
+
*/
|
|
3657
|
+
int unittest_mock_cluster(void) {
|
|
3658
|
+
int fails = 0;
|
|
3659
|
+
fails += ut_cgrp_consumer_member_next_assignment();
|
|
3660
|
+
return fails;
|
|
3661
|
+
}
|