def test_when_notifier_name_empty_then_exception(notifier_config): notifier_config['name'] = '' exception_validator = RunnableExceptionValidator( lambda: Notifier(notifier_config, Monitor.NOTIFIERS_DIRECTORY, Monitor. NOTIFIER_INSTANCES_PARENT_MODULE)) exception_validator.verify_exception( AssertionError, 'The name of the notifier must contain at least one character!')
def test_when_clear_points_not_positive_integer_then_exception(threshold_config): threshold_config['clear_points'] = 0 exception_validator = RunnableExceptionValidator( lambda: Threshold( config=threshold_config, comparator_directory=Monitor.COMPARATORS_DIRECTORY, comparator_parent_module=Monitor.COMPARATOR_INSTANCES_PARENT_MODULE)) exception_validator.verify_exception( AssertionError, "The threshold clear points must be a positive integer, but got '0'!")
def test_when_comparator_empty_then_exception(threshold_config): threshold_config['comparator'] = '' exception_validator = RunnableExceptionValidator( lambda: Threshold( config=threshold_config, comparator_directory=Monitor.COMPARATORS_DIRECTORY, comparator_parent_module=Monitor.COMPARATOR_INSTANCES_PARENT_MODULE)) exception_validator.verify_exception( AssertionError, 'The threshold comparator must contain at least one character!')
def test_when_notifier_file_not_in_directory_then_exception(notifier_config): notifier_config['name'] = 'non_existent_notifier.py' exception_validator = RunnableExceptionValidator(lambda: Notifier( config=notifier_config, notifier_directory=NOTIFIERS_TEST_INSTANCES_DIRECTORY, notifier_parent_module=NOTIFIERS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The notifier name must be the Python file name placed in the path '{NOTIFIERS_TEST_INSTANCES_DIRECTORY}'," f" but got '{notifier_config['name']}'!")
def test_when_comparator_file_not_in_directory_then_exception(threshold_config): threshold_config['comparator'] = 'non_existent_comparator.py' exception_validator = RunnableExceptionValidator( lambda: Threshold( config=threshold_config, comparator_directory=COMPARATORS_TEST_INSTANCES_DIRECTORY, comparator_parent_module=COMPARATORS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The comparator name must be the Python file name placed in the path '{COMPARATORS_TEST_INSTANCES_DIRECTORY}'," f" but got '{threshold_config['comparator']}'!")
def test_when_metric_class_constructor_missing_configuration_parameter_then_exception(metric_config): metric_config['name'] = 'metric_class_constructor_missing_configuration.py' exception_validator = RunnableExceptionValidator( lambda: Metric( config=metric_config, metric_directory=METRIC_TEST_INSTANCES_DIRECTORY, metric_parent_module=METRIC_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"Metric() takes no arguments. Please make sure that the metric class constructor takes a single argument " f"representing the metric configuration (which might be empty/undefined)!")
def test_when_config_contains_duplicate_monitor_names_then_exception(): config = Config(click=click, jsonschema=jsonschema) exception_validator = RunnableExceptionValidator( lambda: config.from_cli_file_path_param( config_file_path=DUPLICATE_MONITOR_NAMES_CONFIG_FILE_NAME)) exception_validator.verify_exception( click.BadParameter, f"Error parsing config file at '{os.path.abspath(DUPLICATE_MONITOR_NAMES_CONFIG_FILE_NAME)}': " f"Duplicate monitor names are not allowed. However, detected duplicate name 'Monitor_1'!" )
def test_when_metric_file_not_in_directory_then_exception(metric_config): metric_config['name'] = 'non_existent_metric.py' exception_validator = RunnableExceptionValidator( lambda: Metric( config=metric_config, metric_directory=METRIC_TEST_INSTANCES_DIRECTORY, metric_parent_module=METRIC_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The metric name must be the Python file name placed in the path '{METRIC_TEST_INSTANCES_DIRECTORY}', " f"but got '{metric_config['name']}'!")
def test_when_comparator_class_constructor_missing_reference_value_parameter_then_exception(threshold_config): threshold_config['comparator'] = 'comparator_class_constructor_missing_reference_value.py' exception_validator = RunnableExceptionValidator( lambda: Threshold( config=threshold_config, comparator_directory=COMPARATORS_TEST_INSTANCES_DIRECTORY, comparator_parent_module=COMPARATORS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"Comparator() takes no arguments. Please make sure that the comparator class constructor takes a single " f"argument representing the reference value for the comparison operation!")
def test_when_metric_class_is_not_subclass_of_abstract_metric_class_then_exception(metric_config): metric_config['name'] = 'metric_class_not_subclass_of_abstract_metric_class.py' exception_validator = RunnableExceptionValidator( lambda: Metric( config=metric_config, metric_directory=METRIC_TEST_INSTANCES_DIRECTORY, metric_parent_module=METRIC_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The metric class defined in '{metric_config['name']}' must be a subclass of the abstract Metric class " f"defined in {os.path.join(Metric.METRIC_ABSTRACT_CLASS_MODULE, Metric.METRIC_ABSTRACT_CLASS_NAME)}")
def test_when_notifier_file_contains_multiple_python_classes_then_exception( notifier_config): notifier_config['name'] = 'multiple_classes_in_file.py' exception_validator = RunnableExceptionValidator(lambda: Notifier( config=notifier_config, notifier_directory=NOTIFIERS_TEST_INSTANCES_DIRECTORY, notifier_parent_module=NOTIFIERS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The notifier defined in '{notifier_config['name']}' must have a single class defined in its file, " f"but got 2 classes: " f"{['Notifier', 'AnotherNotifier']}!")
def test_when_metric_file_contains_multiple_python_classes_then_exception(metric_config): metric_config['name'] = 'multiple_classes_in_file.py' exception_validator = RunnableExceptionValidator( lambda: Metric( config=metric_config, metric_directory=METRIC_TEST_INSTANCES_DIRECTORY, metric_parent_module=METRIC_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The metric defined in '{metric_config['name']}' must have a single class defined in its file, " f"but got 2 classes: " f"{['Metric', 'AnotherMetric']}!")
def test_when_comparator_class_is_not_subclass_of_abstract_comparator_class_then_exception(threshold_config): threshold_config['comparator'] = 'comparator_class_not_subclass_of_abstract_comparator_class.py' exception_validator = RunnableExceptionValidator( lambda: Threshold( config=threshold_config, comparator_directory=COMPARATORS_TEST_INSTANCES_DIRECTORY, comparator_parent_module=COMPARATORS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The comparator class defined in '{threshold_config['comparator']}' must be a subclass of the abstract " f"Comparator class defined in " f"{os.path.join(Threshold.COMPARATOR_ABSTRACT_CLASS_MODULE, Threshold.COMPARATOR_ABSTRACT_CLASS_NAME)}")
def test_when_comparator_file_contains_multiple_python_classes_then_exception(threshold_config): threshold_config['comparator'] = 'multiple_classes_in_file.py' exception_validator = RunnableExceptionValidator( lambda: Threshold( config=threshold_config, comparator_directory=COMPARATORS_TEST_INSTANCES_DIRECTORY, comparator_parent_module=COMPARATORS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The comparator defined in '{threshold_config['comparator']}' must have a single class defined in its file, " f"but got 2 classes: " f"{['Comparator', 'AnotherComparator']}!")
def test_when_config_monitor_invalid_then_exception(): config = Config(click=click, jsonschema=jsonschema) expected_monitor_config = read_json_from_file( NEGATIVE_ALARM_POINTS_CONFIG_FILE_NAME)['monitors'][0] exception_validator = RunnableExceptionValidator( lambda: config.from_cli_file_path_param( config_file_path=NEGATIVE_ALARM_POINTS_CONFIG_FILE_NAME)) exception_validator.verify_exception( click.BadParameter, f"Error initializing monitor from configuration:\n" f"{json.dumps(expected_monitor_config)}\n" f"The threshold alarm points must be a positive integer, but got '-5'!" )
def test_when_comparator_class_constructor_missing_reference_value_parameter_then_exception( notifier_config): notifier_config[ 'name'] = 'notifier_class_constructor_missing_configuration.py' exception_validator = RunnableExceptionValidator(lambda: Notifier( config=notifier_config, notifier_directory=NOTIFIERS_TEST_INSTANCES_DIRECTORY, notifier_parent_module=NOTIFIERS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"Notifier() takes no arguments. Please make sure that the notifier class constructor takes a single " f"argument representing the notifier configuration (which might be empty/undefined)!" )
def test_when_comparator_class_is_not_subclass_of_abstract_comparator_class_then_exception( notifier_config): notifier_config[ 'name'] = 'notifier_class_not_subclass_of_abstract_notifier_class.py' exception_validator = RunnableExceptionValidator(lambda: Notifier( config=notifier_config, notifier_directory=NOTIFIERS_TEST_INSTANCES_DIRECTORY, notifier_parent_module=NOTIFIERS_TEST_INSTANCES_MODULE)) exception_validator.verify_exception( AssertionError, f"The notifier class defined in '{notifier_config['name']}' must be a subclass of the abstract " f"Notifier class defined in " f"{os.path.join(Notifier.NOTIFIER_ABSTRACT_CLASS_MODULE, Notifier.NOTIFIER_ABSTRACT_CLASS_NAME)}" )
def test_when_cli_context_given_and_exception_then_exception_intercepted_and_logged( ): config = Config(click=click, jsonschema=jsonschema) logger = MagicMock() logger.error = MagicMock() cli_context = MagicMock() cli_context.meta = MagicMock() cli_context.meta[LOGGER_ID] = logger exception_validator = RunnableExceptionValidator( lambda: config.from_cli_file_path_param( config_file_path=DUPLICATE_MONITOR_NAMES_CONFIG_FILE_NAME, cli_context=cli_context)) exception_validator.verify_exception(click.BadParameter, 'Error parsing config file') cli_context.meta[LOGGER_ID].error.assert_called_with( String() & Contains('Error parsing config file') & EndsWith('\n'))
def test_when_minutes_not_a_positive_number_then_exception(): exception_validator = RunnableExceptionValidator(lambda: Interval(0)) exception_validator.verify_exception( AssertionError, f"The interval minutes must be a positive number, but got '0'.")
def test_when_monitor_name_empty_then_exception(monitor): monitor['name'] = '' exception_validator = RunnableExceptionValidator(lambda: Monitor(monitor)) exception_validator.verify_exception(AssertionError, 'The name of the monitor must contain at least one character!')
def test_when_metric_name_empty_then_exception(metric_config): metric_config['name'] = '' exception_validator = RunnableExceptionValidator( lambda: Metric(metric_config, Monitor.METRICS_DIRECTORY, Monitor.METRIC_INSTANCES_PARENT_MODULE)) exception_validator.verify_exception(AssertionError, 'The name of the metric must contain at least one character!')