def test_run_check_ignore_not_unknown(mock_print, exit, mock_subproc, mock_os, mock_get_types): logger = FakeLogger() script_path = 'something' target_type = 'thistargettype' hostname = 'thehost' oid = 'theoid' ignore_unknown = True mock_os.path.exists.return_value = True mock_os.path.isfile.return_value = True exit_status = 42 exit_output = 'badexitoutput' error = subprocess.CalledProcessError( exit_status, 'notarealcommand', exit_output, ) mock_subproc.side_effect = error nagios_plugin_utils.run_check(script_path, target_type, hostname, oid, logger, ignore_unknown) mock_print_arg = mock_print.call_args_list[0][0][0].lower() assert exit_output == mock_print_arg logger.string_appears_in('error', ('unknown or error', 'status', text_type(exit_status), 'output', exit_output)) exit.assert_called_once_with(exit_status)
def test_found_already_notified(submit_result, get_status, get_services): logger = FakeLogger() message = 'themessage' trap_check_name = 'thetrapcheckname' instance = 'theinstance' services = [ { 'service_description': 'notthis' }, { 'service_description': trap_check_name, 'current_state': '2' }, ] get_services.return_value = services result = snmp_trap_handler.update_check_state( message=message, trap_check_name=trap_check_name, instance=instance, logger=logger, ) assert result == 1 assert logger.string_appears_in('debug', 'correct service found') assert logger.string_appears_in('warn', 'in progress') get_services.assert_called_once_with(instance, 'nagios status')
def test_instance_finder_address_can_find_name(get_host_name): logger = FakeLogger() expected_name = 'thename' action = { 'instance': { 'finder': re.compile("^(?P<address>[a-z]+)$"), 'oid': 'something', }, } details = { 'something': 'anything', 'unimportant': 'notthis', } get_host_name.return_value = expected_name result = snmp_trap_handler.find_target_instance( action=action, details=details, message_source='notimportant', logger=logger, ) assert result == expected_name assert logger.string_appears_in('debug', ('look up', 'name')) assert logger.string_appears_in('debug', 'details finder found')
def test_no_instance_finder_can_find_name(get_host_name): logger = FakeLogger() expected_name = 'thename' source_address = 'thesource' action = {} details = { 'unimportant': 'notthis', } get_host_name.return_value = expected_name result = snmp_trap_handler.find_target_instance( action=action, details=details, message_source=source_address, logger=logger, ) assert result == expected_name assert logger.string_appears_in('debug', ('look up', 'name')) assert not logger.string_appears_in('debug', 'details finder found') get_host_name.assert_called_once_with(source_address)
def test_instance_finder_address_cannot_find_name(get_host_name): logger = FakeLogger() action = { 'instance': { 'finder': re.compile("^(?P<address>[a-z]+)$"), 'oid': 'something', }, } details = { 'something': 'anything', 'unimportant': 'notthis', } get_host_name.return_value = None with pytest.raises(snmp_trap_handler.MonitoredHostNotFoundError): snmp_trap_handler.find_target_instance( action=action, details=details, message_source='notimportant', logger=logger, ) assert logger.string_appears_in('debug', ('look up', 'name')) assert logger.string_appears_in('debug', 'details finder found') assert logger.string_appears_in('error', 'no host found')
def test_no_instance_finder_cannot_find_name(get_host_name): logger = FakeLogger() source_address = 'thesource' action = {} details = { 'unimportant': 'notthis', } get_host_name.return_value = None with pytest.raises(snmp_trap_handler.MonitoredHostNotFoundError): snmp_trap_handler.find_target_instance( action=action, details=details, message_source=source_address, logger=logger, ) assert logger.string_appears_in('debug', ('look up', 'name')) assert not logger.string_appears_in('debug', 'details finder found') assert logger.string_appears_in('error', 'no host found') get_host_name.assert_called_once_with(source_address)
def test_oid_for_message_and_instance(): logger = FakeLogger() config_name = 'instance_and_message_oid' lookups = { 'instanceoid': 'lookedupinstance', 'messageoid': 'lookedupmessage', } oid_lookup = FakeOidLookup(lookups=lookups) result = snmp_trap_handler.determine_action( oid=config_name, oid_lookup=oid_lookup, logger=logger, ) expected_path = CONF_PATH.format(oid=config_name) assert logger.string_appears_in('debug', expected_path) assert logger.string_appears_in('debug', 'loading instance') assert logger.string_appears_in('debug', 'loading oid_for_message') assert result['instance'] == { 'oid': lookups['instanceoid'], 'finder': re.compile(u'testfinder'), } assert result['oid_for_message'] == lookups['messageoid']
def test_only_wrong_services(submit_result, get_status, get_services): logger = FakeLogger() message = 'themessage' trap_check_name = 'thetrapcheckname' instance = 'theinstance' services = [ { 'service_description': 'notthis' }, { 'service_description': 'orthis' }, ] get_services.return_value = services result = snmp_trap_handler.update_check_state( message=message, trap_check_name=trap_check_name, instance=instance, logger=logger, ) assert result == 3 for service in services: assert logger.string_appears_in( 'debug', ('considering service', service['service_description']), ) assert logger.string_appears_in('warn', ('service', 'not found')) get_services.assert_called_once_with(instance, 'nagios status')
def test_notification_failure(submit_result, get_status, get_services): logger = FakeLogger() message = 'themessage' trap_check_name = 'thetrapcheckname' instance = 'theinstance' services = [ { 'service_description': trap_check_name, 'current_state': '0' }, { 'service_description': 'notthis' }, ] get_services.return_value = services submit_result.side_effect = RuntimeError with pytest.raises(RuntimeError): snmp_trap_handler.update_check_state( message=message, trap_check_name=trap_check_name, instance=instance, logger=logger, ) for expected in ('correct service found', 'submitting check'): assert logger.string_appears_in('debug', expected) assert not logger.string_appears_in('warn', 'in progress')
def test_run_check_missing_script(mock_print, exit, mock_subproc, mock_os, mock_get_types): logger = FakeLogger() script_path = 'something' target_type = 'thistargettype' hostname = 'thehost' oid = 'theoid' ignore_unknown = False mock_os.path.exists.return_value = True mock_os.path.isfile.return_value = False nagios_plugin_utils.run_check(script_path, target_type, hostname, oid, logger, ignore_unknown) exist_check = mock_os.path.exists.call_args_list[0][0][0] assert exist_check.endswith(hashlib.md5(target_type).hexdigest() + '.ini') mock_print_arg = mock_print.call_args_list[0][0][0].lower() assert 'check_snmp' in mock_print_arg assert 'not found' in mock_print_arg logger.string_appears_in('error', ('check_snmp', 'not found')) exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
def test_trap_not_defined(nagios_utils, exit, snmp_utils, logging_utils): trap_name = 'missing' lookups = deepcopy(BASE_LOOKUPS) lookups[BASIC_NOTIFICATION_TRAP_VALUE] = trap_name logger = FakeLogger() oid_lookup = FakeOidLookup(lookups=lookups) stdin = FakeStdin(deepcopy(BASIC_NOTIFICATION)) logging_utils.Logger.return_value = logger snmp_utils.OIDLookup.return_value = oid_lookup snmp_trap_handler.sys.stdin = stdin snmp_trap_handler.main() logging_utils.Logger.assert_called_once_with( 'cloudify_nagios_snmp_trap_handler') assert logger.string_appears_in('info', ( 'trap', trap_name, 'from', NOTIFICATION_SOURCE, )) assert logger.string_appears_in('info', 'no action')
def test_run_check_ignore_unknown(mock_print, exit, mock_subproc, mock_os, mock_get_types): logger = FakeLogger() script_path = 'something' target_type = 'thistargettype' hostname = 'thehost' oid = 'theoid' ignore_unknown = True mock_os.path.exists.return_value = True mock_os.path.isfile.return_value = True exit_status = 3 exit_output = 'badexitoutput' error = subprocess.CalledProcessError( exit_status, 'notarealcommand', exit_output, ) mock_subproc.side_effect = error result = nagios_plugin_utils.run_check(script_path, target_type, hostname, oid, logger, ignore_unknown) logger.string_appears_in('warn', ('unknown state', 'ignoring')) assert result is None assert mock_print.call_count == 0 assert exit.call_count == 0
def test_no_result(mock_print, exit, thresholds, run_check, get_multi_float, calculate_mean, get_instance_addresses, get_host_address, generate_perfdata, generate_check_id, check_thresholds_and_exit, logging_utils): logger = FakeLogger() logging_utils.Logger.return_value = logger run_check_results = None, None run_check.side_effect = run_check_results returned_thresholds = 'thresholds' thresholds.return_value = returned_thresholds float_values = 1.5, 2.0 get_multi_float.return_value = float_values mean = 1.75 calculate_mean.return_value = mean old_calculate_mean = calculate_mean.APPROACHES['arithmetic_mean'] check_snmp_aggregate.APPROACHES['arithmetic_mean'] = calculate_mean instance_addresses = '192.0.2.5', '192.0.2.6' get_instance_addresses.return_value = instance_addresses host_addresses = ['addr1', 'addr2'] get_host_address.side_effect = host_addresses perfdata = 'performance_data' generate_perfdata.return_value = perfdata check_identifier = 'check_id' generate_check_id.return_value = check_identifier node = 'therealhost' oids = 'somefakeoid,other' target_type = 'thetypeoftarget' check_snmp_aggregate.main( ['--node', node, '--oids', oids, '--approach', 'arithmetic_mean', '--unknown', 'ignore', '--target-type', target_type] ) logger.string_appears_in('error', 'no values') mock_print_arg = mock_print.call_args_list[0][0][0].lower() assert 'no values' in mock_print_arg exit.assert_called_once_with(STATUS_UNKNOWN) check_snmp_aggregate.APPROACHES['arithmetic_mean'] = old_calculate_mean
def test_broken_instance(): logger = FakeLogger() config_name = 'broken_instance' with pytest.raises(KeyError): snmp_trap_handler.determine_action( oid=config_name, oid_lookup=mock.Mock(), logger=logger, ) expected_path = CONF_PATH.format(oid=config_name) assert logger.string_appears_in('debug', expected_path) assert logger.string_appears_in('debug', 'loading instance')
def test_get_good_rate(mock_print, mock_exit, mock_time, run, mock_json): mock_time.return_value = 100 logger = FakeLogger() value = 42 path = 'something' opener = FakeOpener() opener.write = mock.Mock() nagios_plugin_utils.open = opener.open mock_json.load.return_value = { 'timestamp': 90, 'result': 32, } expected = 1.0 result = nagios_plugin_utils.store_value_and_calculate_rate( logger, value, path, ) assert mock_exit.call_count == 0 assert mock_print.call_count == 0 assert result == expected
def test_generate_message_without_oid(): logger = FakeLogger() trap_value = 'thetrap' action = {} details = {} expected_prefix = snmp_trap_handler.TRAP_RECEIVED_PREFIX.format( oid=trap_value, ).lower() result = snmp_trap_handler.generate_check_message(trap_value, details, action, logger) result = result.lower() for component in (expected_prefix, 'no message oid', trap_value): assert component in result assert logger.string_appears_in('debug', component)
def test_check_name(): logger = FakeLogger() target_type = 'target' trap_value = 'trap' expected = '{target_type}_instances:SNMPTRAP {trap}'.format( target_type=target_type, trap=trap_value, ) result = snmp_trap_handler.get_check_name(target_type, trap_value, logger) assert result == expected assert logger.string_appears_in('debug', ('check name', 'is', expected.lower()))
def test_incomplete_opening_previous(mock_print, mock_exit, mock_time, run, mock_json): mock_time.return_value = 100 logger = FakeLogger() value = 42 path = 'something' opener = FakeOpener() opener.write = mock.Mock() nagios_plugin_utils.open = opener.open mock_json.load.return_value = {} with pytest.raises(SystemExit): nagios_plugin_utils.store_value_and_calculate_rate( logger, value, path, ) mock_print_arg = mock_print.call_args_list[0][0][0].lower() assert 'previous' in mock_print_arg assert 'incomplete' in mock_print_arg assert 'cannot calculate' in mock_print_arg mock_exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
def test_pre_seed(): logger = FakeLogger() oid_lookup = mock.Mock() oid_lookup.get.side_effect = RuntimeError raw_details = [ { 'raw_oid': 'system.sysUpTime.0', 'value': '1234' }, { 'raw_oid': 'snmp.1.1.4.1.0', 'value': 'enterprises.52312.900.0.0.1' }, ] with pytest.raises(RuntimeError): snmp_trap_handler.normalise_oids_and_get_trap_value( raw_details=raw_details, oid_lookup=oid_lookup, logger=logger, ) oid_lookup.get.assert_called_once_with([ snmp_trap_handler.SNMP_TRAP_OID, 'system.sysUpTime.0', 'snmp.1.1.4.1.0', ])
def test_missing_action(): logger = FakeLogger() config_name = 'missing' result = snmp_trap_handler.determine_action( oid=config_name, oid_lookup=mock.Mock(), logger=logger, ) assert result is None expected_path = CONF_PATH.format(oid=config_name) assert logger.string_appears_in('debug', expected_path) assert 'not found' in logger.messages['warn'][-1]
def test_too_fast(mock_print, mock_exit, mock_time, run, mock_json): mock_time.return_value = 100 logger = FakeLogger() value = 42 path = 'something' opener = FakeOpener() opener.write = mock.Mock() nagios_plugin_utils.open = opener.open mock_json.load.return_value = { 'timestamp': 100, 'result': 52, } with pytest.raises(SystemExit): nagios_plugin_utils.store_value_and_calculate_rate( logger, value, path, ) mock_print_arg = mock_print.call_args_list[0][0][0].lower() assert 'too recently' in mock_print_arg assert 'cannot calculate' in mock_print_arg mock_exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
def test_no_thresholds(mock_print, exit, thresholds, run_check, get_perfdata, get_single_float, get_instance_rate_path, calculate_rate, check_thresholds_and_exit, logging_utils): logger = FakeLogger() logging_utils.Logger.return_value = logger returned_thresholds = 'thresholds' thresholds.return_value = returned_thresholds perfdata = 'theperfdata' get_perfdata.return_value = perfdata float_value = 1.234 get_single_float.return_value = float_value hostname = 'therealhost' oid = 'somefakeoid' target_type = 'thetypeoftarget' check_snmp_numeric.main( ['--hostname', hostname, '--oid', oid, '--target-type', target_type]) check_thresholds_and_exit.assert_called_once_with( float_value, returned_thresholds, perfdata, False, ) thresholds.assert_called_once_with("", "", "", "", logger)
def test_multi_oid(mock_print, exit, thresholds, run_check, get_perfdata, get_single_float, get_instance_rate_path, calculate_rate, check_thresholds_and_exit, logging_utils): logger = FakeLogger() hostname = 'therealhost' oid = 'somefakeoid,otheroid' target_type = 'thetypeoftarget' check_snmp_numeric.main( ['--hostname', hostname, '--oid', oid, '--target-type', target_type]) logger.string_appears_in('error', 'single oid') mock_print_arg = mock_print.call_args_list[0][0][0].lower() assert 'single oid' in mock_print_arg exit.assert_called_once_with(STATUS_UNKNOWN)
def test_generate_message_with_oid(): logger = FakeLogger() trap_value = 'thetrap' expected_message_content = 'thismessage' action = {'oid_for_message': 'something'} details = {'something': expected_message_content} expected_prefix = snmp_trap_handler.TRAP_RECEIVED_PREFIX.format( oid=trap_value, ).lower() result = snmp_trap_handler.generate_check_message(trap_value, details, action, logger) result = result.lower() for component in (expected_prefix, expected_message_content): assert component in result assert logger.string_appears_in('debug', component)
def test_empty_action(): logger = FakeLogger() config_name = 'empty' with pytest.raises(ValueError): snmp_trap_handler.determine_action( oid=config_name, oid_lookup=mock.Mock(), logger=logger, ) expected_path = CONF_PATH.format(oid=config_name) assert logger.string_appears_in('debug', expected_path) assert 'not' in logger.messages['exception'][-1] assert 'JSON' in logger.messages['exception'][-1] assert 'empty' in logger.messages['exception'][-1]
def test_oid_for_message_lookup_exception(): logger = FakeLogger() config_name = 'just_oid_for_message' oid_lookup = mock.Mock() oid_lookup.get.side_effect = RuntimeError with pytest.raises(RuntimeError): snmp_trap_handler.determine_action( oid=config_name, oid_lookup=oid_lookup, logger=logger, ) expected_path = CONF_PATH.format(oid=config_name) assert logger.string_appears_in('debug', expected_path) assert logger.string_appears_in('debug', 'loading oid_for_message')
def test_missing_traps(): logger = FakeLogger() target_type = 'missingtraps' trap_value = 'test_trap' with pytest.raises(KeyError): snmp_trap_handler.determine_reaction( target_type=target_type, trap_value=trap_value, logger=logger, ) expected_path = CONF_PATH.format( target_type=hashlib.md5(target_type).hexdigest(), ) assert logger.string_appears_in('debug', expected_path) assert logger.string_appears_in('debug', 'loading reaction')
def test_thresholds(mock_print, exit, thresholds, run_check, get_multi_float, calculate_mean, get_instance_addresses, get_host_address, generate_perfdata, generate_check_id, check_thresholds_and_exit, logging_utils): logger = FakeLogger() logging_utils.Logger.return_value = logger returned_thresholds = 'thresholds' thresholds.return_value = returned_thresholds float_values = 1.5, 2.0 get_multi_float.return_value = float_values mean = 1.75 calculate_mean.return_value = mean old_calculate_mean = calculate_mean.APPROACHES['arithmetic_mean'] check_snmp_aggregate.APPROACHES['arithmetic_mean'] = calculate_mean instance_addresses = '192.0.2.5', '192.0.2.6' get_instance_addresses.return_value = instance_addresses perfdata = 'performance_data' generate_perfdata.return_value = perfdata low_warn = 2 low_crit = 1 high_warn = 3 high_crit = 4 node = 'therealhost' oids = 'somefakeoid,other' target_type = 'thetypeoftarget' check_snmp_aggregate.main([ '--node', node, '--oids', oids, '--approach', 'arithmetic_mean', '--unknown', 'ignore', '--target-type', target_type, '--low-warning', text_type(low_warn), '--low-critical', text_type(low_crit), '--high-warning', text_type(high_warn), '--high-critical', text_type(high_crit) ]) check_thresholds_and_exit.assert_called_once_with( mean, returned_thresholds, perfdata, False, ) thresholds.assert_called_once_with( low_warn, low_crit, high_warn, high_crit, logger, ) check_snmp_aggregate.APPROACHES['arithmetic_mean'] = old_calculate_mean
def test_just_oid_for_message(): logger = FakeLogger() config_name = 'just_oid_for_message' oid_lookup = FakeOidLookup(default='looked_up_message_oid') result = snmp_trap_handler.determine_action( oid=config_name, oid_lookup=oid_lookup, logger=logger, ) expected_path = CONF_PATH.format(oid=config_name) assert logger.string_appears_in('debug', expected_path) assert not logger.string_appears_in('debug', 'loading instance') assert logger.string_appears_in('debug', 'loading oid_for_message') assert result['oid_for_message'] == 'looked_up_message_oid'
def test_no_reaction_found(): logger = FakeLogger() target_type = 'notrap' trap_value = 'test_trap' result = snmp_trap_handler.determine_reaction( target_type=target_type, trap_value=trap_value, logger=logger, ) expected_path = CONF_PATH.format( target_type=hashlib.md5(target_type).hexdigest(), ) assert logger.string_appears_in('debug', expected_path) assert logger.string_appears_in('debug', 'loading reaction') assert result is None