@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.
Files changed (294) hide show
  1. package/README.md +5 -5
  2. package/bench/seed.sh +0 -0
  3. package/binding.gyp +8 -1
  4. package/ci/prepublish.js +0 -1
  5. package/config.d.ts +126 -10
  6. package/configure +0 -0
  7. package/deps/librdkafka/.semaphore/run-all-tests.yml +77 -0
  8. package/deps/librdkafka/.semaphore/semaphore-integration.yml +250 -0
  9. package/deps/librdkafka/.semaphore/semaphore.yml +67 -44
  10. package/deps/librdkafka/.semaphore/verify-linux-packages.yml +41 -0
  11. package/deps/librdkafka/CHANGELOG.md +471 -1
  12. package/deps/librdkafka/CONFIGURATION.md +29 -9
  13. package/deps/librdkafka/INTRODUCTION.md +909 -601
  14. package/deps/librdkafka/LICENSES.txt +592 -1
  15. package/deps/librdkafka/Makefile +2 -1
  16. package/deps/librdkafka/_mkltmpuuWEwa.c +13 -0
  17. package/deps/librdkafka/configure +0 -0
  18. package/deps/librdkafka/debian/rules +0 -0
  19. package/deps/librdkafka/dev-conf.sh +0 -0
  20. package/deps/librdkafka/examples/consumer.c +18 -8
  21. package/deps/librdkafka/examples/describe_consumer_groups.c +25 -6
  22. package/deps/librdkafka/examples/incremental_alter_configs.c +4 -5
  23. package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +26 -42
  24. package/deps/librdkafka/examples/openssl_engine_example.cpp +3 -4
  25. package/deps/librdkafka/examples/producer.cpp +2 -2
  26. package/deps/librdkafka/examples/user_scram.c +4 -5
  27. package/deps/librdkafka/examples/win_ssl_cert_store.cpp +4 -3
  28. package/deps/librdkafka/lds-gen.py +0 -0
  29. package/deps/librdkafka/mklove/Makefile.base +0 -0
  30. package/deps/librdkafka/packaging/RELEASE.md +8 -0
  31. package/deps/librdkafka/packaging/alpine/build-alpine.sh +0 -0
  32. package/deps/librdkafka/packaging/cp/README.md +4 -1
  33. package/deps/librdkafka/packaging/cp/check_features.c +12 -4
  34. package/deps/librdkafka/packaging/cp/verify-deb.sh +6 -6
  35. package/deps/librdkafka/packaging/cp/verify-packages.sh +52 -31
  36. package/deps/librdkafka/packaging/cp/verify-rpm.sh +6 -13
  37. package/deps/librdkafka/packaging/debian/rules +0 -0
  38. package/deps/librdkafka/packaging/get_version.py +0 -0
  39. package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +0 -0
  40. package/deps/librdkafka/packaging/mingw-w64/{travis-before-install.sh → export-variables.sh} +0 -7
  41. package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +1 -1
  42. package/deps/librdkafka/packaging/nuget/artifact.py +0 -0
  43. package/deps/librdkafka/packaging/nuget/cleanup-s3.py +0 -0
  44. package/deps/librdkafka/packaging/nuget/nuget.sh +0 -0
  45. package/deps/librdkafka/packaging/nuget/packaging.py +0 -0
  46. package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +0 -0
  47. package/deps/librdkafka/packaging/nuget/release.py +0 -0
  48. package/deps/librdkafka/packaging/nuget/requirements.txt +3 -3
  49. package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +0 -0
  50. package/deps/librdkafka/packaging/rpm/tests/run-test.sh +0 -0
  51. package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +0 -0
  52. package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +3 -1
  53. package/deps/librdkafka/packaging/tools/build-deb-package.sh +0 -0
  54. package/deps/librdkafka/packaging/tools/build-debian.sh +0 -0
  55. package/deps/librdkafka/packaging/tools/build-manylinux.sh +0 -0
  56. package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +0 -0
  57. package/deps/librdkafka/packaging/tools/distro-build.sh +0 -0
  58. package/deps/librdkafka/packaging/tools/gh-release-checksums.py +0 -0
  59. package/deps/librdkafka/packaging/tools/rdutcoverage.sh +0 -0
  60. package/deps/librdkafka/packaging/tools/run-in-docker.sh +28 -0
  61. package/deps/librdkafka/packaging/tools/run-integration-tests.sh +31 -0
  62. package/deps/librdkafka/packaging/tools/run-style-check.sh +4 -0
  63. package/deps/librdkafka/packaging/tools/style-format.sh +6 -5
  64. package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
  65. package/deps/librdkafka/service.yml +154 -0
  66. package/deps/librdkafka/src/generate_proto.sh +0 -0
  67. package/deps/librdkafka/src/rd.h +145 -2
  68. package/deps/librdkafka/src/rdaddr.h +6 -7
  69. package/deps/librdkafka/src/rdatomic.h +15 -11
  70. package/deps/librdkafka/src/rdavg.h +3 -2
  71. package/deps/librdkafka/src/rdbase64.c +33 -2
  72. package/deps/librdkafka/src/rdbase64.h +2 -0
  73. package/deps/librdkafka/src/rdendian.h +10 -9
  74. package/deps/librdkafka/src/rdhttp.c +418 -100
  75. package/deps/librdkafka/src/rdhttp.h +23 -5
  76. package/deps/librdkafka/src/rdkafka.c +299 -145
  77. package/deps/librdkafka/src/rdkafka.h +89 -6
  78. package/deps/librdkafka/src/rdkafka_admin.c +482 -105
  79. package/deps/librdkafka/src/rdkafka_admin.h +42 -0
  80. package/deps/librdkafka/src/rdkafka_broker.c +463 -312
  81. package/deps/librdkafka/src/rdkafka_broker.h +68 -10
  82. package/deps/librdkafka/src/rdkafka_buf.c +8 -5
  83. package/deps/librdkafka/src/rdkafka_buf.h +4 -3
  84. package/deps/librdkafka/src/rdkafka_cert.c +25 -1
  85. package/deps/librdkafka/src/rdkafka_cert.h +4 -3
  86. package/deps/librdkafka/src/rdkafka_cgrp.c +468 -143
  87. package/deps/librdkafka/src/rdkafka_cgrp.h +36 -2
  88. package/deps/librdkafka/src/rdkafka_conf.c +526 -102
  89. package/deps/librdkafka/src/rdkafka_conf.h +68 -4
  90. package/deps/librdkafka/src/rdkafka_feature.c +472 -35
  91. package/deps/librdkafka/src/rdkafka_feature.h +2 -0
  92. package/deps/librdkafka/src/rdkafka_fetcher.c +22 -2
  93. package/deps/librdkafka/src/rdkafka_fetcher.h +2 -2
  94. package/deps/librdkafka/src/rdkafka_int.h +84 -46
  95. package/deps/librdkafka/src/rdkafka_metadata.c +221 -136
  96. package/deps/librdkafka/src/rdkafka_metadata.h +15 -11
  97. package/deps/librdkafka/src/rdkafka_metadata_cache.c +279 -73
  98. package/deps/librdkafka/src/rdkafka_mock.c +795 -19
  99. package/deps/librdkafka/src/rdkafka_mock.h +119 -0
  100. package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1298 -132
  101. package/deps/librdkafka/src/rdkafka_mock_handlers.c +345 -49
  102. package/deps/librdkafka/src/rdkafka_mock_int.h +180 -61
  103. package/deps/librdkafka/src/rdkafka_msg.c +35 -19
  104. package/deps/librdkafka/src/rdkafka_msg.h +3 -3
  105. package/deps/librdkafka/src/rdkafka_msgset_writer.c +14 -10
  106. package/deps/librdkafka/src/rdkafka_offset.c +33 -5
  107. package/deps/librdkafka/src/rdkafka_op.c +1 -1
  108. package/deps/librdkafka/src/rdkafka_op.h +45 -21
  109. package/deps/librdkafka/src/rdkafka_partition.c +118 -23
  110. package/deps/librdkafka/src/rdkafka_partition.h +16 -7
  111. package/deps/librdkafka/src/rdkafka_proto.h +4 -1
  112. package/deps/librdkafka/src/rdkafka_protocol.h +1 -0
  113. package/deps/librdkafka/src/rdkafka_queue.c +125 -48
  114. package/deps/librdkafka/src/rdkafka_queue.h +19 -0
  115. package/deps/librdkafka/src/rdkafka_range_assignor.c +1 -1
  116. package/deps/librdkafka/src/rdkafka_request.c +336 -64
  117. package/deps/librdkafka/src/rdkafka_request.h +24 -1
  118. package/deps/librdkafka/src/rdkafka_sasl.c +5 -3
  119. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +14 -10
  120. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1166 -89
  121. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +13 -3
  122. package/deps/librdkafka/src/rdkafka_sasl_plain.c +3 -3
  123. package/deps/librdkafka/src/rdkafka_sasl_scram.c +4 -3
  124. package/deps/librdkafka/src/rdkafka_ssl.c +306 -81
  125. package/deps/librdkafka/src/rdkafka_ssl.h +22 -0
  126. package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4 -0
  127. package/deps/librdkafka/src/rdkafka_telemetry.c +80 -23
  128. package/deps/librdkafka/src/rdkafka_telemetry_encode.c +5 -1
  129. package/deps/librdkafka/src/rdkafka_telemetry_encode.h +20 -20
  130. package/deps/librdkafka/src/rdkafka_topic.c +220 -137
  131. package/deps/librdkafka/src/rdkafka_topic.h +14 -8
  132. package/deps/librdkafka/src/rdkafka_transport.c +59 -47
  133. package/deps/librdkafka/src/rdkafka_transport.h +5 -0
  134. package/deps/librdkafka/src/rdkafka_txnmgr.c +6 -1
  135. package/deps/librdkafka/src/rdmap.c +6 -1
  136. package/deps/librdkafka/src/rdrand.c +11 -1
  137. package/deps/librdkafka/src/rdtime.h +48 -17
  138. package/deps/librdkafka/src/rdunittest.c +42 -25
  139. package/deps/librdkafka/src/rdunittest.h +2 -0
  140. package/deps/librdkafka/src/rdwin32.h +1 -1
  141. package/deps/librdkafka/src/regexp.c +47 -42
  142. package/deps/librdkafka/src/tinycthread_extra.c +45 -21
  143. package/deps/librdkafka/src/tinycthread_extra.h +7 -3
  144. package/deps/librdkafka/src-cpp/rdkafkacpp.h +28 -2
  145. package/deps/librdkafka/tests/0001-multiobj.c +4 -0
  146. package/deps/librdkafka/tests/0004-conf.c +103 -36
  147. package/deps/librdkafka/tests/0009-mock_cluster.c +1 -0
  148. package/deps/librdkafka/tests/0011-produce_batch.c +2 -1
  149. package/deps/librdkafka/tests/0016-client_swname.c +18 -3
  150. package/deps/librdkafka/tests/0017-compression.c +6 -8
  151. package/deps/librdkafka/tests/0018-cgrp_term.c +8 -3
  152. package/deps/librdkafka/tests/0021-rkt_destroy.c +1 -0
  153. package/deps/librdkafka/tests/0022-consume_batch.c +4 -1
  154. package/deps/librdkafka/tests/0026-consume_pause.c +12 -14
  155. package/deps/librdkafka/tests/0028-long_topicnames.c +1 -1
  156. package/deps/librdkafka/tests/0029-assign_offset.c +6 -8
  157. package/deps/librdkafka/tests/0030-offset_commit.c +2 -2
  158. package/deps/librdkafka/tests/0033-regex_subscribe.c +33 -17
  159. package/deps/librdkafka/tests/0034-offset_reset.c +25 -4
  160. package/deps/librdkafka/tests/0036-partial_fetch.c +1 -0
  161. package/deps/librdkafka/tests/0038-performance.c +1 -0
  162. package/deps/librdkafka/tests/0040-io_event.c +11 -5
  163. package/deps/librdkafka/tests/0041-fetch_max_bytes.c +1 -0
  164. package/deps/librdkafka/tests/0044-partition_cnt.c +3 -2
  165. package/deps/librdkafka/tests/0045-subscribe_update.c +284 -20
  166. package/deps/librdkafka/tests/0047-partial_buf_tmout.c +1 -0
  167. package/deps/librdkafka/tests/0048-partitioner.c +1 -1
  168. package/deps/librdkafka/tests/0050-subscribe_adds.c +1 -0
  169. package/deps/librdkafka/tests/0051-assign_adds.c +1 -0
  170. package/deps/librdkafka/tests/0052-msg_timestamps.c +22 -4
  171. package/deps/librdkafka/tests/0053-stats_cb.cpp +12 -20
  172. package/deps/librdkafka/tests/0055-producer_latency.c +176 -3
  173. package/deps/librdkafka/tests/0056-balanced_group_mt.c +6 -2
  174. package/deps/librdkafka/tests/0058-log.cpp +3 -3
  175. package/deps/librdkafka/tests/0059-bsearch.cpp +8 -4
  176. package/deps/librdkafka/tests/0061-consumer_lag.cpp +25 -5
  177. package/deps/librdkafka/tests/0067-empty_topic.cpp +3 -0
  178. package/deps/librdkafka/tests/0068-produce_timeout.c +21 -23
  179. package/deps/librdkafka/tests/0069-consumer_add_parts.c +3 -7
  180. package/deps/librdkafka/tests/0075-retry.c +38 -1
  181. package/deps/librdkafka/tests/0076-produce_retry.c +2 -0
  182. package/deps/librdkafka/tests/0077-compaction.c +8 -2
  183. package/deps/librdkafka/tests/0080-admin_ut.c +34 -4
  184. package/deps/librdkafka/tests/0081-admin.c +455 -155
  185. package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +4 -0
  186. package/deps/librdkafka/tests/0083-cb_event.c +8 -3
  187. package/deps/librdkafka/tests/0084-destroy_flags.c +14 -18
  188. package/deps/librdkafka/tests/0085-headers.cpp +4 -0
  189. package/deps/librdkafka/tests/0086-purge.c +40 -7
  190. package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +1 -1
  191. package/deps/librdkafka/tests/0089-max_poll_interval.c +12 -7
  192. package/deps/librdkafka/tests/0090-idempotence.c +1 -2
  193. package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +5 -7
  194. package/deps/librdkafka/tests/0092-mixed_msgver.c +6 -0
  195. package/deps/librdkafka/tests/0093-holb.c +8 -5
  196. package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +1 -0
  197. package/deps/librdkafka/tests/0097-ssl_verify.cpp +262 -70
  198. package/deps/librdkafka/tests/0098-consumer-txn.cpp +16 -16
  199. package/deps/librdkafka/tests/0099-commit_metadata.c +1 -1
  200. package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +1 -1
  201. package/deps/librdkafka/tests/0102-static_group_rebalance.c +317 -16
  202. package/deps/librdkafka/tests/0103-transactions.c +7 -7
  203. package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +1 -0
  204. package/deps/librdkafka/tests/0105-transactions_mock.c +18 -11
  205. package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +35 -14
  206. package/deps/librdkafka/tests/0107-topic_recreate.c +2 -2
  207. package/deps/librdkafka/tests/0109-auto_create_topics.cpp +86 -26
  208. package/deps/librdkafka/tests/0110-batch_size.cpp +1 -2
  209. package/deps/librdkafka/tests/0112-assign_unknown_part.c +3 -14
  210. package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +248 -104
  211. package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +3 -3
  212. package/deps/librdkafka/tests/0115-producer_auth.cpp +4 -1
  213. package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +7 -5
  214. package/deps/librdkafka/tests/0117-mock_errors.c +15 -5
  215. package/deps/librdkafka/tests/0118-commit_rebalance.c +41 -8
  216. package/deps/librdkafka/tests/0119-consumer_auth.cpp +20 -1
  217. package/deps/librdkafka/tests/0120-asymmetric_subscription.c +8 -3
  218. package/deps/librdkafka/tests/0125-immediate_flush.c +1 -1
  219. package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +323 -8
  220. package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +1 -0
  221. package/deps/librdkafka/tests/0132-strategy_ordering.c +12 -4
  222. package/deps/librdkafka/tests/0133-ssl_keys.c +28 -6
  223. package/deps/librdkafka/tests/0137-barrier_batch_consume.c +24 -14
  224. package/deps/librdkafka/tests/0139-offset_validation_mock.c +510 -2
  225. package/deps/librdkafka/tests/0140-commit_metadata.cpp +1 -1
  226. package/deps/librdkafka/tests/0142-reauthentication.c +37 -17
  227. package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +39 -40
  228. package/deps/librdkafka/tests/0146-metadata_mock.c +76 -15
  229. package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +952 -0
  230. package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +563 -0
  231. package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
  232. package/deps/librdkafka/tests/0150-telemetry_mock.c +9 -6
  233. package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
  234. package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
  235. package/deps/librdkafka/tests/0153-memberid.c +128 -0
  236. package/deps/librdkafka/tests/CMakeLists.txt +6 -0
  237. package/deps/librdkafka/tests/LibrdkafkaTestApp.py +34 -9
  238. package/deps/librdkafka/tests/autotest.sh +0 -0
  239. package/deps/librdkafka/tests/broker_version_tests.py +0 -0
  240. package/deps/librdkafka/tests/buildbox.sh +0 -0
  241. package/deps/librdkafka/tests/cleanup-checker-tests.sh +0 -0
  242. package/deps/librdkafka/tests/cluster_testing.py +0 -0
  243. package/deps/librdkafka/tests/delete-test-topics.sh +0 -0
  244. package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
  245. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
  246. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
  247. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
  248. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +42 -101
  249. package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
  250. package/deps/librdkafka/tests/fixtures/ssl/client2.key +41 -29
  251. package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +112 -37
  252. package/deps/librdkafka/tests/gen-ssl-certs.sh +0 -0
  253. package/deps/librdkafka/tests/interactive_broker_version.py +0 -0
  254. package/deps/librdkafka/tests/java/Makefile +2 -1
  255. package/deps/librdkafka/tests/java/run-class.sh +0 -0
  256. package/deps/librdkafka/tests/lz4_manual_test.sh +0 -0
  257. package/deps/librdkafka/tests/multi-broker-version-test.sh +0 -0
  258. package/deps/librdkafka/tests/parse-refcnt.sh +0 -0
  259. package/deps/librdkafka/tests/performance_plot.py +0 -0
  260. package/deps/librdkafka/tests/requirements.txt +1 -1
  261. package/deps/librdkafka/tests/run-all-tests.sh +79 -0
  262. package/deps/librdkafka/tests/run-consumer-tests.sh +0 -0
  263. package/deps/librdkafka/tests/run-producer-tests.sh +0 -0
  264. package/deps/librdkafka/tests/run-test-batches.py +157 -0
  265. package/deps/librdkafka/tests/run-test.sh +0 -0
  266. package/deps/librdkafka/tests/sasl_test.py +0 -0
  267. package/deps/librdkafka/tests/test.c +478 -18
  268. package/deps/librdkafka/tests/test.h +62 -13
  269. package/deps/librdkafka/tests/testcpp.cpp +6 -1
  270. package/deps/librdkafka/tests/testcpp.h +30 -2
  271. package/deps/librdkafka/tests/testshared.h +16 -2
  272. package/deps/librdkafka/tests/tools/stats/graph.py +0 -0
  273. package/deps/librdkafka/tests/tools/stats/to_csv.py +1 -1
  274. package/deps/librdkafka/tests/trivup/trivup-0.14.0.tar.gz +0 -0
  275. package/deps/librdkafka/tests/until-fail.sh +0 -0
  276. package/deps/librdkafka/tests/xxxx-metadata.cpp +1 -1
  277. package/deps/librdkafka/vcpkg.json +1 -1
  278. package/deps/librdkafka/win32/setup-msys2.ps1 +24 -8
  279. package/deps/librdkafka/win32/setup-vcpkg.ps1 +28 -6
  280. package/deps/librdkafka/win32/tests/tests.vcxproj +6 -0
  281. package/deps/librdkafka/win32/wingetopt.h +5 -4
  282. package/errors.d.ts +27 -1
  283. package/lib/error.js +29 -3
  284. package/make_docs.sh +0 -0
  285. package/package.json +11 -11
  286. package/run_docker.sh +0 -0
  287. package/src/callbacks.cc +6 -9
  288. package/src/callbacks.h +1 -5
  289. package/test/kafka-consumer-worker.js +10 -7
  290. package/test/kafka-consumer.spec.js +32 -21
  291. package/ci/update-version.js +0 -123
  292. package/deps/librdkafka/.semaphore/project.yml +0 -43
  293. package/deps/librdkafka/.semaphore/project_public.yml +0 -20
  294. package/deps/librdkafka/win32/install-openssl.ps1 +0 -33
@@ -157,6 +157,8 @@ _TEST_DECL(0045_subscribe_update_topic_remove);
157
157
  _TEST_DECL(0045_subscribe_update_non_exist_and_partchange);
158
158
  _TEST_DECL(0045_subscribe_update_mock);
159
159
  _TEST_DECL(0045_subscribe_update_racks_mock);
160
+ _TEST_DECL(0045_resubscribe_with_regex);
161
+ _TEST_DECL(0045_subscribe_many_updates);
160
162
  _TEST_DECL(0046_rkt_cache);
161
163
  _TEST_DECL(0047_partial_buf_tmout);
162
164
  _TEST_DECL(0048_partitioner);
@@ -168,6 +170,7 @@ _TEST_DECL(0053_stats_timing);
168
170
  _TEST_DECL(0053_stats);
169
171
  _TEST_DECL(0054_offset_time);
170
172
  _TEST_DECL(0055_producer_latency);
173
+ _TEST_DECL(0055_producer_latency_mock);
171
174
  _TEST_DECL(0056_balanced_group_mt);
172
175
  _TEST_DECL(0057_invalid_topic);
173
176
  _TEST_DECL(0058_log);
@@ -216,6 +219,7 @@ _TEST_DECL(0099_commit_metadata);
216
219
  _TEST_DECL(0100_thread_interceptors);
217
220
  _TEST_DECL(0101_fetch_from_follower);
218
221
  _TEST_DECL(0102_static_group_rebalance);
222
+ _TEST_DECL(0102_static_group_rebalance_mock);
219
223
  _TEST_DECL(0103_transactions_local);
220
224
  _TEST_DECL(0103_transactions);
221
225
  _TEST_DECL(0104_fetch_from_follower_mock);
@@ -261,7 +265,13 @@ _TEST_DECL(0143_exponential_backoff_mock);
261
265
  _TEST_DECL(0144_idempotence_mock);
262
266
  _TEST_DECL(0145_pause_resume_mock);
263
267
  _TEST_DECL(0146_metadata_mock);
268
+ _TEST_DECL(0147_consumer_group_consumer_mock);
269
+ _TEST_DECL(0148_offset_fetch_commit_error_mock);
270
+ _TEST_DECL(0149_broker_same_host_port_mock);
264
271
  _TEST_DECL(0150_telemetry_mock);
272
+ _TEST_DECL(0151_purge_brokers_mock);
273
+ _TEST_DECL(0152_rebootstrap_local);
274
+ _TEST_DECL(0153_memberid);
265
275
 
266
276
  /* Manual tests */
267
277
  _TEST_DECL(8000_idle);
@@ -378,6 +388,8 @@ struct test tests[] = {
378
388
  .scenario = "noautocreate"),
379
389
  _TEST(0045_subscribe_update_mock, TEST_F_LOCAL),
380
390
  _TEST(0045_subscribe_update_racks_mock, TEST_F_LOCAL),
391
+ _TEST(0045_resubscribe_with_regex, 0, TEST_BRKVER(0, 9, 0, 0)),
392
+ _TEST(0045_subscribe_many_updates, 0, TEST_BRKVER(0, 10, 2, 0)),
381
393
  _TEST(0046_rkt_cache, TEST_F_LOCAL),
382
394
  _TEST(0047_partial_buf_tmout, TEST_F_KNOWN_ISSUE),
383
395
  _TEST(0048_partitioner,
@@ -394,6 +406,7 @@ struct test tests[] = {
394
406
  _TEST(0053_stats, 0),
395
407
  _TEST(0054_offset_time, 0, TEST_BRKVER(0, 10, 1, 0)),
396
408
  _TEST(0055_producer_latency, TEST_F_KNOWN_ISSUE_WIN32),
409
+ _TEST(0055_producer_latency_mock, TEST_F_LOCAL),
397
410
  _TEST(0056_balanced_group_mt, 0, TEST_BRKVER(0, 9, 0, 0)),
398
411
  _TEST(0057_invalid_topic, 0, TEST_BRKVER(0, 9, 0, 0)),
399
412
  _TEST(0058_log, TEST_F_LOCAL),
@@ -463,6 +476,7 @@ struct test tests[] = {
463
476
  _TEST(0100_thread_interceptors, TEST_F_LOCAL),
464
477
  _TEST(0101_fetch_from_follower, 0, TEST_BRKVER(2, 4, 0, 0)),
465
478
  _TEST(0102_static_group_rebalance, 0, TEST_BRKVER(2, 3, 0, 0)),
479
+ _TEST(0102_static_group_rebalance_mock, TEST_F_LOCAL),
466
480
  _TEST(0103_transactions_local, TEST_F_LOCAL),
467
481
  _TEST(0103_transactions,
468
482
  0,
@@ -519,8 +533,13 @@ struct test tests[] = {
519
533
  _TEST(0144_idempotence_mock, TEST_F_LOCAL, TEST_BRKVER(0, 11, 0, 0)),
520
534
  _TEST(0145_pause_resume_mock, TEST_F_LOCAL),
521
535
  _TEST(0146_metadata_mock, TEST_F_LOCAL),
536
+ _TEST(0147_consumer_group_consumer_mock, TEST_F_LOCAL),
537
+ _TEST(0148_offset_fetch_commit_error_mock, TEST_F_LOCAL),
538
+ _TEST(0149_broker_same_host_port_mock, TEST_F_LOCAL),
522
539
  _TEST(0150_telemetry_mock, 0),
523
-
540
+ _TEST(0151_purge_brokers_mock, TEST_F_LOCAL),
541
+ _TEST(0152_rebootstrap_local, TEST_F_LOCAL),
542
+ _TEST(0153_memberid, 0, TEST_BRKVER(0, 4, 0, 0)),
524
543
 
525
544
  /* Manual tests */
526
545
  _TEST(8000_idle, TEST_F_MANUAL),
@@ -544,6 +563,14 @@ static void test_socket_add(struct test *test, sockem_t *skm) {
544
563
  TEST_UNLOCK();
545
564
  }
546
565
 
566
+ void *test_socket_find(struct test *test, sockem_t *skm) {
567
+ void *ret;
568
+ TEST_LOCK();
569
+ ret = rd_list_find(&test->sockets, skm, rd_list_cmp_ptr);
570
+ TEST_UNLOCK();
571
+ return ret;
572
+ }
573
+
547
574
  static void test_socket_del(struct test *test, sockem_t *skm, int do_lock) {
548
575
  if (do_lock)
549
576
  TEST_LOCK();
@@ -843,6 +870,50 @@ int test_set_special_conf(const char *name, const char *val, int *timeoutp) {
843
870
  return 1;
844
871
  }
845
872
 
873
+ /**
874
+ * Reads max \p dst_size - 1 bytes from text or binary file at \p path
875
+ * to \p dst . In any case \p dst is NULL terminated.
876
+ *
877
+ * @return The number of bytes read, 0 if file was not found.
878
+ */
879
+ size_t test_read_file(const char *path, char *dst, size_t dst_size) {
880
+ FILE *fp;
881
+ char buf[1024];
882
+ size_t dst_len = 0;
883
+ size_t read_bytes;
884
+
885
+ #ifndef _WIN32
886
+ fp = fopen(path, "rb");
887
+ #else
888
+ fp = NULL;
889
+ errno = fopen_s(&fp, path, "rb");
890
+ #endif
891
+ if (!fp) {
892
+ if (errno == ENOENT) {
893
+ TEST_SAY("Test file %s not found\n", path);
894
+ return 0;
895
+ } else
896
+ TEST_FAIL("Failed to read %s: %s", path,
897
+ strerror(errno));
898
+ }
899
+
900
+ read_bytes = fread(buf, 1, sizeof(buf), fp);
901
+ while (read_bytes) {
902
+ if (dst_len + 1 >= dst_size)
903
+ break;
904
+
905
+ if (dst_len + read_bytes + 1 > dst_size)
906
+ read_bytes = dst_size - dst_len - 1;
907
+ memcpy(dst + dst_len, buf, read_bytes);
908
+ dst_len += read_bytes;
909
+ read_bytes = fread(buf, 1, sizeof(buf), fp);
910
+ }
911
+ dst[dst_len] = '\0';
912
+
913
+ fclose(fp);
914
+ return dst_len;
915
+ }
916
+
846
917
  static void test_read_conf_file(const char *conf_path,
847
918
  rd_kafka_conf_t *conf,
848
919
  rd_kafka_topic_conf_t *topic_conf,
@@ -917,6 +988,16 @@ static void test_read_conf_file(const char *conf_path,
917
988
  fclose(fp);
918
989
  }
919
990
 
991
+ /**
992
+ * @brief Log interceptor opaque holding the registered log callback.
993
+ */
994
+ typedef struct test_conf_log_interceptor_s {
995
+ void (*log_cb)(const rd_kafka_t *rk,
996
+ int level,
997
+ const char *fac,
998
+ const char *buf);
999
+ } test_conf_log_interceptor_t;
1000
+
920
1001
  /**
921
1002
  * @brief Get path to test config file
922
1003
  */
@@ -989,13 +1070,92 @@ void test_conf_init(rd_kafka_conf_t **conf,
989
1070
  test_conf_common_init(conf ? *conf : NULL, timeout);
990
1071
  }
991
1072
 
1073
+ /**
1074
+ * @brief Log callback calls the
1075
+ * interceptor and logs the message if the TEST_DEBUG environment
1076
+ * was set, allowing to see the debug messages when requested.
1077
+ *
1078
+ * @remark The interceptor shouldn't log the message again but do test related
1079
+ * actions such as checking if string is present, adding a sleep or
1080
+ * signaling a condition variable to continue with the next step of
1081
+ * the test.
1082
+ */
1083
+ static void test_conf_log_interceptor_log_cb(const rd_kafka_t *rk,
1084
+ int level,
1085
+ const char *fac,
1086
+ const char *buf) {
1087
+ int secs, msecs;
1088
+ struct timeval tv;
1089
+ test_conf_log_interceptor_t *interceptor = rd_kafka_opaque(rk);
1090
+ interceptor->log_cb(rk, level, fac, buf);
1091
+ const char *test_debug = test_getenv("TEST_DEBUG", NULL);
1092
+
1093
+ if (test_debug) {
1094
+ rd_gettimeofday(&tv, NULL);
1095
+ secs = (int)tv.tv_sec;
1096
+ msecs = (int)(tv.tv_usec / 1000);
1097
+ fprintf(stderr, "%%%i|%u.%03u|%s|%s| %s\n", level, secs, msecs,
1098
+ fac, rk ? rd_kafka_name(rk) : "", buf);
1099
+ }
1100
+ }
1101
+
1102
+ /**
1103
+ * @brief Set test log interceptor with NULL terminated `debug_contexts`
1104
+ * string array.
1105
+ * When debug log doesn't contain `all` and the debug contexts aren't
1106
+ * included, they are added to the debug configuration.
1107
+ * The interceptor is set as opaque in `rk` so the generic test log
1108
+ * callback can call the provided \p log_cb .
1109
+ *
1110
+ * @remark The returned interceptor structure set as opaque must be destroyed
1111
+ * after destroying the client instance.
1112
+ */
1113
+ test_conf_log_interceptor_t *
1114
+ test_conf_set_log_interceptor(rd_kafka_conf_t *conf,
1115
+ void (*log_cb)(const rd_kafka_t *rk,
1116
+ int level,
1117
+ const char *fac,
1118
+ const char *buf),
1119
+ const char **debug_contexts) {
1120
+ const char *test_debug = test_getenv("TEST_DEBUG", NULL);
1121
+ test_conf_log_interceptor_t *interceptor =
1122
+ rd_calloc(1, sizeof(*interceptor));
1123
+ interceptor->log_cb = log_cb;
1124
+ rd_kafka_conf_set_opaque(conf, interceptor);
1125
+ rd_kafka_conf_set_log_cb(conf, test_conf_log_interceptor_log_cb);
1126
+
1127
+ if (!test_debug || !strstr(test_debug, "all")) {
1128
+ char debug_with_contexts[256] = {0};
1129
+ size_t i = rd_snprintf(debug_with_contexts,
1130
+ sizeof(debug_with_contexts), "%s",
1131
+ test_debug ? test_debug : "");
1132
+ /* Add all debug contexts and set debug configuration */
1133
+ while (
1134
+ *debug_contexts &&
1135
+ i + strlen(*debug_contexts) +
1136
+ (i > 0 ? 2 : 1) /* 1 for the comma + 1 for the \0 */
1137
+ <= sizeof(debug_with_contexts)) {
1138
+ if (!strstr(debug_with_contexts, *debug_contexts)) {
1139
+ if (i > 0)
1140
+ debug_with_contexts[i++] = ',';
1141
+ i +=
1142
+ rd_snprintf(&debug_with_contexts[i],
1143
+ sizeof(debug_with_contexts) - i,
1144
+ "%s", *debug_contexts);
1145
+ }
1146
+ debug_contexts++;
1147
+ }
1148
+ test_conf_set(conf, "debug", debug_with_contexts);
1149
+ }
1150
+ return interceptor;
1151
+ }
992
1152
 
993
1153
  static RD_INLINE unsigned int test_rand(void) {
994
1154
  unsigned int r;
995
1155
  #ifdef _WIN32
996
1156
  rand_s(&r);
997
1157
  #else
998
- r = rand();
1158
+ r = rand();
999
1159
  #endif
1000
1160
  return r;
1001
1161
  }
@@ -1893,7 +2053,7 @@ int main(int argc, char **argv) {
1893
2053
  #ifdef _WIN32
1894
2054
  pcwd = _getcwd(cwd, sizeof(cwd) - 1);
1895
2055
  #else
1896
- pcwd = getcwd(cwd, sizeof(cwd) - 1);
2056
+ pcwd = getcwd(cwd, sizeof(cwd) - 1);
1897
2057
  #endif
1898
2058
  if (pcwd)
1899
2059
  TEST_SAY("Current directory: %s\n", cwd);
@@ -2535,7 +2695,6 @@ void test_rebalance_cb(rd_kafka_t *rk,
2535
2695
  }
2536
2696
 
2537
2697
 
2538
-
2539
2698
  rd_kafka_t *test_create_consumer(
2540
2699
  const char *group_id,
2541
2700
  void (*rebalance_cb)(rd_kafka_t *rk,
@@ -2957,6 +3116,106 @@ void test_consumer_verify_assignment0(const char *func,
2957
3116
  rd_kafka_topic_partition_list_destroy(assignment);
2958
3117
  }
2959
3118
 
3119
+ /**
3120
+ * @brief Verify that the consumer's assignment matches the expected assignment.
3121
+ * passed as a topic partition list in \p expected_assignment .
3122
+ */
3123
+ rd_bool_t test_consumer_verify_assignment_topic_partition_list0(
3124
+ const char *func,
3125
+ int line,
3126
+ rd_kafka_t *rk,
3127
+ const rd_kafka_topic_partition_list_t *expected_assignment) {
3128
+ rd_kafka_topic_partition_list_t *assignment,
3129
+ *expected_assignment_copy = NULL;
3130
+ rd_kafka_resp_err_t err;
3131
+ int i;
3132
+ rd_bool_t ret = rd_true;
3133
+
3134
+ if ((err = rd_kafka_assignment(rk, &assignment)))
3135
+ TEST_FAIL("%s:%d: Failed to get assignment for %s: %s", func,
3136
+ line, rd_kafka_name(rk), rd_kafka_err2str(err));
3137
+
3138
+ TEST_SAYL(4, "%s assignment (%d partition(s)):\n", rd_kafka_name(rk),
3139
+ assignment->cnt);
3140
+ for (i = 0; i < assignment->cnt; i++)
3141
+ TEST_SAYL(4, " %s [%" PRId32 "]\n", assignment->elems[i].topic,
3142
+ assignment->elems[i].partition);
3143
+
3144
+ if (assignment->cnt != expected_assignment->cnt) {
3145
+ ret = rd_false;
3146
+ goto done;
3147
+ }
3148
+
3149
+ expected_assignment_copy =
3150
+ rd_kafka_topic_partition_list_copy(expected_assignment);
3151
+ rd_kafka_topic_partition_list_sort(assignment, NULL, NULL);
3152
+ rd_kafka_topic_partition_list_sort(expected_assignment_copy, NULL,
3153
+ NULL);
3154
+
3155
+ for (i = 0; i < assignment->cnt; i++) {
3156
+ if (strcmp(assignment->elems[i].topic,
3157
+ expected_assignment_copy->elems[i].topic) ||
3158
+ assignment->elems[i].partition !=
3159
+ expected_assignment_copy->elems[i].partition) {
3160
+ ret = rd_false;
3161
+ goto done;
3162
+ }
3163
+ }
3164
+
3165
+ done:
3166
+ RD_IF_FREE(expected_assignment_copy,
3167
+ rd_kafka_topic_partition_list_destroy);
3168
+ rd_kafka_topic_partition_list_destroy(assignment);
3169
+ return ret;
3170
+ }
3171
+
3172
+ /**
3173
+ * @brief Wait until the consumer's assignment matches the expected assignment.
3174
+ * passed as a topic partition list in \p expected_assignment .
3175
+ * Polling if \p do_poll is true, otherwise sleeps.
3176
+ * Until \p timeout_ms milliseconds.
3177
+ */
3178
+ void test_consumer_wait_assignment_topic_partition_list0(
3179
+ const char *func,
3180
+ int line,
3181
+ rd_kafka_t *rk,
3182
+ rd_bool_t do_poll,
3183
+ const rd_kafka_topic_partition_list_t *expected_assignment,
3184
+ int timeout_ms) {
3185
+ int i;
3186
+ rd_ts_t end = test_clock() + timeout_ms * 1000;
3187
+ rd_bool_t verified = rd_false;
3188
+
3189
+ TEST_SAY("Verifying assignment\n");
3190
+ TEST_SAYL(4, "%s expected assignment (%d partition(s)):\n",
3191
+ rd_kafka_name(rk), expected_assignment->cnt);
3192
+ for (i = 0; i < expected_assignment->cnt; i++)
3193
+ TEST_SAYL(4, " %s [%" PRId32 "]\n",
3194
+ expected_assignment->elems[i].topic,
3195
+ expected_assignment->elems[i].partition);
3196
+
3197
+ do {
3198
+ verified =
3199
+ test_consumer_verify_assignment_topic_partition_list0(
3200
+ func, line, rk, expected_assignment);
3201
+ if (verified)
3202
+ break;
3203
+
3204
+ if (do_poll)
3205
+ test_consumer_poll_once(rk, NULL, 100);
3206
+ else
3207
+ rd_usleep(100 * 1000, NULL);
3208
+
3209
+ } while (test_clock() < end);
3210
+
3211
+ if (!verified) {
3212
+ TEST_FAIL(
3213
+ "%s:%d: Expected assignment not found in %s's "
3214
+ "assignment within timeout %d",
3215
+ func, line, rd_kafka_name(rk), timeout_ms);
3216
+ }
3217
+ TEST_SAY("Verified assignment\n");
3218
+ }
2960
3219
 
2961
3220
 
2962
3221
  /**
@@ -2978,6 +3237,34 @@ void test_consumer_subscribe(rd_kafka_t *rk, const char *topic) {
2978
3237
  }
2979
3238
 
2980
3239
 
3240
+ /**
3241
+ * @brief Start subscribing for multiple topics
3242
+ */
3243
+ void test_consumer_subscribe_multi(rd_kafka_t *rk, int topic_count, ...) {
3244
+ rd_kafka_topic_partition_list_t *topics;
3245
+ rd_kafka_resp_err_t err;
3246
+ va_list ap;
3247
+ int i;
3248
+
3249
+ topics = rd_kafka_topic_partition_list_new(topic_count);
3250
+
3251
+ va_start(ap, topic_count);
3252
+ for (i = 0; i < topic_count; i++) {
3253
+ const char *topic = va_arg(ap, const char *);
3254
+ rd_kafka_topic_partition_list_add(topics, topic,
3255
+ RD_KAFKA_PARTITION_UA);
3256
+ }
3257
+ va_end(ap);
3258
+
3259
+ err = rd_kafka_subscribe(rk, topics);
3260
+ if (err)
3261
+ TEST_FAIL("%s: Failed to subscribe to topics: %s\n",
3262
+ rd_kafka_name(rk), rd_kafka_err2str(err));
3263
+
3264
+ rd_kafka_topic_partition_list_destroy(topics);
3265
+ }
3266
+
3267
+
2981
3268
  void test_consumer_assign(const char *what,
2982
3269
  rd_kafka_t *rk,
2983
3270
  rd_kafka_topic_partition_list_t *partitions) {
@@ -3055,6 +3342,44 @@ void test_consumer_incremental_unassign(
3055
3342
  }
3056
3343
 
3057
3344
 
3345
+ void test_consumer_assign_by_rebalance_protocol(
3346
+ const char *what,
3347
+ rd_kafka_t *rk,
3348
+ rd_kafka_topic_partition_list_t *parts) {
3349
+ const char *protocol = rd_kafka_rebalance_protocol(rk);
3350
+ if (!strcmp(protocol, "NONE")) {
3351
+ TEST_FAIL(
3352
+ "Assign not supported with "
3353
+ "rebalance protocol NONE\n");
3354
+ } else if (!strcmp(protocol, "EAGER")) {
3355
+ TEST_SAY("Assign: %d partition(s)\n", parts->cnt);
3356
+ test_consumer_assign(what, rk, parts);
3357
+ } else {
3358
+ TEST_SAY("Assign: %d partition(s)\n", parts->cnt);
3359
+ test_consumer_incremental_assign(what, rk, parts);
3360
+ }
3361
+ }
3362
+
3363
+
3364
+ void test_consumer_unassign_by_rebalance_protocol(
3365
+ const char *what,
3366
+ rd_kafka_t *rk,
3367
+ rd_kafka_topic_partition_list_t *parts) {
3368
+ const char *protocol = rd_kafka_rebalance_protocol(rk);
3369
+ if (!strcmp(protocol, "NONE")) {
3370
+ TEST_FAIL(
3371
+ "Unassign not supported with "
3372
+ "rebalance protocol NONE\n");
3373
+ } else if (!strcmp(protocol, "EAGER")) {
3374
+ TEST_SAY("Unassign all partition(s)\n");
3375
+ test_consumer_unassign(what, rk);
3376
+ } else {
3377
+ TEST_SAY("Unassign: %d partition(s)\n", parts->cnt);
3378
+ test_consumer_incremental_unassign(what, rk, parts);
3379
+ }
3380
+ }
3381
+
3382
+
3058
3383
  /**
3059
3384
  * @brief Assign a single partition with an optional starting offset
3060
3385
  */
@@ -4429,9 +4754,29 @@ void test_flush(rd_kafka_t *rk, int timeout_ms) {
4429
4754
  rd_kafka_outq_len(rk));
4430
4755
  }
4431
4756
 
4757
+ int test_is_forbidden_conf_group_protocol_consumer(const char *name) {
4758
+ char *forbidden_conf[] = {
4759
+ "session.timeout.ms", "partition.assignment.strategy",
4760
+ "heartbeat.interval.ms", "group.protocol.type", NULL};
4761
+ int i;
4762
+ if (test_consumer_group_protocol_classic())
4763
+ return 0;
4764
+ for (i = 0; forbidden_conf[i]; i++) {
4765
+ if (!strcmp(name, forbidden_conf[i]))
4766
+ return 1;
4767
+ }
4768
+ return 0;
4769
+ }
4432
4770
 
4433
4771
  void test_conf_set(rd_kafka_conf_t *conf, const char *name, const char *val) {
4434
4772
  char errstr[512];
4773
+ if (test_is_forbidden_conf_group_protocol_consumer(name)) {
4774
+ TEST_SAY(
4775
+ "Skipping setting forbidden configuration %s for CONSUMER "
4776
+ "protocol.\n",
4777
+ name);
4778
+ return;
4779
+ }
4435
4780
  if (rd_kafka_conf_set(conf, name, val, errstr, sizeof(errstr)) !=
4436
4781
  RD_KAFKA_CONF_OK)
4437
4782
  TEST_FAIL("Failed to set config \"%s\"=\"%s\": %s\n", name, val,
@@ -4547,6 +4892,38 @@ int test_needs_auth(void) {
4547
4892
  return strcmp(sec, "plaintext");
4548
4893
  }
4549
4894
 
4895
+ /**
4896
+ * @brief Create a topic-partition list with vararg arguments.
4897
+ *
4898
+ * @param cnt Number of topic-partitions.
4899
+ * @param ...vararg is a tuple of:
4900
+ * const char *topic_name
4901
+ * int32_t partition
4902
+ *
4903
+ * @return The desired topic-partition list
4904
+ *
4905
+ * @remark The returned pointer ownership is transferred to the caller.
4906
+ */
4907
+ rd_kafka_topic_partition_list_t *test_topic_partitions(int cnt, ...) {
4908
+ va_list ap;
4909
+ int i = 0;
4910
+ const char *topic_name;
4911
+
4912
+ rd_kafka_topic_partition_list_t *rktparlist =
4913
+ rd_kafka_topic_partition_list_new(cnt);
4914
+ va_start(ap, cnt);
4915
+ while (i < cnt) {
4916
+ topic_name = va_arg(ap, const char *);
4917
+ int32_t partition = va_arg(ap, int32_t);
4918
+
4919
+ rd_kafka_topic_partition_list_add(rktparlist, topic_name,
4920
+ partition);
4921
+ i++;
4922
+ }
4923
+ va_end(ap);
4924
+
4925
+ return rktparlist;
4926
+ }
4550
4927
 
4551
4928
  void test_print_partition_list(
4552
4929
  const rd_kafka_topic_partition_list_t *partitions) {
@@ -4851,6 +5228,15 @@ void test_create_topic(rd_kafka_t *use_rk,
4851
5228
  replication_factor, NULL);
4852
5229
  }
4853
5230
 
5231
+ void test_create_topic_wait_exists(rd_kafka_t *use_rk,
5232
+ const char *topicname,
5233
+ int partition_cnt,
5234
+ int replication_factor,
5235
+ int timeout) {
5236
+ test_create_topic(use_rk, topicname, partition_cnt, replication_factor);
5237
+ test_wait_topic_exists(use_rk, topicname, timeout);
5238
+ }
5239
+
4854
5240
 
4855
5241
  /**
4856
5242
  * @brief Create topic using kafka-topics.sh --delete
@@ -5464,7 +5850,8 @@ void test_headers_dump(const char *what,
5464
5850
 
5465
5851
 
5466
5852
  /**
5467
- * @brief Retrieve and return the list of broker ids in the cluster.
5853
+ * @brief Retrieve and return the list of broker ids in the cluster by
5854
+ * sending a Metadata request.
5468
5855
  *
5469
5856
  * @param rk Optional instance to use.
5470
5857
  * @param cntp Will be updated to the number of brokers returned.
@@ -5774,6 +6161,14 @@ void test_wait_metadata_update(rd_kafka_t *rk,
5774
6161
  test_timing_t t_md;
5775
6162
  rd_kafka_t *our_rk = NULL;
5776
6163
 
6164
+ /* Wait an additional second for the topic to propagate in
6165
+ * the cluster. This is not perfect but a cheap workaround for
6166
+ * the asynchronous nature of topic creations in Kafka.
6167
+ * Sleeping comes before the full metadata requests because otherwise
6168
+ * those requests can trigger rejoins in case of
6169
+ * regex subscriptions. */
6170
+ rd_sleep(1);
6171
+
5777
6172
  if (!rk)
5778
6173
  rk = our_rk = test_create_handle(RD_KAFKA_PRODUCER, NULL);
5779
6174
 
@@ -5814,11 +6209,6 @@ void test_wait_topic_exists(rd_kafka_t *rk, const char *topic, int tmout) {
5814
6209
  rd_kafka_metadata_topic_t topics = {.topic = (char *)topic};
5815
6210
 
5816
6211
  test_wait_metadata_update(rk, &topics, 1, NULL, 0, tmout);
5817
-
5818
- /* Wait an additional second for the topic to propagate in
5819
- * the cluster. This is not perfect but a cheap workaround for
5820
- * the asynchronous nature of topic creations in Kafka. */
5821
- rd_sleep(1);
5822
6212
  }
5823
6213
 
5824
6214
 
@@ -7144,7 +7534,7 @@ rd_kafka_mock_cluster_t *test_mock_cluster_new(int broker_cnt,
7144
7534
  * received by mock cluster \p mcluster, matching
7145
7535
  * function \p match , called with opaque \p opaque .
7146
7536
  */
7147
- static size_t test_mock_get_matching_request_cnt(
7537
+ size_t test_mock_get_matching_request_cnt(
7148
7538
  rd_kafka_mock_cluster_t *mcluster,
7149
7539
  rd_bool_t (*match)(rd_kafka_mock_request_t *request, void *opaque),
7150
7540
  void *opaque) {
@@ -7189,14 +7579,89 @@ size_t test_mock_wait_matching_requests(
7189
7579
  while (matching_request_cnt < expected_cnt) {
7190
7580
  matching_request_cnt =
7191
7581
  test_mock_get_matching_request_cnt(mcluster, match, opaque);
7192
- if (matching_request_cnt < expected_cnt)
7582
+ if (matching_request_cnt < expected_cnt) {
7583
+ TEST_SAYL(3,
7584
+ "Still waiting to see %" PRIusz
7585
+ " requests"
7586
+ ", got %" PRIusz " \n",
7587
+ expected_cnt, matching_request_cnt);
7193
7588
  rd_usleep(100 * 1000, 0);
7589
+ }
7194
7590
  }
7195
7591
 
7196
7592
  rd_usleep(confidence_interval_ms * 1000, 0);
7197
7593
  return test_mock_get_matching_request_cnt(mcluster, match, opaque);
7198
7594
  }
7199
7595
 
7596
+ /**
7597
+ * @brief Sets an assignment for \p member_cnt members in \p mcluster.
7598
+ * Followed by \p member_cnt pairs of
7599
+ * (rd_kafka_t *, rd_kafka_topic_partition_list_t *) corresponding to
7600
+ * a member and its assignment.
7601
+ */
7602
+ void test_mock_cluster_member_assignment(rd_kafka_mock_cluster_t *mcluster,
7603
+ int member_cnt,
7604
+ ...) {
7605
+ int i = 0;
7606
+ char **member_ids = rd_calloc(member_cnt, sizeof(*member_ids));
7607
+ rd_kafka_topic_partition_list_t **assignment =
7608
+ rd_calloc(member_cnt, sizeof(*assignment));
7609
+ char *group_id = NULL;
7610
+ rd_kafka_mock_cgrp_consumer_target_assignment_t *target_assignment;
7611
+ va_list ap;
7612
+
7613
+ va_start(ap, member_cnt);
7614
+ for (i = 0; i < member_cnt; i++) {
7615
+ rd_kafka_consumer_group_metadata_t *cgmetadata = NULL;
7616
+ rd_kafka_t *consumer = va_arg(ap, rd_kafka_t *);
7617
+ rd_kafka_topic_partition_list_t *member_assignment =
7618
+ va_arg(ap, rd_kafka_topic_partition_list_t *);
7619
+
7620
+ const char *member_id = NULL;
7621
+ const char *member_group_id = NULL;
7622
+ rd_bool_t first_time = rd_true;
7623
+ /* Await member joins the group and obtains a member id
7624
+ * to use for setting target assignment. */
7625
+ while (!member_id || *member_id == '\0' || !member_group_id) {
7626
+ if (!first_time)
7627
+ rd_usleep(100000, NULL);
7628
+ cgmetadata = rd_kafka_consumer_group_metadata(consumer);
7629
+ member_id = rd_kafka_consumer_group_metadata_member_id(
7630
+ cgmetadata);
7631
+ member_group_id =
7632
+ rd_kafka_consumer_group_metadata_group_id(
7633
+ cgmetadata);
7634
+ first_time = rd_false;
7635
+ }
7636
+
7637
+ if (!group_id)
7638
+ group_id = rd_strdup(member_group_id);
7639
+ else
7640
+ rd_assert(!strcmp(group_id, member_group_id));
7641
+
7642
+ member_ids[i] = rd_strdup(member_id);
7643
+ assignment[i] =
7644
+ rd_kafka_topic_partition_list_copy(member_assignment);
7645
+ rd_kafka_consumer_group_metadata_destroy(cgmetadata);
7646
+ }
7647
+ va_end(ap);
7648
+
7649
+ target_assignment = rd_kafka_mock_cgrp_consumer_target_assignment_new(
7650
+ member_ids, member_cnt, assignment);
7651
+ rd_kafka_mock_cgrp_consumer_target_assignment(mcluster, group_id,
7652
+ target_assignment);
7653
+ rd_kafka_mock_cgrp_consumer_target_assignment_destroy(
7654
+ target_assignment);
7655
+
7656
+ for (i = 0; i < member_cnt; i++) {
7657
+ rd_free(member_ids[i]);
7658
+ rd_kafka_topic_partition_list_destroy(assignment[i]);
7659
+ }
7660
+ rd_free(member_ids);
7661
+ rd_free(assignment);
7662
+ rd_free(group_id);
7663
+ }
7664
+
7200
7665
  /**
7201
7666
  * @name Sub-tests
7202
7667
  */
@@ -7307,12 +7772,7 @@ const char *test_consumer_group_protocol() {
7307
7772
  return test_consumer_group_protocol_str;
7308
7773
  }
7309
7774
 
7310
- int test_consumer_group_protocol_generic() {
7775
+ int test_consumer_group_protocol_classic() {
7311
7776
  return !test_consumer_group_protocol_str ||
7312
7777
  !strcmp(test_consumer_group_protocol_str, "classic");
7313
7778
  }
7314
-
7315
- int test_consumer_group_protocol_consumer() {
7316
- return test_consumer_group_protocol_str &&
7317
- !strcmp(test_consumer_group_protocol_str, "consumer");
7318
- }