Skip to content

Commit 67dd0ce

Browse files
authored
KAFKA-20941 Replace HTMLTestRunner with pytest-html (#23170)
Replaces the inactive `HTMLTestRunner-Python3` dependency with `pytest` and `pytest-html` for Docker sanity tests. The existing unittest-based tests and HTML report paths remain unchanged. Test results are now determined using the pytest exit code. pytest 9.0+ requires Python 3.10 or later. Testing: * Verified successful and failing pytest runs. * Verified HTML report generation. * Ran the JVM Docker sanity suite. Reviewers: Chia-Ping Tsai <chia7712@gmail.com>
1 parent 29ca796 commit 67dd0ce

4 files changed

Lines changed: 28 additions & 32 deletions

File tree

‎docker/README.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ supported_image_tag: ['3.6.1', 'latest', '3.7.0-rc1']
108108
Local Setup
109109
-----------
110110

111-
Make sure you have python (>= 3.7.x) and java (>= 17) (java needed only for running tests) installed before running the tests and scripts.
111+
Make sure you have python (>= 3.10.x) and java (>= 17) (java needed only for running tests) installed before running the tests and scripts.
112112

113113
Run `pip install -r requirements.txt` to get all the requirements for running the scripts.
114114

@@ -216,4 +216,3 @@ python generate_kafka_pr_template.py --image-type=jvm
216216
- kafka-version - This is the version to create the Docker official images static Dockerfile and assets for, as well as the version to build and test the Docker official image for.
217217
- image-type - This is the type of image that we intend to build. This will be dropdown menu type selection in the workflow. `jvm` image type is for official docker image (to be hosted on apache/kafka) as described in [KIP-975](https://cwiki.apache.org/confluence/x/z5izDw).
218218
- **NOTE:** As of now [KIP-1028](https://cwiki.apache.org/confluence/x/0AmpEQ) only aims to release JVM based Docker Official Images and not GraalVM based native Apache Kafka docker image.
219-

‎docker/docker_build_test.py‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,15 @@ def run_docker_tests(image, tag, kafka_url, kafka_archive, image_type, container
6161
raise ValueError("Either --kafka-url or --kafka-archive must be passed")
6262
execute(["mkdir", f"{temp_dir_path}/fixtures/kafka"])
6363
execute(["tar", "xfz", f"{temp_dir_path}/kafka.tgz", "-C", f"{temp_dir_path}/fixtures/kafka", "--strip-components", "1"])
64-
failure_count, error_count = run_tests(f"{image}:{tag}", image_type, temp_dir_path, container_runtime)
64+
test_exit_code = run_tests(f"{image}:{tag}", image_type, temp_dir_path, container_runtime)
6565
except:
6666
raise SystemError("Failed to run the tests")
6767
finally:
6868
shutil.rmtree(temp_dir_path)
6969
test_report_location_text = f"To view test report please check {current_dir}/test/report_{image_type}.html"
70-
if failure_count != 0:
71-
raise SystemError(f"{failure_count} tests have failed. {test_report_location_text}")
72-
elif error_count != 0:
73-
raise SystemError(f"{error_count} tests have errored. {test_report_location_text}")
74-
else:
75-
print(f"All tests passed successfully. {test_report_location_text}")
70+
if test_exit_code != 0:
71+
raise SystemError(f"Tests failed with pytest exit code {test_exit_code}. {test_report_location_text}")
72+
print(f"All tests passed successfully. {test_report_location_text}")
7673

7774
if __name__ == '__main__':
7875
parser = argparse.ArgumentParser()
@@ -97,4 +94,4 @@ def run_docker_tests(image, tag, kafka_url, kafka_archive, image_type, container
9794
build_docker_image_runner(f"{container_runtime} build -f $DOCKER_FILE -t {args.image}:{args.tag} --build-arg build_date={date.today()} --no-cache $DOCKER_DIR", args.image_type, args.kafka_archive)
9895

9996
if args.test_only or not (args.build_only or args.test_only):
100-
run_docker_tests(args.image, args.tag, args.kafka_url, args.kafka_archive, args.image_type, container_runtime)
97+
run_docker_tests(args.image, args.tag, args.kafka_url, args.kafka_archive, args.image_type, container_runtime)

‎docker/requirements.txt‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
requests
16-
HTMLTestRunner-Python3
16+
pytest
17+
pytest-html

‎docker/test/docker_sanity_test.py‎

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
1717

18-
import unittest
18+
import os
1919
import subprocess
20-
from HTMLTestRunner import HTMLTestRunner
20+
import unittest
21+
22+
import pytest
2123
import test.constants as constants
22-
import os
2324

2425
class DockerSanityTest(unittest.TestCase):
2526
IMAGE="apache/kafka"
@@ -231,22 +232,20 @@ def run_tests(image, mode, fixtures_dir, container_runtime="docker"):
231232
DockerSanityTest.MODE = mode
232233
DockerSanityTest.CONTAINER_RUNTIME = container_runtime
233234

234-
test_classes_to_run = []
235-
if mode == "jvm" or mode == "native":
236-
test_classes_to_run = [DockerSanityTestCombinedMode, DockerSanityTestIsolatedMode]
237-
238-
loader = unittest.TestLoader()
239-
suites_list = []
240-
for test_class in test_classes_to_run:
241-
suite = loader.loadTestsFromTestCase(test_class)
242-
suites_list.append(suite)
243-
combined_suite = unittest.TestSuite(suites_list)
244235
cur_directory = os.path.dirname(os.path.realpath(__file__))
245-
outfile = open(f"{cur_directory}/report_{mode}.html", "w")
246-
runner = HTMLTestRunner.HTMLTestRunner(
247-
stream=outfile,
248-
title=f'Test Report: Apache Kafka {mode.capitalize()} Docker Image',
249-
description='This demonstrates the report output.'
250-
)
251-
result = runner.run(combined_suite)
252-
return (result.failure_count, result.error_count)
236+
report_path = f"{cur_directory}/report_{mode}.html"
237+
238+
class ReportTitlePlugin:
239+
@pytest.hookimpl(optionalhook=True)
240+
def pytest_html_report_title(self, report):
241+
report.title = f"Test Report: Apache Kafka {mode.capitalize()} Docker Image"
242+
243+
return pytest.main([
244+
"--pyargs",
245+
__name__,
246+
f"--html={report_path}",
247+
"--self-contained-html",
248+
"--capture=tee-sys",
249+
"-p",
250+
"no:cacheprovider",
251+
], plugins=[ReportTitlePlugin()])

0 commit comments

Comments
 (0)