@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
@@ -86,7 +86,7 @@ static void do_test_producer(bool topic_known) {
86
86
 
87
87
  /* Create topic */
88
88
  std::string topic_unauth = Test::mk_topic_name("0115-unauthorized", 1);
89
- Test::create_topic(NULL, topic_unauth.c_str(), 3, 1);
89
+ Test::create_topic_wait_exists(NULL, topic_unauth.c_str(), 3, 1, 5000);
90
90
 
91
91
  int exp_dr_cnt = 0;
92
92
 
@@ -112,6 +112,9 @@ static void do_test_producer(bool topic_known) {
112
112
  "--topic '%s'",
113
113
  bootstraps.c_str(), topic_unauth.c_str());
114
114
 
115
+ /* Allow ACLs to propagate */
116
+ rd_sleep(1);
117
+
115
118
  /* Produce message to any partition. */
116
119
  Test::Say("Producing message 1 to any partition\n");
117
120
  err = p->produce(topic_unauth, RdKafka::Topic::PARTITION_UA,
@@ -2,6 +2,7 @@
2
2
  * librdkafka - Apache Kafka C library
3
3
  *
4
4
  * Copyright (c) 2020-2022, Magnus Edenhill
5
+ * 2025, Confluent Inc.
5
6
  * All rights reserved.
6
7
  *
7
8
  * Redistribution and use in source and binary forms, with or without
@@ -81,11 +82,10 @@ static void do_test_consumer_close(bool do_subscribe,
81
82
  bool do_unsubscribe,
82
83
  bool do_close,
83
84
  bool with_queue) {
84
- std::string testname = tostr()
85
- << "Test C++ KafkaConsumer close "
86
- << "subscribe=" << do_subscribe
87
- << ", unsubscribe=" << do_unsubscribe
88
- << ", close=" << do_close << ", queue=" << with_queue;
85
+ std::string testname =
86
+ tostr() << "Test C++ KafkaConsumer close " << "subscribe=" << do_subscribe
87
+ << ", unsubscribe=" << do_unsubscribe << ", close=" << do_close
88
+ << ", queue=" << with_queue;
89
89
  SUB_TEST("%s", testname.c_str());
90
90
 
91
91
  rd_kafka_mock_cluster_t *mcluster;
@@ -199,6 +199,8 @@ static void do_test_consumer_close(bool do_subscribe,
199
199
 
200
200
  extern "C" {
201
201
  int main_0116_kafkaconsumer_close(int argc, char **argv) {
202
+ TEST_SKIP_MOCK_CLUSTER(0);
203
+
202
204
  /* Parameters:
203
205
  * subscribe, unsubscribe, close, with_queue */
204
206
  for (int i = 0; i < 1 << 4; i++) {
@@ -2,6 +2,7 @@
2
2
  * librdkafka - Apache Kafka C library
3
3
  *
4
4
  * Copyright (c) 2020-2022, Magnus Edenhill
5
+ * 2025, Confluent Inc.
5
6
  * All rights reserved.
6
7
  *
7
8
  * Redistribution and use in source and binary forms, with or without
@@ -102,8 +103,10 @@ static void do_test_offset_commit_error_during_rebalance(void) {
102
103
  rd_kafka_t *c1, *c2;
103
104
  rd_kafka_mock_cluster_t *mcluster;
104
105
  const char *bootstraps;
105
- const char *topic = "test";
106
- const int msgcnt = 100;
106
+ const char *topic = "test";
107
+ const int msgcnt = 100;
108
+ const int exp_msg_cnt_intial = 1;
109
+ int exp_msg_cnt_final = msgcnt;
107
110
  rd_kafka_resp_err_t err;
108
111
 
109
112
  SUB_TEST();
@@ -136,8 +139,8 @@ static void do_test_offset_commit_error_during_rebalance(void) {
136
139
 
137
140
 
138
141
  /* Wait for assignment and one message */
139
- test_consumer_poll("C1.PRE", c1, 0, -1, -1, 1, NULL);
140
- test_consumer_poll("C2.PRE", c2, 0, -1, -1, 1, NULL);
142
+ test_consumer_poll("C1.PRE", c1, 0, -1, -1, exp_msg_cnt_intial, NULL);
143
+ test_consumer_poll("C2.PRE", c2, 0, -1, -1, exp_msg_cnt_intial, NULL);
141
144
 
142
145
  /* Trigger rebalance */
143
146
  test_consumer_close(c2);
@@ -161,8 +164,15 @@ static void do_test_offset_commit_error_during_rebalance(void) {
161
164
  "not %s",
162
165
  rd_kafka_err2name(err));
163
166
 
167
+ /* Since all the assignors in the `consumer` protocol are COOPERATIVE
168
+ * only the new partitions are assigned to the consumer. All the
169
+ * previously assigned partitions will start consuming from the last
170
+ * offset. */
171
+ if (!test_consumer_group_protocol_classic())
172
+ exp_msg_cnt_final = msgcnt - exp_msg_cnt_intial;
173
+
164
174
  /* Wait for new assignment and able to read all messages */
165
- test_consumer_poll("C1.PRE", c1, 0, -1, -1, msgcnt, NULL);
175
+ test_consumer_poll("C1.POST", c1, 0, -1, -1, exp_msg_cnt_final, NULL);
166
176
 
167
177
  rd_kafka_destroy(c1);
168
178
 
@@ -2,6 +2,7 @@
2
2
  * librdkafka - Apache Kafka C library
3
3
  *
4
4
  * Copyright (c) 2020-2022, Magnus Edenhill
5
+ * 2025, Confluent Inc.
5
6
  * All rights reserved.
6
7
  *
7
8
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +35,7 @@
34
35
 
35
36
  static rd_kafka_t *c1, *c2;
36
37
 
38
+ static int rebalances = 0;
37
39
 
38
40
  static void rebalance_cb(rd_kafka_t *rk,
39
41
  rd_kafka_resp_err_t err,
@@ -42,16 +44,18 @@ static void rebalance_cb(rd_kafka_t *rk,
42
44
 
43
45
  TEST_SAY("Rebalance for %s: %s: %d partition(s)\n", rd_kafka_name(rk),
44
46
  rd_kafka_err2name(err), parts->cnt);
45
-
47
+ rebalances++;
46
48
  if (err == RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS) {
47
- TEST_CALL_ERR__(rd_kafka_assign(rk, parts));
49
+ test_consumer_assign_by_rebalance_protocol("rebalance", rk,
50
+ parts);
48
51
 
49
52
  } else if (err == RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS) {
50
53
  rd_kafka_resp_err_t commit_err;
51
54
 
52
55
  TEST_CALL_ERR__(rd_kafka_position(rk, parts));
53
56
 
54
- TEST_CALL_ERR__(rd_kafka_assign(rk, NULL));
57
+ test_consumer_unassign_by_rebalance_protocol("rebalance", rk,
58
+ parts);
55
59
 
56
60
  if (rk == c1)
57
61
  return;
@@ -86,7 +90,11 @@ static void rebalance_cb(rd_kafka_t *rk,
86
90
  int main_0118_commit_rebalance(int argc, char **argv) {
87
91
  const char *topic = test_mk_topic_name(__FUNCTION__, 1);
88
92
  rd_kafka_conf_t *conf;
89
- const int msgcnt = 1000;
93
+ const int msgcnt = 1000;
94
+ const int exp_msg_cnt_pre = 10;
95
+ int exp_msg_cnt_post = msgcnt;
96
+ int exp_msg_cnt_c1_pre = exp_msg_cnt_pre;
97
+ int exp_msg_cnt_c2_pre = exp_msg_cnt_pre;
90
98
 
91
99
  test_conf_init(&conf, NULL, 60);
92
100
  test_conf_set(conf, "enable.auto.commit", "false");
@@ -103,17 +111,42 @@ int main_0118_commit_rebalance(int argc, char **argv) {
103
111
  test_consumer_subscribe(c1, topic);
104
112
  test_consumer_subscribe(c2, topic);
105
113
 
106
-
107
- test_consumer_poll("C1.PRE", c1, 0, -1, -1, 10, NULL);
108
- test_consumer_poll("C2.PRE", c2, 0, -1, -1, 10, NULL);
114
+ while (exp_msg_cnt_c1_pre > 0 || exp_msg_cnt_c2_pre > 0) {
115
+ if (exp_msg_cnt_c1_pre > 0 ||
116
+ exp_msg_cnt_c2_pre == exp_msg_cnt_pre) {
117
+ exp_msg_cnt_c1_pre -=
118
+ test_consumer_poll_once(c1, NULL, 100);
119
+ if (exp_msg_cnt_c2_pre == exp_msg_cnt_pre)
120
+ /* Slow down consumption until both have
121
+ * partitions assigned. */
122
+ rd_usleep(100 * 1000, 0);
123
+ }
124
+ if (exp_msg_cnt_c2_pre > 0 ||
125
+ exp_msg_cnt_c1_pre == exp_msg_cnt_pre) {
126
+ exp_msg_cnt_c2_pre -=
127
+ test_consumer_poll_once(c2, NULL, 100);
128
+ if (exp_msg_cnt_c1_pre == exp_msg_cnt_pre)
129
+ /* Slow down consumption until both have
130
+ * partitions assigned. */
131
+ rd_usleep(100 * 1000, 0);
132
+ }
133
+ }
109
134
 
110
135
  /* Trigger rebalance */
111
136
  test_consumer_close(c2);
112
137
  rd_kafka_destroy(c2);
113
138
 
139
+ /* Since all the assignors in the `consumer` protocol are COOPERATIVE
140
+ * only the new partitions are assigned to the consumer. All the
141
+ * previously assigned partitions will start consuming from the last
142
+ * offset. */
143
+ if (!test_consumer_group_protocol_classic())
144
+ exp_msg_cnt_post =
145
+ msgcnt - exp_msg_cnt_pre + exp_msg_cnt_c1_pre;
146
+
114
147
  /* Since no offsets were successfully committed the remaining consumer
115
148
  * should be able to receive all messages. */
116
- test_consumer_poll("C1.POST", c1, 0, -1, -1, msgcnt, NULL);
149
+ test_consumer_poll("C1.POST", c1, 0, -1, -1, exp_msg_cnt_post, NULL);
117
150
 
118
151
  rd_kafka_destroy(c1);
119
152
 
@@ -2,6 +2,7 @@
2
2
  * librdkafka - Apache Kafka C library
3
3
  *
4
4
  * Copyright (c) 2020-2022, Magnus Edenhill
5
+ * 2025, Confluent Inc.
5
6
  * All rights reserved.
6
7
  *
7
8
  * Redistribution and use in source and binary forms, with or without
@@ -61,7 +62,7 @@ static void do_test_fetch_unauth() {
61
62
 
62
63
  /* Create topic */
63
64
  const int partition_cnt = 3;
64
- Test::create_topic(NULL, topic.c_str(), partition_cnt, 1);
65
+ Test::create_topic_wait_exists(NULL, topic.c_str(), partition_cnt, 1, 5000);
65
66
 
66
67
  /* Produce messages */
67
68
  test_produce_msgs_easy(topic.c_str(), 0, RdKafka::Topic::PARTITION_UA, 1000);
@@ -85,6 +86,9 @@ static void do_test_fetch_unauth() {
85
86
  "--topic '%s'",
86
87
  bootstraps.c_str(), topic.c_str());
87
88
 
89
+ /* Allow ACLs to propagate */
90
+ rd_sleep(1);
91
+
88
92
  Test::subscribe(c, topic);
89
93
 
90
94
  int auth_err_cnt = 0;
@@ -128,8 +132,23 @@ static void do_test_fetch_unauth() {
128
132
  "Expected exactly %d auth errors, saw %d", partition_cnt,
129
133
  auth_err_cnt);
130
134
 
135
+ c->close();
131
136
  delete c;
132
137
 
138
+ test_kafka_cmd(
139
+ "kafka-acls.sh --bootstrap-server %s "
140
+ "--remove --force --allow-principal 'User:*' "
141
+ "--operation Describe --allow-host '*' "
142
+ "--topic '%s'",
143
+ bootstraps.c_str(), topic.c_str());
144
+
145
+ test_kafka_cmd(
146
+ "kafka-acls.sh --bootstrap-server %s "
147
+ "--remove --force --deny-principal 'User:*' "
148
+ "--operation Read --deny-host '*' "
149
+ "--topic '%s'",
150
+ bootstraps.c_str(), topic.c_str());
151
+
133
152
  Test::Say(tostr() << _C_GRN << "[ Test unauthorized Fetch PASS ]\n");
134
153
  }
135
154
 
@@ -169,10 +169,15 @@ int main_0120_asymmetric_subscription(int argc, char **argv) {
169
169
  rd_kafka_mock_topic_create(mcluster, "t3", _PART_CNT, 1);
170
170
  rd_kafka_mock_topic_create(mcluster, "t4", _PART_CNT, 1);
171
171
 
172
-
173
- do_test_asymmetric("roundrobin", bootstraps);
174
172
  do_test_asymmetric("range", bootstraps);
175
- do_test_asymmetric("cooperative-sticky", bootstraps);
173
+
174
+ /* These tests would be duplicate with KIP 848 protocol,
175
+ * given we're not testing the assignment here,
176
+ * as it's mocked. */
177
+ if (test_consumer_group_protocol_classic()) {
178
+ do_test_asymmetric("roundrobin", bootstraps);
179
+ do_test_asymmetric("cooperative-sticky", bootstraps);
180
+ }
176
181
 
177
182
  test_mock_cluster_destroy(mcluster);
178
183
 
@@ -48,7 +48,7 @@ void do_test_flush_overrides_linger_ms_time() {
48
48
  rd_kafka_conf_set_dr_msg_cb(conf, test_dr_msg_cb);
49
49
  rk = test_create_handle(RD_KAFKA_PRODUCER, conf);
50
50
 
51
- test_create_topic(rk, topic, 1, 1);
51
+ test_create_topic_wait_exists(rk, topic, 1, 1, 5000);
52
52
 
53
53
  /* Produce half set of messages without waiting for delivery. */
54
54
  test_produce_msgs2_nowait(rk, topic, 0, 0, 0, msgcnt / 2, NULL, 50,
@@ -2,6 +2,7 @@
2
2
  * librdkafka - Apache Kafka C library
3
3
  *
4
4
  * Copyright (c) 2021-2022, Magnus Edenhill
5
+ * 2025, Confluent Inc.
5
6
  * All rights reserved.
6
7
  *
7
8
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +32,11 @@
31
32
  * is built from within the librdkafka source tree and thus differs. */
32
33
  #include "rdkafka.h" /* for Kafka driver */
33
34
 
35
+ #define TEST_FIXTURES_FOLDER "./fixtures"
36
+ #define TEST_FIXTURES_OAUTHBEARER_FOLDER TEST_FIXTURES_FOLDER "/oauthbearer/"
37
+ #define TEST_FIXTURES_JWT_ASSERTION_TEMPLATE \
38
+ TEST_FIXTURES_OAUTHBEARER_FOLDER "jwt_assertion_template.json"
39
+
34
40
  static rd_bool_t error_seen;
35
41
  /**
36
42
  * @brief After config OIDC, make sure the producer and consumer
@@ -38,7 +44,8 @@ static rd_bool_t error_seen;
38
44
  *
39
45
  */
40
46
  static void
41
- do_test_produce_consumer_with_OIDC(const rd_kafka_conf_t *base_conf) {
47
+ do_test_produce_consumer_with_OIDC(const char *test_name,
48
+ const rd_kafka_conf_t *base_conf) {
42
49
  const char *topic;
43
50
  uint64_t testid;
44
51
  rd_kafka_t *p1;
@@ -47,7 +54,8 @@ do_test_produce_consumer_with_OIDC(const rd_kafka_conf_t *base_conf) {
47
54
 
48
55
  const char *url = test_getenv("VALID_OIDC_URL", NULL);
49
56
 
50
- SUB_TEST("Test producer and consumer with oidc configuration");
57
+ SUB_TEST("Test producer and consumer with oidc configuration: %s",
58
+ test_name);
51
59
 
52
60
  if (!url) {
53
61
  SUB_TEST_SKIP(
@@ -65,13 +73,13 @@ do_test_produce_consumer_with_OIDC(const rd_kafka_conf_t *base_conf) {
65
73
  p1 = test_create_handle(RD_KAFKA_PRODUCER, rd_kafka_conf_dup(conf));
66
74
 
67
75
  topic = test_mk_topic_name("0126-oauthbearer_oidc", 1);
68
- test_create_topic(p1, topic, 1, 3);
76
+ test_create_topic_wait_exists(p1, topic, 1, 3, 5000);
69
77
  TEST_SAY("Topic: %s is created\n", topic);
70
78
 
71
79
  test_produce_msgs2(p1, topic, testid, 0, 0, 1, NULL, 0);
72
80
 
73
81
  test_conf_set(conf, "auto.offset.reset", "earliest");
74
- c1 = test_create_consumer(topic, NULL, rd_kafka_conf_dup(conf), NULL);
82
+ c1 = test_create_consumer(topic, NULL, conf, NULL);
75
83
  test_consumer_subscribe(c1, topic);
76
84
 
77
85
  /* Give it some time to trigger the token refresh. */
@@ -142,11 +150,53 @@ static void do_test_produce_consumer_with_OIDC_expired_token_should_fail(
142
150
 
143
151
 
144
152
  /**
145
- * @brief After config OIDC, if the token is not valid, make sure the
153
+ * @brief After configiguring OIDC, make sure the
154
+ * authentication fails as expected.
155
+ */
156
+ static void do_test_produce_consumer_with_OIDC_should_fail(
157
+ const char *test_name,
158
+ const rd_kafka_conf_t *base_conf) {
159
+ rd_kafka_t *c1;
160
+ uint64_t testid;
161
+ rd_kafka_conf_t *conf;
162
+
163
+ const char *url = test_getenv("VALID_OIDC_URL", NULL);
164
+
165
+ SUB_TEST("Test authentication failure with oidc configuration: %s",
166
+ test_name);
167
+ if (!url) {
168
+ SUB_TEST_SKIP(
169
+ "VALID_OIDC_URL environment variable is not set\n");
170
+ return;
171
+ }
172
+
173
+ error_seen = rd_false;
174
+
175
+ conf = rd_kafka_conf_dup(base_conf);
176
+ test_conf_set(conf, "sasl.oauthbearer.token.endpoint.url", url);
177
+
178
+ rd_kafka_conf_set_error_cb(conf, auth_error_cb);
179
+
180
+ testid = test_id_generate();
181
+
182
+ c1 = test_create_consumer("OIDC.fail.C1", NULL, conf, NULL);
183
+
184
+ test_consumer_poll_no_msgs("OIDC.fail.C1", c1, testid, 5 * 1000);
185
+
186
+ TEST_ASSERT(error_seen);
187
+
188
+ test_consumer_close(c1);
189
+ rd_kafka_destroy(c1);
190
+ SUB_TEST_PASS();
191
+ }
192
+
193
+ /**
194
+ * @brief After config OIDC, if the token endpoint is not valid, make sure the
146
195
  * authentication fail as expected.
147
196
  *
148
197
  */
149
- static void do_test_produce_consumer_with_OIDC_should_fail(
198
+ static void
199
+ do_test_produce_consumer_with_OIDC_should_fail_invalid_token_endpoint(
150
200
  const rd_kafka_conf_t *base_conf) {
151
201
  rd_kafka_t *c1;
152
202
  uint64_t testid;
@@ -183,6 +233,266 @@ static void do_test_produce_consumer_with_OIDC_should_fail(
183
233
  SUB_TEST_PASS();
184
234
  }
185
235
 
236
+ typedef enum oidc_configuration_jwt_bearer_variation_t {
237
+ /** Use a private key file. */
238
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE,
239
+ /** Use an encrypted private key file. */
240
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE_ENCRYPTED,
241
+ /** Use a private key file
242
+ * set as a configuration property. */
243
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING,
244
+ /** Use an encrypted private key file
245
+ * set as a configuration property. */
246
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING_ENCRYPTED,
247
+ /** Use a private key file
248
+ * and a template for the JWT assertion. */
249
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_TEMPLATE_FILE,
250
+ /** Use a private key file and set the JOSE algorithm to ES256.
251
+ * This variation will fail as the private key is RSA in trivup */
252
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256,
253
+ /** Invalid scope */
254
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_INVALID_SCOPE,
255
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION__CNT
256
+ } oidc_configuration_jwt_bearer_variation_t;
257
+
258
+ #define OIDC_CONFIGURATION_JWT_BEARER_VARIATION__FIRST_FAILING \
259
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256
260
+
261
+ static const char *oidc_configuration_jwt_bearer_variation_name(
262
+ oidc_configuration_jwt_bearer_variation_t variation) {
263
+ rd_assert(
264
+ variation >=
265
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE &&
266
+ variation < OIDC_CONFIGURATION_JWT_BEARER_VARIATION__CNT);
267
+ static const char *names[] = {
268
+ "private key file", "private key encrypted file",
269
+ "private key pem string", "private key encrypted pem string",
270
+ "template file", "JOSE algorithm ES256",
271
+ "invalid scope"};
272
+ return names[variation];
273
+ }
274
+
275
+ static rd_kafka_conf_t *oidc_configuration_jwt_bearer(
276
+ rd_kafka_conf_t *conf,
277
+ oidc_configuration_jwt_bearer_variation_t variation) {
278
+ char file_content[4096];
279
+ const char *private_key_file =
280
+ test_getenv("OAUTHBEARER_CLIENT_PRIVATE_KEY", NULL);
281
+ const char *private_key_encrypted_file =
282
+ test_getenv("OAUTHBEARER_CLIENT_PRIVATE_KEY_ENCRYPTED", NULL);
283
+ const char *private_key_password =
284
+ test_getenv("OAUTHBEARER_CLIENT_PRIVATE_KEY_PASSWORD", NULL);
285
+
286
+ conf = rd_kafka_conf_dup(conf);
287
+ test_conf_set(conf, "sasl.oauthbearer.grant.type",
288
+ "urn:ietf:params:oauth:grant-type:jwt-bearer");
289
+ /* "sub" isn't mandatory if already defined in the template. */
290
+ if (variation != OIDC_CONFIGURATION_JWT_BEARER_VARIATION_TEMPLATE_FILE)
291
+ test_conf_set(conf, "sasl.oauthbearer.assertion.claim.sub",
292
+ "testuser");
293
+ else
294
+ test_conf_set(conf,
295
+ "sasl.oauthbearer.assertion.jwt.template.file",
296
+ TEST_FIXTURES_JWT_ASSERTION_TEMPLATE);
297
+
298
+ if (variation ==
299
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256)
300
+ test_conf_set(conf, "sasl.oauthbearer.assertion.algorithm",
301
+ "ES256");
302
+ if (variation == OIDC_CONFIGURATION_JWT_BEARER_VARIATION_INVALID_SCOPE)
303
+ test_conf_set(conf, "sasl.oauthbearer.scope", "invalid_scope");
304
+
305
+ switch (variation) {
306
+ case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE:
307
+ case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_TEMPLATE_FILE:
308
+ case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256:
309
+ case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_INVALID_SCOPE:
310
+ if (!private_key_file)
311
+ goto fail;
312
+
313
+ test_conf_set(conf,
314
+ "sasl.oauthbearer.assertion.private.key.file",
315
+ private_key_file);
316
+ break;
317
+ case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE_ENCRYPTED:
318
+ if (!private_key_encrypted_file || !private_key_password)
319
+ goto fail;
320
+ test_conf_set(conf,
321
+ "sasl.oauthbearer.assertion.private.key.file",
322
+ private_key_encrypted_file);
323
+ test_conf_set(
324
+ conf, "sasl.oauthbearer.assertion.private.key.passphrase",
325
+ private_key_password);
326
+ break;
327
+ case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING:
328
+ if (!private_key_file)
329
+ goto fail;
330
+ TEST_ASSERT(test_read_file(private_key_file, file_content,
331
+ sizeof(file_content)) > 0);
332
+
333
+ test_conf_set(conf,
334
+ "sasl.oauthbearer.assertion.private.key.pem",
335
+ file_content);
336
+ break;
337
+ case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING_ENCRYPTED:
338
+ if (!private_key_encrypted_file || !private_key_password)
339
+ goto fail;
340
+ TEST_ASSERT(test_read_file(private_key_file, file_content,
341
+ sizeof(file_content)) > 0);
342
+
343
+ test_conf_set(conf,
344
+ "sasl.oauthbearer.assertion.private.key.pem",
345
+ file_content);
346
+ test_conf_set(
347
+ conf, "sasl.oauthbearer.assertion.private.key.passphrase",
348
+ private_key_password);
349
+ break;
350
+ default:
351
+ rd_assert(!*"Unknown OIDC JWT bearer test variation");
352
+ }
353
+ return conf;
354
+ fail:
355
+ rd_kafka_conf_destroy(conf);
356
+ TEST_WARN("Skipping OIDC JWT bearer test variation: %s",
357
+ oidc_configuration_jwt_bearer_variation_name(variation));
358
+ return NULL;
359
+ }
360
+
361
+ void do_test_produce_consumer_with_OIDC_jwt_bearer(rd_kafka_conf_t *conf) {
362
+ rd_kafka_conf_t *jwt_bearer_conf;
363
+ oidc_configuration_jwt_bearer_variation_t variation;
364
+ for (variation =
365
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE;
366
+ variation < OIDC_CONFIGURATION_JWT_BEARER_VARIATION__CNT;
367
+ variation++) {
368
+ const char *test_name;
369
+ jwt_bearer_conf =
370
+ oidc_configuration_jwt_bearer(conf, variation);
371
+ if (!jwt_bearer_conf)
372
+ continue;
373
+
374
+ test_name = tsprintf(
375
+ "JWT bearer: %s\n",
376
+ oidc_configuration_jwt_bearer_variation_name(variation));
377
+
378
+ if (variation <
379
+ OIDC_CONFIGURATION_JWT_BEARER_VARIATION__FIRST_FAILING)
380
+ do_test_produce_consumer_with_OIDC(test_name,
381
+ jwt_bearer_conf);
382
+ else
383
+ do_test_produce_consumer_with_OIDC_should_fail(
384
+ test_name, jwt_bearer_conf);
385
+ rd_kafka_conf_destroy(jwt_bearer_conf);
386
+ }
387
+ }
388
+
389
+
390
+ typedef enum oidc_configuration_metadata_authentication_variation_t {
391
+ /** Azure IMDS. Successful case. */
392
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS,
393
+ /** Azure IMDS. Missing client ID. */
394
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_CLIENT_ID,
395
+ /** Azure IMDS. Missing resource parameter. */
396
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_RESOURCE,
397
+ /** Azure IMDS. Missing API version. */
398
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_API_VERSION,
399
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__CNT
400
+ } oidc_configuration_metadata_authentication_variation_t;
401
+
402
+ #define OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__FIRST_FAILING \
403
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_CLIENT_ID
404
+
405
+ static const char *oidc_configuration_metadata_authentication_variation_name(
406
+ oidc_configuration_metadata_authentication_variation_t variation) {
407
+ rd_assert(
408
+ variation >=
409
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS &&
410
+ variation <
411
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__CNT);
412
+ static const char *names[] = {
413
+ "Azure IMDS: success", "Azure IMDS: missing client ID",
414
+ "Azure IMDS: missing resource", "Azure IMDS: missing API version"};
415
+ return names[variation];
416
+ }
417
+
418
+ static rd_kafka_conf_t *oidc_configuration_metadata_authentication(
419
+ rd_kafka_conf_t *conf,
420
+ oidc_configuration_metadata_authentication_variation_t variation) {
421
+ conf = rd_kafka_conf_dup(conf);
422
+ switch (variation) {
423
+ case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS:
424
+ test_conf_set(conf,
425
+ "sasl.oauthbearer.metadata.authentication.type",
426
+ "azure_imds");
427
+ test_conf_set(conf, "sasl.oauthbearer.config",
428
+ "query=__metadata_authentication_type=azure_imds&"
429
+ "api-version=2025-04-07&resource="
430
+ "api://external_resource_id&client_id=client_id");
431
+ break;
432
+ case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_CLIENT_ID:
433
+ test_conf_set(conf,
434
+ "sasl.oauthbearer.metadata.authentication.type",
435
+ "azure_imds");
436
+ test_conf_set(conf, "sasl.oauthbearer.config",
437
+ "query=__metadata_authentication_type=azure_imds&"
438
+ "api-version=2025-04-07&resource="
439
+ "api://external_resource_id");
440
+ break;
441
+ case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_RESOURCE:
442
+ test_conf_set(conf,
443
+ "sasl.oauthbearer.metadata.authentication.type",
444
+ "azure_imds");
445
+ test_conf_set(conf, "sasl.oauthbearer.config",
446
+ "query=__metadata_authentication_type=azure_imds&"
447
+ "api-version=2025-04-07&"
448
+ "client_id=client_id");
449
+ break;
450
+ case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_API_VERSION:
451
+ test_conf_set(conf,
452
+ "sasl.oauthbearer.metadata.authentication.type",
453
+ "azure_imds");
454
+ test_conf_set(conf, "sasl.oauthbearer.config",
455
+ "query=__metadata_authentication_type=azure_imds&"
456
+ "resource="
457
+ "api://external_resource_id&client_id=client_id");
458
+ break;
459
+ default:
460
+ TEST_ASSERT(rd_false,
461
+ "Unknown OIDC metadata authentication type");
462
+ }
463
+ return conf;
464
+ }
465
+
466
+ /* Test metadata-based authentication cases against Trivup. */
467
+ void do_test_produce_consumer_with_OIDC_metadata_authentication(
468
+ rd_kafka_conf_t *conf) {
469
+ rd_kafka_conf_t *metadata_authentication_conf;
470
+ oidc_configuration_metadata_authentication_variation_t variation;
471
+ for (
472
+ variation =
473
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS;
474
+ variation <
475
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__CNT;
476
+ variation++) {
477
+ const char *test_name;
478
+ metadata_authentication_conf =
479
+ oidc_configuration_metadata_authentication(conf, variation);
480
+
481
+ test_name = tsprintf(
482
+ "Metadata authentication variation: %s\n",
483
+ oidc_configuration_metadata_authentication_variation_name(
484
+ variation));
485
+
486
+ if (variation <
487
+ OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__FIRST_FAILING)
488
+ do_test_produce_consumer_with_OIDC(
489
+ test_name, metadata_authentication_conf);
490
+ else
491
+ do_test_produce_consumer_with_OIDC_should_fail(
492
+ test_name, metadata_authentication_conf);
493
+ rd_kafka_conf_destroy(metadata_authentication_conf);
494
+ }
495
+ }
186
496
 
187
497
  int main_0126_oauthbearer_oidc(int argc, char **argv) {
188
498
  rd_kafka_conf_t *conf;
@@ -194,18 +504,23 @@ int main_0126_oauthbearer_oidc(int argc, char **argv) {
194
504
  sec = test_conf_get(conf, "security.protocol");
195
505
  if (!strstr(sec, "sasl")) {
196
506
  TEST_SKIP("Apache Kafka cluster not configured for SASL\n");
507
+ rd_kafka_conf_destroy(conf);
197
508
  return 0;
198
509
  }
199
510
 
200
511
  oidc = test_conf_get(conf, "sasl.oauthbearer.method");
201
512
  if (rd_strcasecmp(oidc, "OIDC")) {
202
513
  TEST_SKIP("`sasl.oauthbearer.method=OIDC` is required\n");
514
+ rd_kafka_conf_destroy(conf);
203
515
  return 0;
204
516
  }
205
517
 
206
- do_test_produce_consumer_with_OIDC(conf);
207
- do_test_produce_consumer_with_OIDC_should_fail(conf);
518
+ do_test_produce_consumer_with_OIDC("client_credentials", conf);
519
+ do_test_produce_consumer_with_OIDC_should_fail_invalid_token_endpoint(
520
+ conf);
208
521
  do_test_produce_consumer_with_OIDC_expired_token_should_fail(conf);
522
+ do_test_produce_consumer_with_OIDC_jwt_bearer(conf);
523
+ do_test_produce_consumer_with_OIDC_metadata_authentication(conf);
209
524
 
210
525
  rd_kafka_conf_destroy(conf);
211
526