From af01aa40dc5b3b03e9513115d36f65bb70b4372e Mon Sep 17 00:00:00 2001 From: Krishna Sharma Date: Tue, 4 Nov 2025 10:21:02 +0530 Subject: [PATCH 1/2] Add test coverage for parameter_extraction_cache_capacity type handling Addresses #109 by adding comprehensive test cases for the fix implemented in commit c7496f6. Tests ensure: - Integer values are handled correctly - String-to-int conversion works as expected - Edge cases are covered - Prevents regression of the original TypeError bug This provides quality assurance for configuration parameter handling and prevents the issue from reoccurring. --- tests/test_template_miner.py | 142 +++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/tests/test_template_miner.py b/tests/test_template_miner.py index 8775d9f..72ca3d5 100644 --- a/tests/test_template_miner.py +++ b/tests/test_template_miner.py @@ -2,7 +2,9 @@ import io import logging +import os import sys +import tempfile import unittest from os.path import dirname @@ -381,3 +383,143 @@ def test_match_strategies(self): self.assertIsNotNone(miner.match("", full_search_strategy="never")) self.assertIsNotNone(miner.match("", full_search_strategy="always")) self.assertIsNotNone(miner.match("", full_search_strategy="fallback")) + + def create_temp_config(self, content): + temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.ini', delete=False) + temp_file.write(content) + temp_file.close() + return temp_file.name + + def cleanup_temp_file(self, filepath): + if os.path.exists(filepath): + os.unlink(filepath) + + def test_parameter_extraction_cache_capacity_default_value(self): + config = TemplateMinerConfig() + self.assertEqual(config.parameter_extraction_cache_capacity, 3000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + def test_parameter_extraction_cache_capacity_integer_assignment(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 5000 + self.assertEqual(config.parameter_extraction_cache_capacity, 5000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + def test_parameter_extraction_cache_capacity_type_validation(self): + config = TemplateMinerConfig() + test_values = [1000, 5000, 10000] + for value in test_values: + config.parameter_extraction_cache_capacity = value + self.assertEqual(config.parameter_extraction_cache_capacity, value) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + def test_parameter_extraction_cache_capacity_config_file_parsing(self): + config_content = """[MASKING] +parameter_extraction_cache_capacity = 7000 +mask_prefix = < +mask_suffix = > +""" + config_file = self.create_temp_config(config_content) + try: + config = TemplateMinerConfig() + config.load(config_file) + self.assertEqual(config.parameter_extraction_cache_capacity, 7000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_config_fallback(self): + config_content = """[MASKING] +mask_prefix = < +mask_suffix = > +""" + config_file = self.create_temp_config(config_content) + try: + config = TemplateMinerConfig() + config.load(config_file) + self.assertEqual(config.parameter_extraction_cache_capacity, 3000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_invalid_config(self): + config_content = """[MASKING] +parameter_extraction_cache_capacity = invalid_value +mask_prefix = < +mask_suffix = > +""" + config_file = self.create_temp_config(config_content) + try: + config = TemplateMinerConfig() + with self.assertRaises(ValueError): + config.load(config_file) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_lru_cache_instantiation(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 5000 + template_miner = TemplateMiner(config=config) + self.assertIsNotNone(template_miner.parameter_extraction_cache) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 5000) + + def test_parameter_extraction_cache_capacity_cache_operations(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 2 + template_miner = TemplateMiner(config=config) + + template_miner.parameter_extraction_cache[("test1", True)] = "result1" + template_miner.parameter_extraction_cache[("test2", False)] = "result2" + template_miner.parameter_extraction_cache[("test3", True)] = "result3" + + self.assertEqual(len(template_miner.parameter_extraction_cache), 2) + self.assertNotIn(("test1", True), template_miner.parameter_extraction_cache) + + def test_parameter_extraction_cache_capacity_edge_cases(self): + config = TemplateMinerConfig() + + config.parameter_extraction_cache_capacity = 0 + template_miner = TemplateMiner(config=config) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 0) + + config.parameter_extraction_cache_capacity = 1 + template_miner = TemplateMiner(config=config) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 1) + + config.parameter_extraction_cache_capacity = 1000000 + template_miner = TemplateMiner(config=config) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 1000000) + + def test_parameter_extraction_cache_capacity_issue_105_regression(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 5000 + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + template_miner = TemplateMiner(config=config) + self.assertIsNotNone(template_miner.parameter_extraction_cache) + + config_content = """[MASKING] +parameter_extraction_cache_capacity = 8000 +""" + config_file = self.create_temp_config(config_content) + try: + config2 = TemplateMinerConfig() + config2.load(config_file) + self.assertIsInstance(config2.parameter_extraction_cache_capacity, int) + template_miner2 = TemplateMiner(config=config2) + self.assertIsNotNone(template_miner2.parameter_extraction_cache) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_end_to_end(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 100 + template_miner = TemplateMiner(config=config) + + result = template_miner.add_log_message("hello world 123") + self.assertIsNotNone(result) + + template = result["template_mined"] + extracted_params = template_miner.extract_parameters(template, "hello world 456") + + self.assertEqual(len(template_miner.parameter_extraction_cache), 1) \ No newline at end of file From aa84b43d6de6a3945505109b55254a9320848e98 Mon Sep 17 00:00:00 2001 From: Krishna Sharma Date: Tue, 4 Nov 2025 10:22:09 +0530 Subject: [PATCH 2/2] Add test coverage for parameter_extraction_cache_capacity type handling Addresses #105 by adding comprehensive test cases for the fix implemented in commit c7496f6. Tests ensure: - Integer values are handled correctly - String-to-int conversion works as expected - Edge cases are covered - Prevents regression of the original TypeError bug This provides quality assurance for configuration parameter handling and prevents the issue from reoccurring. --- tests/test_template_miner.py | 142 +++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/tests/test_template_miner.py b/tests/test_template_miner.py index 8775d9f..72ca3d5 100644 --- a/tests/test_template_miner.py +++ b/tests/test_template_miner.py @@ -2,7 +2,9 @@ import io import logging +import os import sys +import tempfile import unittest from os.path import dirname @@ -381,3 +383,143 @@ def test_match_strategies(self): self.assertIsNotNone(miner.match("", full_search_strategy="never")) self.assertIsNotNone(miner.match("", full_search_strategy="always")) self.assertIsNotNone(miner.match("", full_search_strategy="fallback")) + + def create_temp_config(self, content): + temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.ini', delete=False) + temp_file.write(content) + temp_file.close() + return temp_file.name + + def cleanup_temp_file(self, filepath): + if os.path.exists(filepath): + os.unlink(filepath) + + def test_parameter_extraction_cache_capacity_default_value(self): + config = TemplateMinerConfig() + self.assertEqual(config.parameter_extraction_cache_capacity, 3000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + def test_parameter_extraction_cache_capacity_integer_assignment(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 5000 + self.assertEqual(config.parameter_extraction_cache_capacity, 5000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + def test_parameter_extraction_cache_capacity_type_validation(self): + config = TemplateMinerConfig() + test_values = [1000, 5000, 10000] + for value in test_values: + config.parameter_extraction_cache_capacity = value + self.assertEqual(config.parameter_extraction_cache_capacity, value) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + def test_parameter_extraction_cache_capacity_config_file_parsing(self): + config_content = """[MASKING] +parameter_extraction_cache_capacity = 7000 +mask_prefix = < +mask_suffix = > +""" + config_file = self.create_temp_config(config_content) + try: + config = TemplateMinerConfig() + config.load(config_file) + self.assertEqual(config.parameter_extraction_cache_capacity, 7000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_config_fallback(self): + config_content = """[MASKING] +mask_prefix = < +mask_suffix = > +""" + config_file = self.create_temp_config(config_content) + try: + config = TemplateMinerConfig() + config.load(config_file) + self.assertEqual(config.parameter_extraction_cache_capacity, 3000) + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_invalid_config(self): + config_content = """[MASKING] +parameter_extraction_cache_capacity = invalid_value +mask_prefix = < +mask_suffix = > +""" + config_file = self.create_temp_config(config_content) + try: + config = TemplateMinerConfig() + with self.assertRaises(ValueError): + config.load(config_file) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_lru_cache_instantiation(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 5000 + template_miner = TemplateMiner(config=config) + self.assertIsNotNone(template_miner.parameter_extraction_cache) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 5000) + + def test_parameter_extraction_cache_capacity_cache_operations(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 2 + template_miner = TemplateMiner(config=config) + + template_miner.parameter_extraction_cache[("test1", True)] = "result1" + template_miner.parameter_extraction_cache[("test2", False)] = "result2" + template_miner.parameter_extraction_cache[("test3", True)] = "result3" + + self.assertEqual(len(template_miner.parameter_extraction_cache), 2) + self.assertNotIn(("test1", True), template_miner.parameter_extraction_cache) + + def test_parameter_extraction_cache_capacity_edge_cases(self): + config = TemplateMinerConfig() + + config.parameter_extraction_cache_capacity = 0 + template_miner = TemplateMiner(config=config) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 0) + + config.parameter_extraction_cache_capacity = 1 + template_miner = TemplateMiner(config=config) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 1) + + config.parameter_extraction_cache_capacity = 1000000 + template_miner = TemplateMiner(config=config) + self.assertEqual(template_miner.parameter_extraction_cache.maxsize, 1000000) + + def test_parameter_extraction_cache_capacity_issue_105_regression(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 5000 + self.assertIsInstance(config.parameter_extraction_cache_capacity, int) + + template_miner = TemplateMiner(config=config) + self.assertIsNotNone(template_miner.parameter_extraction_cache) + + config_content = """[MASKING] +parameter_extraction_cache_capacity = 8000 +""" + config_file = self.create_temp_config(config_content) + try: + config2 = TemplateMinerConfig() + config2.load(config_file) + self.assertIsInstance(config2.parameter_extraction_cache_capacity, int) + template_miner2 = TemplateMiner(config=config2) + self.assertIsNotNone(template_miner2.parameter_extraction_cache) + finally: + self.cleanup_temp_file(config_file) + + def test_parameter_extraction_cache_capacity_end_to_end(self): + config = TemplateMinerConfig() + config.parameter_extraction_cache_capacity = 100 + template_miner = TemplateMiner(config=config) + + result = template_miner.add_log_message("hello world 123") + self.assertIsNotNone(result) + + template = result["template_mined"] + extracted_params = template_miner.extract_parameters(template, "hello world 456") + + self.assertEqual(len(template_miner.parameter_extraction_cache), 1) \ No newline at end of file