@platformatic/rdkafka 4.0.1 → 4.1.0-alpha.1

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 (292) 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 +4 -4
  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/configure +0 -0
  17. package/deps/librdkafka/debian/rules +0 -0
  18. package/deps/librdkafka/dev-conf.sh +0 -0
  19. package/deps/librdkafka/examples/consumer.c +18 -8
  20. package/deps/librdkafka/examples/describe_consumer_groups.c +25 -6
  21. package/deps/librdkafka/examples/incremental_alter_configs.c +4 -5
  22. package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +26 -42
  23. package/deps/librdkafka/examples/openssl_engine_example.cpp +3 -4
  24. package/deps/librdkafka/examples/producer.cpp +2 -2
  25. package/deps/librdkafka/examples/user_scram.c +4 -5
  26. package/deps/librdkafka/examples/win_ssl_cert_store.cpp +4 -3
  27. package/deps/librdkafka/lds-gen.py +0 -0
  28. package/deps/librdkafka/mklove/Makefile.base +0 -0
  29. package/deps/librdkafka/packaging/RELEASE.md +8 -0
  30. package/deps/librdkafka/packaging/alpine/build-alpine.sh +0 -0
  31. package/deps/librdkafka/packaging/cp/README.md +4 -1
  32. package/deps/librdkafka/packaging/cp/check_features.c +12 -4
  33. package/deps/librdkafka/packaging/cp/verify-deb.sh +6 -6
  34. package/deps/librdkafka/packaging/cp/verify-packages.sh +52 -31
  35. package/deps/librdkafka/packaging/cp/verify-rpm.sh +6 -13
  36. package/deps/librdkafka/packaging/debian/rules +0 -0
  37. package/deps/librdkafka/packaging/get_version.py +0 -0
  38. package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +0 -0
  39. package/deps/librdkafka/packaging/mingw-w64/{travis-before-install.sh → export-variables.sh} +0 -7
  40. package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +1 -1
  41. package/deps/librdkafka/packaging/nuget/artifact.py +0 -0
  42. package/deps/librdkafka/packaging/nuget/cleanup-s3.py +0 -0
  43. package/deps/librdkafka/packaging/nuget/nuget.sh +0 -0
  44. package/deps/librdkafka/packaging/nuget/packaging.py +0 -0
  45. package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +0 -0
  46. package/deps/librdkafka/packaging/nuget/release.py +0 -0
  47. package/deps/librdkafka/packaging/nuget/requirements.txt +3 -3
  48. package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +0 -0
  49. package/deps/librdkafka/packaging/rpm/tests/run-test.sh +0 -0
  50. package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +0 -0
  51. package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +3 -1
  52. package/deps/librdkafka/packaging/tools/build-deb-package.sh +0 -0
  53. package/deps/librdkafka/packaging/tools/build-debian.sh +0 -0
  54. package/deps/librdkafka/packaging/tools/build-manylinux.sh +0 -0
  55. package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +0 -0
  56. package/deps/librdkafka/packaging/tools/distro-build.sh +0 -0
  57. package/deps/librdkafka/packaging/tools/gh-release-checksums.py +0 -0
  58. package/deps/librdkafka/packaging/tools/rdutcoverage.sh +0 -0
  59. package/deps/librdkafka/packaging/tools/run-in-docker.sh +28 -0
  60. package/deps/librdkafka/packaging/tools/run-integration-tests.sh +31 -0
  61. package/deps/librdkafka/packaging/tools/run-style-check.sh +4 -0
  62. package/deps/librdkafka/packaging/tools/style-format.sh +6 -5
  63. package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
  64. package/deps/librdkafka/service.yml +154 -0
  65. package/deps/librdkafka/src/generate_proto.sh +0 -0
  66. package/deps/librdkafka/src/rd.h +145 -2
  67. package/deps/librdkafka/src/rdaddr.h +6 -7
  68. package/deps/librdkafka/src/rdatomic.h +15 -11
  69. package/deps/librdkafka/src/rdavg.h +3 -2
  70. package/deps/librdkafka/src/rdbase64.c +33 -2
  71. package/deps/librdkafka/src/rdbase64.h +2 -0
  72. package/deps/librdkafka/src/rdendian.h +10 -9
  73. package/deps/librdkafka/src/rdhttp.c +418 -100
  74. package/deps/librdkafka/src/rdhttp.h +23 -5
  75. package/deps/librdkafka/src/rdkafka.c +299 -145
  76. package/deps/librdkafka/src/rdkafka.h +89 -6
  77. package/deps/librdkafka/src/rdkafka_admin.c +482 -105
  78. package/deps/librdkafka/src/rdkafka_admin.h +42 -0
  79. package/deps/librdkafka/src/rdkafka_broker.c +463 -312
  80. package/deps/librdkafka/src/rdkafka_broker.h +68 -10
  81. package/deps/librdkafka/src/rdkafka_buf.c +8 -5
  82. package/deps/librdkafka/src/rdkafka_buf.h +4 -3
  83. package/deps/librdkafka/src/rdkafka_cert.c +25 -1
  84. package/deps/librdkafka/src/rdkafka_cert.h +4 -3
  85. package/deps/librdkafka/src/rdkafka_cgrp.c +468 -143
  86. package/deps/librdkafka/src/rdkafka_cgrp.h +36 -2
  87. package/deps/librdkafka/src/rdkafka_conf.c +526 -102
  88. package/deps/librdkafka/src/rdkafka_conf.h +68 -4
  89. package/deps/librdkafka/src/rdkafka_feature.c +472 -35
  90. package/deps/librdkafka/src/rdkafka_feature.h +2 -0
  91. package/deps/librdkafka/src/rdkafka_fetcher.c +22 -2
  92. package/deps/librdkafka/src/rdkafka_fetcher.h +2 -2
  93. package/deps/librdkafka/src/rdkafka_int.h +84 -46
  94. package/deps/librdkafka/src/rdkafka_metadata.c +221 -136
  95. package/deps/librdkafka/src/rdkafka_metadata.h +15 -11
  96. package/deps/librdkafka/src/rdkafka_metadata_cache.c +279 -73
  97. package/deps/librdkafka/src/rdkafka_mock.c +795 -19
  98. package/deps/librdkafka/src/rdkafka_mock.h +119 -0
  99. package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1298 -132
  100. package/deps/librdkafka/src/rdkafka_mock_handlers.c +345 -49
  101. package/deps/librdkafka/src/rdkafka_mock_int.h +180 -61
  102. package/deps/librdkafka/src/rdkafka_msg.c +35 -19
  103. package/deps/librdkafka/src/rdkafka_msg.h +3 -3
  104. package/deps/librdkafka/src/rdkafka_msgset_writer.c +14 -10
  105. package/deps/librdkafka/src/rdkafka_offset.c +33 -5
  106. package/deps/librdkafka/src/rdkafka_op.c +1 -1
  107. package/deps/librdkafka/src/rdkafka_op.h +45 -21
  108. package/deps/librdkafka/src/rdkafka_partition.c +118 -23
  109. package/deps/librdkafka/src/rdkafka_partition.h +16 -7
  110. package/deps/librdkafka/src/rdkafka_proto.h +4 -1
  111. package/deps/librdkafka/src/rdkafka_protocol.h +1 -0
  112. package/deps/librdkafka/src/rdkafka_queue.c +125 -48
  113. package/deps/librdkafka/src/rdkafka_queue.h +19 -0
  114. package/deps/librdkafka/src/rdkafka_range_assignor.c +1 -1
  115. package/deps/librdkafka/src/rdkafka_request.c +336 -64
  116. package/deps/librdkafka/src/rdkafka_request.h +24 -1
  117. package/deps/librdkafka/src/rdkafka_sasl.c +5 -3
  118. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +14 -10
  119. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1166 -89
  120. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +13 -3
  121. package/deps/librdkafka/src/rdkafka_sasl_plain.c +3 -3
  122. package/deps/librdkafka/src/rdkafka_sasl_scram.c +4 -3
  123. package/deps/librdkafka/src/rdkafka_ssl.c +306 -81
  124. package/deps/librdkafka/src/rdkafka_ssl.h +22 -0
  125. package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4 -0
  126. package/deps/librdkafka/src/rdkafka_telemetry.c +80 -23
  127. package/deps/librdkafka/src/rdkafka_telemetry_encode.c +5 -1
  128. package/deps/librdkafka/src/rdkafka_telemetry_encode.h +20 -20
  129. package/deps/librdkafka/src/rdkafka_topic.c +220 -137
  130. package/deps/librdkafka/src/rdkafka_topic.h +14 -8
  131. package/deps/librdkafka/src/rdkafka_transport.c +59 -47
  132. package/deps/librdkafka/src/rdkafka_transport.h +5 -0
  133. package/deps/librdkafka/src/rdkafka_txnmgr.c +6 -1
  134. package/deps/librdkafka/src/rdmap.c +6 -1
  135. package/deps/librdkafka/src/rdrand.c +11 -1
  136. package/deps/librdkafka/src/rdtime.h +48 -17
  137. package/deps/librdkafka/src/rdunittest.c +42 -25
  138. package/deps/librdkafka/src/rdunittest.h +2 -0
  139. package/deps/librdkafka/src/rdwin32.h +1 -1
  140. package/deps/librdkafka/src/regexp.c +47 -42
  141. package/deps/librdkafka/src/tinycthread_extra.c +45 -21
  142. package/deps/librdkafka/src/tinycthread_extra.h +7 -3
  143. package/deps/librdkafka/src-cpp/rdkafkacpp.h +28 -2
  144. package/deps/librdkafka/tests/0001-multiobj.c +4 -0
  145. package/deps/librdkafka/tests/0004-conf.c +103 -36
  146. package/deps/librdkafka/tests/0009-mock_cluster.c +1 -0
  147. package/deps/librdkafka/tests/0011-produce_batch.c +2 -1
  148. package/deps/librdkafka/tests/0016-client_swname.c +18 -3
  149. package/deps/librdkafka/tests/0017-compression.c +6 -8
  150. package/deps/librdkafka/tests/0018-cgrp_term.c +8 -3
  151. package/deps/librdkafka/tests/0021-rkt_destroy.c +1 -0
  152. package/deps/librdkafka/tests/0022-consume_batch.c +4 -1
  153. package/deps/librdkafka/tests/0026-consume_pause.c +12 -14
  154. package/deps/librdkafka/tests/0028-long_topicnames.c +1 -1
  155. package/deps/librdkafka/tests/0029-assign_offset.c +6 -8
  156. package/deps/librdkafka/tests/0030-offset_commit.c +2 -2
  157. package/deps/librdkafka/tests/0033-regex_subscribe.c +33 -17
  158. package/deps/librdkafka/tests/0034-offset_reset.c +25 -4
  159. package/deps/librdkafka/tests/0036-partial_fetch.c +1 -0
  160. package/deps/librdkafka/tests/0038-performance.c +1 -0
  161. package/deps/librdkafka/tests/0040-io_event.c +11 -5
  162. package/deps/librdkafka/tests/0041-fetch_max_bytes.c +1 -0
  163. package/deps/librdkafka/tests/0044-partition_cnt.c +3 -2
  164. package/deps/librdkafka/tests/0045-subscribe_update.c +284 -20
  165. package/deps/librdkafka/tests/0047-partial_buf_tmout.c +1 -0
  166. package/deps/librdkafka/tests/0048-partitioner.c +1 -1
  167. package/deps/librdkafka/tests/0050-subscribe_adds.c +1 -0
  168. package/deps/librdkafka/tests/0051-assign_adds.c +1 -0
  169. package/deps/librdkafka/tests/0052-msg_timestamps.c +22 -4
  170. package/deps/librdkafka/tests/0053-stats_cb.cpp +12 -20
  171. package/deps/librdkafka/tests/0055-producer_latency.c +176 -3
  172. package/deps/librdkafka/tests/0056-balanced_group_mt.c +6 -2
  173. package/deps/librdkafka/tests/0058-log.cpp +3 -3
  174. package/deps/librdkafka/tests/0059-bsearch.cpp +8 -4
  175. package/deps/librdkafka/tests/0061-consumer_lag.cpp +25 -5
  176. package/deps/librdkafka/tests/0067-empty_topic.cpp +3 -0
  177. package/deps/librdkafka/tests/0068-produce_timeout.c +21 -23
  178. package/deps/librdkafka/tests/0069-consumer_add_parts.c +3 -7
  179. package/deps/librdkafka/tests/0075-retry.c +38 -1
  180. package/deps/librdkafka/tests/0076-produce_retry.c +2 -0
  181. package/deps/librdkafka/tests/0077-compaction.c +8 -2
  182. package/deps/librdkafka/tests/0080-admin_ut.c +34 -4
  183. package/deps/librdkafka/tests/0081-admin.c +455 -155
  184. package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +4 -0
  185. package/deps/librdkafka/tests/0083-cb_event.c +8 -3
  186. package/deps/librdkafka/tests/0084-destroy_flags.c +14 -18
  187. package/deps/librdkafka/tests/0085-headers.cpp +4 -0
  188. package/deps/librdkafka/tests/0086-purge.c +40 -7
  189. package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +1 -1
  190. package/deps/librdkafka/tests/0089-max_poll_interval.c +12 -7
  191. package/deps/librdkafka/tests/0090-idempotence.c +1 -2
  192. package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +5 -7
  193. package/deps/librdkafka/tests/0092-mixed_msgver.c +6 -0
  194. package/deps/librdkafka/tests/0093-holb.c +8 -5
  195. package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +1 -0
  196. package/deps/librdkafka/tests/0097-ssl_verify.cpp +262 -70
  197. package/deps/librdkafka/tests/0098-consumer-txn.cpp +16 -16
  198. package/deps/librdkafka/tests/0099-commit_metadata.c +1 -1
  199. package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +1 -1
  200. package/deps/librdkafka/tests/0102-static_group_rebalance.c +317 -16
  201. package/deps/librdkafka/tests/0103-transactions.c +7 -7
  202. package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +1 -0
  203. package/deps/librdkafka/tests/0105-transactions_mock.c +18 -11
  204. package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +35 -14
  205. package/deps/librdkafka/tests/0107-topic_recreate.c +2 -2
  206. package/deps/librdkafka/tests/0109-auto_create_topics.cpp +86 -26
  207. package/deps/librdkafka/tests/0110-batch_size.cpp +1 -2
  208. package/deps/librdkafka/tests/0112-assign_unknown_part.c +3 -14
  209. package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +248 -104
  210. package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +3 -3
  211. package/deps/librdkafka/tests/0115-producer_auth.cpp +4 -1
  212. package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +7 -5
  213. package/deps/librdkafka/tests/0117-mock_errors.c +15 -5
  214. package/deps/librdkafka/tests/0118-commit_rebalance.c +41 -8
  215. package/deps/librdkafka/tests/0119-consumer_auth.cpp +20 -1
  216. package/deps/librdkafka/tests/0120-asymmetric_subscription.c +8 -3
  217. package/deps/librdkafka/tests/0125-immediate_flush.c +1 -1
  218. package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +323 -8
  219. package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +1 -0
  220. package/deps/librdkafka/tests/0132-strategy_ordering.c +12 -4
  221. package/deps/librdkafka/tests/0133-ssl_keys.c +28 -6
  222. package/deps/librdkafka/tests/0137-barrier_batch_consume.c +24 -14
  223. package/deps/librdkafka/tests/0139-offset_validation_mock.c +510 -2
  224. package/deps/librdkafka/tests/0140-commit_metadata.cpp +1 -1
  225. package/deps/librdkafka/tests/0142-reauthentication.c +37 -17
  226. package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +39 -40
  227. package/deps/librdkafka/tests/0146-metadata_mock.c +76 -15
  228. package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +952 -0
  229. package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +563 -0
  230. package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
  231. package/deps/librdkafka/tests/0150-telemetry_mock.c +9 -6
  232. package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
  233. package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
  234. package/deps/librdkafka/tests/0153-memberid.c +128 -0
  235. package/deps/librdkafka/tests/CMakeLists.txt +6 -0
  236. package/deps/librdkafka/tests/LibrdkafkaTestApp.py +34 -9
  237. package/deps/librdkafka/tests/autotest.sh +0 -0
  238. package/deps/librdkafka/tests/broker_version_tests.py +0 -0
  239. package/deps/librdkafka/tests/buildbox.sh +0 -0
  240. package/deps/librdkafka/tests/cleanup-checker-tests.sh +0 -0
  241. package/deps/librdkafka/tests/cluster_testing.py +0 -0
  242. package/deps/librdkafka/tests/delete-test-topics.sh +0 -0
  243. package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
  244. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
  245. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
  246. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
  247. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +42 -101
  248. package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
  249. package/deps/librdkafka/tests/fixtures/ssl/client2.key +41 -29
  250. package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +112 -37
  251. package/deps/librdkafka/tests/gen-ssl-certs.sh +0 -0
  252. package/deps/librdkafka/tests/interactive_broker_version.py +0 -0
  253. package/deps/librdkafka/tests/java/Makefile +2 -1
  254. package/deps/librdkafka/tests/java/run-class.sh +0 -0
  255. package/deps/librdkafka/tests/lz4_manual_test.sh +0 -0
  256. package/deps/librdkafka/tests/multi-broker-version-test.sh +0 -0
  257. package/deps/librdkafka/tests/parse-refcnt.sh +0 -0
  258. package/deps/librdkafka/tests/performance_plot.py +0 -0
  259. package/deps/librdkafka/tests/requirements.txt +1 -1
  260. package/deps/librdkafka/tests/run-all-tests.sh +79 -0
  261. package/deps/librdkafka/tests/run-consumer-tests.sh +0 -0
  262. package/deps/librdkafka/tests/run-producer-tests.sh +0 -0
  263. package/deps/librdkafka/tests/run-test-batches.py +157 -0
  264. package/deps/librdkafka/tests/run-test.sh +0 -0
  265. package/deps/librdkafka/tests/sasl_test.py +0 -0
  266. package/deps/librdkafka/tests/test.c +478 -18
  267. package/deps/librdkafka/tests/test.h +62 -13
  268. package/deps/librdkafka/tests/testcpp.cpp +6 -1
  269. package/deps/librdkafka/tests/testcpp.h +30 -2
  270. package/deps/librdkafka/tests/testshared.h +16 -2
  271. package/deps/librdkafka/tests/tools/stats/graph.py +0 -0
  272. package/deps/librdkafka/tests/tools/stats/to_csv.py +1 -1
  273. package/deps/librdkafka/tests/trivup/trivup-0.14.0.tar.gz +0 -0
  274. package/deps/librdkafka/tests/until-fail.sh +0 -0
  275. package/deps/librdkafka/tests/xxxx-metadata.cpp +1 -1
  276. package/deps/librdkafka/vcpkg.json +1 -1
  277. package/deps/librdkafka/win32/setup-msys2.ps1 +24 -8
  278. package/deps/librdkafka/win32/setup-vcpkg.ps1 +28 -6
  279. package/deps/librdkafka/win32/tests/tests.vcxproj +6 -0
  280. package/deps/librdkafka/win32/wingetopt.h +5 -4
  281. package/errors.d.ts +27 -1
  282. package/lib/error.js +29 -3
  283. package/make_docs.sh +0 -0
  284. package/package.json +10 -11
  285. package/run_docker.sh +0 -0
  286. package/src/callbacks.cc +6 -9
  287. package/src/callbacks.h +1 -5
  288. package/test/kafka-consumer-worker.js +10 -7
  289. package/test/kafka-consumer.spec.js +32 -21
  290. package/deps/librdkafka/.semaphore/project.yml +0 -43
  291. package/deps/librdkafka/.semaphore/project_public.yml +0 -20
  292. package/deps/librdkafka/win32/install-openssl.ps1 +0 -33
@@ -192,14 +192,14 @@ static void do_test_permanent_error_retried(rd_kafka_resp_err_t err) {
192
192
  rktpar = rd_kafka_topic_partition_list_add(rktpars, topic, 0);
193
193
  rktpar->offset = 0;
194
194
 
195
- /* Will validate the offset at start fetching again
195
+ /* Will validate the offset and start fetching again
196
196
  * from offset 0. */
197
197
  rd_kafka_topic_partition_set_leader_epoch(rktpar, 0);
198
198
  rd_kafka_seek_partitions(c1, rktpars, -1);
199
199
  rd_kafka_topic_partition_list_destroy(rktpars);
200
200
 
201
201
  /* Read all messages after seek to zero.
202
- * In case of permanent error instead it reset to latest and
202
+ * In case of permanent error, instead, it resets to latest and
203
203
  * gets an EOF. */
204
204
  test_consumer_poll("MSG_ALL", c1, testid, 0, 0, 5, NULL);
205
205
 
@@ -424,6 +424,505 @@ static void do_test_store_offset_without_leader_epoch(void) {
424
424
  SUB_TEST_PASS();
425
425
  }
426
426
 
427
+ static rd_bool_t is_broker_fetch_request(rd_kafka_mock_request_t *request,
428
+ void *opaque) {
429
+ return rd_kafka_mock_request_id(request) == *(int *)(opaque) &&
430
+ rd_kafka_mock_request_api_key(request) == RD_KAFKAP_Fetch;
431
+ }
432
+
433
+ static rd_bool_t
434
+ is_offset_for_leader_epoch_request(rd_kafka_mock_request_t *request,
435
+ void *opaque) {
436
+ return rd_kafka_mock_request_id(request) == *(int *)(opaque) &&
437
+ rd_kafka_mock_request_api_key(request) ==
438
+ RD_KAFKAP_OffsetForLeaderEpoch;
439
+ }
440
+
441
+ static rd_bool_t is_metadata_request(rd_kafka_mock_request_t *request,
442
+ void *opaque) {
443
+ return rd_kafka_mock_request_api_key(request) == RD_KAFKAP_Metadata;
444
+ }
445
+
446
+ /**
447
+ * @brief A second leader change is triggered after first one switches
448
+ * to a leader supporting KIP-320, the second leader either:
449
+ *
450
+ * - variation 0: doesn't support KIP-320 (leader epoch -1).
451
+ * This can happed during a cluster roll for upgrading the cluster.
452
+ * See #4796.
453
+ * - variation 1: the leader epoch is the same as previous leader.
454
+ * This can happen when the broker doesn't need that a validation
455
+ * should be performed after a leader change.
456
+ *
457
+ * In both cases no validation should be performed
458
+ * and it should continue fetching messages on the new leader.
459
+ */
460
+ static void do_test_leader_change_no_validation(int variation) {
461
+ const char *topic = test_mk_topic_name(__FUNCTION__, 1);
462
+ const char *c1_groupid = topic;
463
+ rd_kafka_t *c1;
464
+ const char *bootstraps;
465
+ rd_kafka_mock_cluster_t *mcluster;
466
+ int msg_cnt = 5;
467
+ uint64_t testid = test_id_generate();
468
+ rd_kafka_conf_t *conf;
469
+ int i, leader = 1;
470
+ size_t matching_requests;
471
+ /* No KIP-320 support on second leader change */
472
+ int32_t leader_epoch = -1;
473
+ if (variation == 1) {
474
+ /* Same leader epoch on second leader change */
475
+ leader_epoch = 2;
476
+ }
477
+
478
+ SUB_TEST_QUICK("variation: %d", variation);
479
+
480
+ mcluster = test_mock_cluster_new(2, &bootstraps);
481
+ rd_kafka_mock_topic_create(mcluster, topic, 1, 2);
482
+ rd_kafka_mock_partition_set_leader(mcluster, topic, 0, 1);
483
+
484
+ /* Seed the topic with messages */
485
+ test_produce_msgs_easy_v(topic, testid, 0, 0, msg_cnt, 10,
486
+ "bootstrap.servers", bootstraps,
487
+ "batch.num.messages", "1", NULL);
488
+
489
+ test_conf_init(&conf, NULL, 60);
490
+ test_conf_set(conf, "bootstrap.servers", bootstraps);
491
+ test_conf_set(conf, "auto.offset.reset", "earliest");
492
+ test_conf_set(conf, "enable.auto.commit", "false");
493
+
494
+ c1 = test_create_consumer(c1_groupid, NULL, conf, NULL);
495
+ test_consumer_subscribe(c1, topic);
496
+
497
+ rd_kafka_mock_start_request_tracking(mcluster);
498
+ TEST_SAY("Consume initial messages and join the group, etc.\n");
499
+ test_consumer_poll("MSG_INIT", c1, testid, 0, 0, msg_cnt, NULL);
500
+
501
+ TEST_SAY("Wait Fetch request to broker 1\n");
502
+ matching_requests = test_mock_wait_matching_requests(
503
+ mcluster, 1, 1000, is_broker_fetch_request, &leader);
504
+ TEST_ASSERT_LATER(matching_requests > 0,
505
+ "Expected at least one Fetch request to broker 1");
506
+
507
+ /* No validation is performed on first fetch. */
508
+ TEST_SAY("Wait no OffsetForLeaderEpoch request to broker 1\n");
509
+ matching_requests = test_mock_wait_matching_requests(
510
+ mcluster, 0, 1000, is_offset_for_leader_epoch_request, &leader);
511
+ TEST_ASSERT_LATER(matching_requests == 0,
512
+ "Expected no OffsetForLeaderEpoch request"
513
+ " to broker 1, got %" PRIusz,
514
+ matching_requests);
515
+ rd_kafka_mock_stop_request_tracking(mcluster);
516
+
517
+ /* The leader will change from 1->2, and the OffsetForLeaderEpoch will
518
+ * be sent to broker 2. Leader epoch becomes 1. */
519
+ rd_kafka_mock_start_request_tracking(mcluster);
520
+ TEST_SAY("Changing leader to broker 2\n");
521
+ rd_kafka_mock_partition_set_leader(mcluster, topic, 0, 2);
522
+ leader = 2;
523
+ rd_kafka_poll(c1, 1000);
524
+
525
+ TEST_SAY("Wait Fetch request to broker 2\n");
526
+ matching_requests = test_mock_wait_matching_requests(
527
+ mcluster, 1, 1000, is_broker_fetch_request, &leader);
528
+ TEST_ASSERT_LATER(matching_requests > 0,
529
+ "Expected at least one fetch request to broker 2");
530
+
531
+ TEST_SAY("Wait OffsetForLeaderEpoch request to broker 2\n");
532
+ matching_requests = test_mock_wait_matching_requests(
533
+ mcluster, 1, 1000, is_offset_for_leader_epoch_request, &leader);
534
+ TEST_ASSERT_LATER(matching_requests == 1,
535
+ "Expected one OffsetForLeaderEpoch request"
536
+ " to broker 2, got %" PRIusz,
537
+ matching_requests);
538
+ rd_kafka_mock_stop_request_tracking(mcluster);
539
+
540
+ /* Reset leader, set leader epoch to `leader_epoch`
541
+ * to trigger this special case. */
542
+ TEST_SAY("Changing leader to broker 1\n");
543
+ for (i = 0; i < 5; i++) {
544
+ rd_kafka_mock_partition_push_leader_response(mcluster, topic, 0,
545
+ 1, leader_epoch);
546
+ }
547
+ rd_kafka_mock_partition_set_leader(mcluster, topic, 0, 1);
548
+ leader = 1;
549
+ rd_kafka_mock_start_request_tracking(mcluster);
550
+ rd_kafka_poll(c1, 1000);
551
+
552
+ TEST_SAY("Wait Fetch request to broker 1\n");
553
+ /* 0 is correct here as second parameter as we don't wait to receive
554
+ * at least one Fetch request, given in the failure case it'll take more
555
+ * than 1s and it's possible a OffsetForLeaderEpoch is received after
556
+ * that, because we ran out of overridden leader responses. */
557
+ matching_requests = test_mock_wait_matching_requests(
558
+ mcluster, 0, 1000, is_broker_fetch_request, &leader);
559
+ TEST_ASSERT_LATER(matching_requests > 0,
560
+ "Expected at least one fetch request to broker 1");
561
+
562
+ /* Given same leader epoch, or -1, is returned,
563
+ * no validation is performed */
564
+ TEST_SAY("Wait no OffsetForLeaderEpoch request to broker 1\n");
565
+ matching_requests = test_mock_wait_matching_requests(
566
+ mcluster, 0, 1000, is_offset_for_leader_epoch_request, &leader);
567
+ TEST_ASSERT_LATER(matching_requests == 0,
568
+ "Expected no OffsetForLeaderEpoch request"
569
+ " to broker 1, got %" PRIusz,
570
+ matching_requests);
571
+ rd_kafka_mock_stop_request_tracking(mcluster);
572
+
573
+ rd_kafka_destroy(c1);
574
+ test_mock_cluster_destroy(mcluster);
575
+
576
+ TEST_LATER_CHECK();
577
+ SUB_TEST_PASS();
578
+ }
579
+
580
+ static int
581
+ is_fatal_cb(rd_kafka_t *rk, rd_kafka_resp_err_t err, const char *reason) {
582
+ /* Ignore UNKNOWN_TOPIC_OR_PART errors. */
583
+ TEST_SAY("is_fatal?: %s: %s\n", rd_kafka_err2str(err), reason);
584
+ if (err == RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION ||
585
+ err == RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART)
586
+ return 0;
587
+ return 1;
588
+ }
589
+
590
+ /**
591
+ * @brief Test partition validation when it's temporarily delegated to
592
+ * the internal broker. There are two variations:
593
+ *
594
+ * variation 1: leader epoch bump is simultaneous to the partition
595
+ * delegation returning from the internal broker to the
596
+ * new leader.
597
+ * variation 2: leader epoch bump is triggered immediately by KIP-951
598
+ * and validation fails, later metadata request fails
599
+ * and partition is delegated to the internal broker.
600
+ * When partition is delegated back to the leader,
601
+ * it finds the same leader epoch but validation must
602
+ * be completed as state is still VALIDATE_EPOCH_WAIT.
603
+ *
604
+ * In both cases, fetch must continue with the new leader and
605
+ * after the validation is completed.
606
+ *
607
+ * See #4804.
608
+ */
609
+ static void do_test_leader_change_from_internal_broker(int variation) {
610
+ const char *topic = test_mk_topic_name(__FUNCTION__, 1);
611
+ const char *c1_groupid = topic;
612
+ rd_kafka_t *c1;
613
+ const char *bootstraps;
614
+ rd_kafka_mock_cluster_t *mcluster;
615
+ int msg_cnt = 5;
616
+ uint64_t testid = test_id_generate();
617
+ rd_kafka_conf_t *conf;
618
+ int leader = 1;
619
+ size_t matching_requests, expected_offset_for_leader_epoch_requests = 1;
620
+
621
+ SUB_TEST_QUICK("variation: %d", variation);
622
+
623
+ mcluster = test_mock_cluster_new(2, &bootstraps);
624
+ rd_kafka_mock_topic_create(mcluster, topic, 1, 2);
625
+ rd_kafka_mock_partition_set_leader(mcluster, topic, 0, 1);
626
+
627
+ /* Seed the topic with messages */
628
+ test_produce_msgs_easy_v(topic, testid, 0, 0, msg_cnt, 10,
629
+ "bootstrap.servers", bootstraps,
630
+ "batch.num.messages", "1", NULL);
631
+
632
+ test_conf_init(&conf, NULL, 60);
633
+ test_conf_set(conf, "bootstrap.servers", bootstraps);
634
+ test_conf_set(conf, "auto.offset.reset", "earliest");
635
+ test_conf_set(conf, "enable.auto.commit", "false");
636
+
637
+ c1 = test_create_consumer(c1_groupid, NULL, conf, NULL);
638
+ test_consumer_subscribe(c1, topic);
639
+ test_curr->is_fatal_cb = is_fatal_cb;
640
+
641
+ rd_kafka_mock_start_request_tracking(mcluster);
642
+ TEST_SAY("Consume initial messages and join the group, etc.\n");
643
+ test_consumer_poll("MSG_INIT", c1, testid, 0, 0, msg_cnt, NULL);
644
+
645
+ TEST_SAY("Wait Fetch request to broker 1\n");
646
+ matching_requests = test_mock_wait_matching_requests(
647
+ mcluster, 1, 1000, is_broker_fetch_request, &leader);
648
+ TEST_ASSERT_LATER(matching_requests > 0,
649
+ "Expected at least one Fetch request to broker 1");
650
+
651
+ /* No validation is performed on first fetch. */
652
+ TEST_SAY("Wait no OffsetForLeaderEpoch request to broker 1\n");
653
+ matching_requests = test_mock_wait_matching_requests(
654
+ mcluster, 0, 1000, is_offset_for_leader_epoch_request, &leader);
655
+ TEST_ASSERT_LATER(matching_requests == 0,
656
+ "Expected no OffsetForLeaderEpoch request"
657
+ " to broker 1, got %" PRIusz,
658
+ matching_requests);
659
+ rd_kafka_mock_stop_request_tracking(mcluster);
660
+
661
+ /* The leader will change from 1->2, and the OffsetForLeaderEpoch will
662
+ * be sent to broker 2. Leader epoch becomes 1. */
663
+ rd_kafka_mock_start_request_tracking(mcluster);
664
+ TEST_SAY("Changing leader to broker 2\n");
665
+ rd_kafka_mock_partition_set_leader(mcluster, topic, 0, 2);
666
+ leader = 2;
667
+ rd_kafka_poll(c1, 1000);
668
+
669
+ TEST_SAY("Wait Fetch request to broker 2\n");
670
+ matching_requests = test_mock_wait_matching_requests(
671
+ mcluster, 1, 1000, is_broker_fetch_request, &leader);
672
+ TEST_ASSERT_LATER(matching_requests > 0,
673
+ "Expected at least one fetch request to broker 2");
674
+
675
+ TEST_SAY("Wait OffsetForLeaderEpoch request to broker 2\n");
676
+ matching_requests = test_mock_wait_matching_requests(
677
+ mcluster, 1, 1000, is_offset_for_leader_epoch_request, &leader);
678
+ TEST_ASSERT_LATER(matching_requests == 1,
679
+ "Expected one OffsetForLeaderEpoch request"
680
+ " to broker 2, got %" PRIusz,
681
+ matching_requests);
682
+ rd_kafka_mock_stop_request_tracking(mcluster);
683
+
684
+ /* Reset leader, Metadata request fails in between and delegates
685
+ * the partition to the internal broker. */
686
+ TEST_SAY("Changing leader to broker 1\n");
687
+ if (variation == 0) {
688
+ /* Fail Fetch request too, otherwise KIP-951 mechanism is faster
689
+ * than the Metadata request. */
690
+ rd_kafka_mock_push_request_errors(
691
+ mcluster, RD_KAFKAP_Fetch, 1,
692
+ RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART);
693
+ } else if (variation == 1) {
694
+ /* First OffsetForLeaderEpoch is triggered by KIP-951,
695
+ * it updates leader epoch, then it fails, triggers metadata
696
+ * refresh,
697
+ * Metadata fails too and partition is delegated to the internal
698
+ * broker.
699
+ * Validation is retried three times during this period
700
+ * and it should fail because we want to see what happens
701
+ * next when partition isn't delegated to the internal
702
+ * broker anymore. */
703
+ rd_kafka_mock_push_request_errors(
704
+ mcluster, RD_KAFKAP_OffsetForLeaderEpoch, 3,
705
+ RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART,
706
+ RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART,
707
+ RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART);
708
+ }
709
+
710
+ /* This causes a Metadata request error. */
711
+ rd_kafka_mock_topic_set_error(mcluster, topic,
712
+ RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART);
713
+ rd_kafka_mock_partition_set_leader(mcluster, topic, 0, 1);
714
+ leader = 1;
715
+ rd_kafka_mock_start_request_tracking(mcluster);
716
+ rd_kafka_poll(c1, 1000);
717
+
718
+ TEST_SAY(
719
+ "Wait a Metadata request that fails and delegates partition to"
720
+ " the internal broker.\n");
721
+ matching_requests = test_mock_wait_matching_requests(
722
+ mcluster, 1, 1000, is_metadata_request, NULL);
723
+ TEST_ASSERT_LATER(matching_requests > 0,
724
+ "Expected at least one Metadata request");
725
+ TEST_SAY(
726
+ "Reset partition error status."
727
+ " Partition is delegated to broker 1.\n");
728
+ rd_kafka_mock_topic_set_error(mcluster, topic,
729
+ RD_KAFKA_RESP_ERR_NO_ERROR);
730
+
731
+ TEST_SAY("Wait Fetch request to broker 1\n");
732
+ matching_requests = test_mock_wait_matching_requests(
733
+ mcluster, 1, 2000, is_broker_fetch_request, &leader);
734
+ TEST_ASSERT_LATER(matching_requests > 0,
735
+ "Expected at least one fetch request to broker 1");
736
+
737
+ TEST_SAY("Wait OffsetForLeaderEpoch request to broker 1\n");
738
+ if (variation == 1) {
739
+ /* There's three OffsetForLeaderEpoch requests more in
740
+ * variation 1. See previous comment. */
741
+ expected_offset_for_leader_epoch_requests += 3;
742
+ }
743
+ matching_requests = test_mock_wait_matching_requests(
744
+ mcluster, 1, 1000, is_offset_for_leader_epoch_request, &leader);
745
+ TEST_ASSERT_LATER(
746
+ matching_requests == expected_offset_for_leader_epoch_requests,
747
+ "Expected %" PRIusz
748
+ " OffsetForLeaderEpoch request"
749
+ " to broker 1, got %" PRIusz,
750
+ expected_offset_for_leader_epoch_requests, matching_requests);
751
+ rd_kafka_mock_stop_request_tracking(mcluster);
752
+
753
+ rd_kafka_destroy(c1);
754
+ test_mock_cluster_destroy(mcluster);
755
+
756
+ TEST_LATER_CHECK();
757
+ SUB_TEST_PASS();
758
+ test_curr->is_fatal_cb = NULL;
759
+ }
760
+
761
+ /**
762
+ * @brief Opaque for do_test_list_offsets_leader_change.
763
+ */
764
+ typedef struct do_test_list_offsets_leader_change_s {
765
+ rd_kafka_mock_cluster_t *mcluster;
766
+ const char *topic;
767
+ int msg_cnt;
768
+ int variation;
769
+ } do_test_list_offsets_leader_change_t;
770
+
771
+ /**
772
+ * @brief Rebalance callback for do_test_list_offsets_leader_change.
773
+ */
774
+ static void do_test_list_offsets_leader_change_rebalance_cb(
775
+ rd_kafka_t *rk,
776
+ rd_kafka_resp_err_t err,
777
+ rd_kafka_topic_partition_list_t *partitions,
778
+ void *opaque) {
779
+ TEST_SAY("Rebalance callback: %s with %d partition(s)\n",
780
+ rd_kafka_err2str(err), partitions->cnt);
781
+ do_test_list_offsets_leader_change_t *test = opaque;
782
+ switch (err) {
783
+ case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS: {
784
+ int retries = 0;
785
+ int64_t low, high;
786
+ rd_kafka_resp_err_t list_offsets_err =
787
+ RD_KAFKA_RESP_ERR_NO_ERROR;
788
+
789
+ TEST_ASSERT(partitions->cnt == 1,
790
+ "Expected 1 assigned partition, got %d",
791
+ partitions->cnt);
792
+
793
+ /* Change leader to 2 */
794
+ rd_kafka_mock_partition_set_leader(test->mcluster, test->topic,
795
+ 0, 2);
796
+
797
+ do {
798
+ /* Set a wrong leader epoch that should not be used
799
+ * for listing offsets. */
800
+ rd_kafka_topic_partition_set_leader_epoch(
801
+ &partitions->elems[0], 1234);
802
+
803
+ if (test->variation == 0) {
804
+ partitions->elems[0].offset = 1;
805
+ list_offsets_err = rd_kafka_offsets_for_times(
806
+ rk, partitions, 1000);
807
+ } else {
808
+ list_offsets_err =
809
+ rd_kafka_query_watermark_offsets(
810
+ rk, partitions->elems[0].topic,
811
+ partitions->elems[0].partition, &low,
812
+ &high, 1000);
813
+ }
814
+ retries++;
815
+ if (retries == 1) {
816
+ TEST_ASSERT(
817
+ list_offsets_err ==
818
+ RD_KAFKA_RESP_ERR_NOT_LEADER_FOR_PARTITION,
819
+ "Expected NOT_LEADER_FOR_PARTITION, got %s",
820
+ rd_kafka_err2str(list_offsets_err));
821
+ }
822
+ if (retries > 2)
823
+ TEST_FAIL(
824
+ "Offsets for times failed %d times "
825
+ " during the rebalance callback",
826
+ retries);
827
+ } while (list_offsets_err != RD_KAFKA_RESP_ERR_NO_ERROR);
828
+
829
+ TEST_ASSERT(retries == 2,
830
+ "There must be exactly 2 retries, "
831
+ "got %d",
832
+ retries);
833
+
834
+
835
+ if (test->variation == 0) {
836
+ /* Mock handler currently returns
837
+ * RD_KAFKA_OFFSET_SPEC_LATEST
838
+ * in the offsets for times case */
839
+ TEST_ASSERT(partitions->elems[0].offset ==
840
+ RD_KAFKA_OFFSET_SPEC_LATEST,
841
+ "Expected offset for times LATEST,"
842
+ " got %" PRId64,
843
+ partitions->elems[0].offset);
844
+ } else {
845
+ TEST_ASSERT(0 == low,
846
+ "Expected low offset 0"
847
+ ", got %" PRId64,
848
+ low);
849
+ TEST_ASSERT(10 == high,
850
+ "Expected high offset 10"
851
+ ", got %" PRId64,
852
+ high);
853
+ partitions->elems[0].offset = high;
854
+ }
855
+
856
+ test_consumer_assign_by_rebalance_protocol("rebalance", rk,
857
+ partitions);
858
+
859
+ break;
860
+ }
861
+ case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
862
+ test_consumer_unassign_by_rebalance_protocol("rebalance", rk,
863
+ partitions);
864
+ break;
865
+ default:
866
+ break;
867
+ }
868
+ }
869
+
870
+ /**
871
+ * @brief Test that listing offsets during a leader change works as expected.
872
+ * by returning a NOT_LEADER_FOR_PARTITION error and clearing the cache.
873
+ *
874
+ * There are two variations:
875
+ * - variation 0: uses rd_kafka_offsets_for_times
876
+ * - variation 1: uses rd_kafka_query_watermark_offsets
877
+ */
878
+ static void do_test_list_offsets_leader_change(int variation) {
879
+ const char *topic = test_mk_topic_name(__FUNCTION__, 1);
880
+ const char *c1_groupid = topic;
881
+ rd_kafka_t *c1;
882
+ const char *bootstraps;
883
+ rd_kafka_mock_cluster_t *mcluster;
884
+ int msg_cnt = 10;
885
+ uint64_t testid = test_id_generate();
886
+ rd_kafka_conf_t *conf;
887
+ do_test_list_offsets_leader_change_t opaque;
888
+
889
+ SUB_TEST_QUICK("%s", variation == 0 ? "offsets_for_times"
890
+ : "query_watermark_offsets");
891
+
892
+ mcluster = test_mock_cluster_new(2, &bootstraps);
893
+ rd_kafka_mock_topic_create(mcluster, topic, 1, 2);
894
+ rd_kafka_mock_partition_set_leader(mcluster, topic, 0, 1);
895
+
896
+ /* Seed the topic with messages */
897
+ test_produce_msgs_easy_v(topic, testid, 0, 0, msg_cnt, 10,
898
+ "bootstrap.servers", bootstraps, NULL);
899
+
900
+ test_conf_init(&conf, NULL, 60);
901
+ test_conf_set(conf, "bootstrap.servers", bootstraps);
902
+ test_conf_set(conf, "auto.offset.reset", "earliest");
903
+ rd_kafka_conf_set_rebalance_cb(
904
+ conf, do_test_list_offsets_leader_change_rebalance_cb);
905
+ opaque.mcluster = mcluster;
906
+ opaque.topic = topic;
907
+ opaque.msg_cnt = msg_cnt;
908
+ opaque.variation = variation;
909
+ rd_kafka_conf_set_opaque(conf, &opaque);
910
+
911
+ c1 = test_create_consumer(c1_groupid, NULL, conf, NULL);
912
+ test_consumer_subscribe(c1, topic);
913
+
914
+ /* Consumes no messages if assignment starts from
915
+ * latest as set in the rebalance callback,
916
+ * otherwise it's configured as earliest. */
917
+ test_consumer_poll_no_msgs("MSG_INIT", c1, testid, 5000);
918
+
919
+ rd_kafka_destroy(c1);
920
+
921
+ test_mock_cluster_destroy(mcluster);
922
+
923
+ TEST_LATER_CHECK();
924
+ SUB_TEST_PASS();
925
+ }
427
926
 
428
927
  int main_0139_offset_validation_mock(int argc, char **argv) {
429
928
 
@@ -438,5 +937,14 @@ int main_0139_offset_validation_mock(int argc, char **argv) {
438
937
 
439
938
  do_test_store_offset_without_leader_epoch();
440
939
 
940
+ do_test_leader_change_no_validation(0);
941
+ do_test_leader_change_no_validation(1);
942
+
943
+ do_test_leader_change_from_internal_broker(0);
944
+ do_test_leader_change_from_internal_broker(1);
945
+
946
+ do_test_list_offsets_leader_change(0);
947
+ do_test_list_offsets_leader_change(1);
948
+
441
949
  return 0;
442
950
  }
@@ -54,7 +54,7 @@ static void test_commit_metadata() {
54
54
  delete conf;
55
55
 
56
56
  Test::Say("Create topic.\n");
57
- Test::create_topic(consumer, topic.c_str(), 1, 1);
57
+ Test::create_topic_wait_exists(consumer, topic.c_str(), 1, 1, 5000);
58
58
 
59
59
  Test::Say("Commit offsets.\n");
60
60
  std::vector<RdKafka::TopicPartition *> offsets;
@@ -83,6 +83,7 @@ void do_test_producer(int64_t reauth_time, const char *topic) {
83
83
 
84
84
  rk = test_create_handle(RD_KAFKA_PRODUCER, conf);
85
85
  rkt = test_create_producer_topic(rk, topic, NULL);
86
+ test_wait_topic_exists(rk, topic, 5000);
86
87
 
87
88
  /* Create the topic to make sure connections are up and ready. */
88
89
  err = test_auto_create_topic_rkt(rk, rkt, tmout_multip(5000));
@@ -129,7 +130,7 @@ void do_test_consumer(int64_t reauth_time, const char *topic) {
129
130
 
130
131
  p1 = test_create_handle(RD_KAFKA_PRODUCER, rd_kafka_conf_dup(conf));
131
132
 
132
- test_create_topic(p1, topic, 1, 3);
133
+ test_create_topic_wait_exists(p1, topic, 1, 3, 5000);
133
134
  TEST_SAY("Topic: %s is created\n", topic);
134
135
 
135
136
  test_conf_set(conf, "auto.offset.reset", "earliest");
@@ -207,6 +208,7 @@ void do_test_txn_producer(int64_t reauth_time,
207
208
 
208
209
  rk = test_create_handle(RD_KAFKA_PRODUCER, conf);
209
210
  rkt = test_create_producer_topic(rk, topic, NULL);
211
+ test_wait_topic_exists(rk, topic, 5000);
210
212
 
211
213
  err = test_auto_create_topic_rkt(rk, rkt, tmout_multip(5000));
212
214
  TEST_ASSERT(!err, "topic creation failed: %s", rd_kafka_err2str(err));
@@ -268,7 +270,7 @@ void do_test_oauthbearer(int64_t reauth_time,
268
270
  rd_kafka_t *rk = NULL;
269
271
  uint64_t testid = test_id_generate();
270
272
  rd_kafka_resp_err_t err;
271
- char *mechanism;
273
+ char *mechanism, *oauthbearer_method;
272
274
  int msgrate, msgcnt, sent_msg;
273
275
  test_timing_t t_produce;
274
276
  int token_lifetime_s = token_lifetime_ms / 1000;
@@ -290,11 +292,16 @@ void do_test_oauthbearer(int64_t reauth_time,
290
292
  mechanism);
291
293
  }
292
294
 
293
- test_conf_set(
294
- conf, "sasl.oauthbearer.config",
295
- tsprintf("principal=admin scope=requiredScope lifeSeconds=%d",
296
- token_lifetime_s));
297
- test_conf_set(conf, "enable.sasl.oauthbearer.unsecure.jwt", "true");
295
+ oauthbearer_method = test_conf_get(conf, "sasl.oauthbearer.method");
296
+ if (rd_strcasecmp(oauthbearer_method, "oidc")) {
297
+ test_conf_set(
298
+ conf, "sasl.oauthbearer.config",
299
+ tsprintf(
300
+ "principal=admin scope=requiredScope lifeSeconds=%d",
301
+ token_lifetime_s));
302
+ test_conf_set(conf, "enable.sasl.oauthbearer.unsecure.jwt",
303
+ "true");
304
+ }
298
305
  rk = test_create_handle(RD_KAFKA_PRODUCER, conf);
299
306
 
300
307
  /* Enable to background queue since we don't want to poll the SASL
@@ -303,6 +310,7 @@ void do_test_oauthbearer(int64_t reauth_time,
303
310
  rd_kafka_sasl_background_callbacks_enable(rk);
304
311
 
305
312
  rkt = test_create_producer_topic(rk, topic, NULL);
313
+ test_wait_topic_exists(rk, topic, 5000);
306
314
 
307
315
  /* Create the topic to make sure connections are up and ready. */
308
316
  err = test_auto_create_topic_rkt(rk, rkt, tmout_multip(5000));
@@ -372,6 +380,7 @@ void do_test_reauth_failure(int64_t reauth_time, const char *topic) {
372
380
 
373
381
  rk = test_create_handle(RD_KAFKA_PRODUCER, conf);
374
382
  rkt = test_create_producer_topic(rk, topic, NULL);
383
+ test_wait_topic_exists(rk, topic, 5000);
375
384
 
376
385
  /* Create the topic to make sure connections are up and ready. */
377
386
  err = test_auto_create_topic_rkt(rk, rkt, tmout_multip(5000));
@@ -403,7 +412,9 @@ int main_0142_reauthentication(int argc, char **argv) {
403
412
  size_t broker_id_cnt;
404
413
  int32_t *broker_ids = NULL;
405
414
  rd_kafka_conf_t *conf = NULL;
406
- const char *security_protocol, *sasl_mechanism;
415
+ const char *security_protocol;
416
+ rd_bool_t sasl_mechanism_oauthbearer = rd_false;
417
+ rd_bool_t oauthbearer_method_default = rd_false;
407
418
 
408
419
  size_t i;
409
420
  int64_t reauth_time = INT64_MAX;
@@ -419,8 +430,11 @@ int main_0142_reauthentication(int argc, char **argv) {
419
430
  return 0;
420
431
  }
421
432
 
422
- sasl_mechanism = test_conf_get(NULL, "sasl.mechanism");
423
- if (!rd_strcasecmp(sasl_mechanism, "oauthbearer"))
433
+ sasl_mechanism_oauthbearer = !rd_strcasecmp(
434
+ test_conf_get(NULL, "sasl.mechanism"), "oauthbearer");
435
+ oauthbearer_method_default = !rd_strcasecmp(
436
+ test_conf_get(NULL, "sasl.oauthbearer.method"), "default");
437
+ if (sasl_mechanism_oauthbearer && oauthbearer_method_default)
424
438
  test_conf_set(conf, "enable.sasl.oauthbearer.unsecure.jwt",
425
439
  "true");
426
440
 
@@ -481,13 +495,19 @@ int main_0142_reauthentication(int argc, char **argv) {
481
495
  * reauth time. */
482
496
  do_test_oauthbearer(reauth_time, topic, reauth_time / 2, rd_true);
483
497
  do_test_oauthbearer(reauth_time, topic, reauth_time / 2, rd_false);
484
- /* Case when the token_lifetime is greater than the maximum reauth time
485
- * configured.
486
- * In this case, the broker returns the maximum reauth time configured.
487
- * We don't need to recreate the token, but we need to reauthenticate
488
- * using the same token. */
489
- do_test_oauthbearer(reauth_time, topic, reauth_time * 2, rd_true);
490
- do_test_oauthbearer(reauth_time, topic, reauth_time * 2, rd_false);
498
+
499
+ /* With OIDC the expiration time is fixed so do the testing only
500
+ * once. */
501
+ if (oauthbearer_method_default) {
502
+ /* Case when the token_lifetime is greater than the maximum
503
+ * reauth time configured. In this case, the broker returns the
504
+ * maximum reauth time configured. We don't need to recreate the
505
+ * token, but we need to reauthenticate using the same token. */
506
+ do_test_oauthbearer(reauth_time, topic, reauth_time * 2,
507
+ rd_true);
508
+ do_test_oauthbearer(reauth_time, topic, reauth_time * 2,
509
+ rd_false);
510
+ }
491
511
 
492
512
  do_test_reauth_failure(reauth_time, topic);
493
513