diff --git a/checks.d/iis.py b/checks.d/iis.py index 2ed4829ac0..f35422e5a5 100644 --- a/checks.d/iis.py +++ b/checks.d/iis.py @@ -7,6 +7,7 @@ # 3rd party import wmi + class IIS(AgentCheck): METRICS = [ ('iis.uptime', 'gauge', 'ServiceUptime'), @@ -43,8 +44,8 @@ class IIS(AgentCheck): ] SERVICE_CHECK = "iis.site_up" - def __init__(self, name, init_config, agentConfig): - AgentCheck.__init__(self, name, init_config, agentConfig) + def __init__(self, name, init_config, agentConfig, instances): + AgentCheck.__init__(self, name, init_config, agentConfig, instances) self.wmi_conns = {} def _get_wmi_conn(self, host, user, password): @@ -84,17 +85,23 @@ def check(self, instance): tags = instance_tags status = AgentCheck.CRITICAL if iis_site.ServiceUptime == 0 else AgentCheck.OK - self.service_check("iis.site_up", status, tags = ['site:%s' % iis_site.Name]) + self.service_check("iis.site_up", status, tags=['site:%s' % iis_site.Name]) expected_sites.remove(iis_site.Name) for metric, mtype, wmi_val in self.METRICS: if not hasattr(iis_site, wmi_val): - if wmi_val == 'TotalBytesTransferred' and hasattr(iis_site, 'TotalBytesTransfered'): - # Windows 2008 sp2 reports it as TotalbytesTransfered instead of TotalBytesTransferred (single r) + if wmi_val == 'TotalBytesTransferred' and hasattr(iis_site, + 'TotalBytesTransfered'): + # Windows 2008 sp2 reports it as TotalbytesTransfered + # instead of TotalBytesTransferred (single r) wmi_val = 'TotalBytesTransfered' + elif wmi_val == 'TotalConnectionAttemptsAllInstances' \ + and hasattr(iis_site, 'TotalConnectionAttemptsallinstances'): + wmi_val = 'TotalConnectionAttemptsallinstances' else: - self.warning('Unable to fetch metric %s. Missing %s in Win32_PerfFormattedData_W3SVC_WebService' \ - % (metric, wmi_val)) + self.warning("Unable to fetch metric %s. Missing %s in " + "Win32_PerfFormattedData_W3SVC_WebService" + % (metric, wmi_val)) continue # Submit the metric value with the correct type @@ -103,4 +110,5 @@ def check(self, instance): metric_func(metric, value, tags=tags) for remaining_site in expected_sites: - self.service_check("iis.site_up", AgentCheck.CRITICAL, tags =['site:%s' % remaining_site]) + self.service_check("iis.site_up", AgentCheck.CRITICAL, + tags=['site:%s' % remaining_site]) diff --git a/tests/test_iis.py b/tests/test_iis.py index 5e3f75b328..d1b3250ab2 100644 --- a/tests/test_iis.py +++ b/tests/test_iis.py @@ -1,58 +1,153 @@ -import unittest -import logging -import time -from nose.plugins.attrib import attr - -from tests.common import get_check - -logging.basicConfig() - -# Run this test on a windows machine with IIS running, with the Default Web Site -# of IIS turned on - -CONFIG = """ -init_config: - -instances: - - host: . - tags: - - mytag1 - - mytag2 - sites: - - Default Web Site -""" - -class IISTestCase(unittest.TestCase): - @attr('windows') - def testIIS(self): - check, instances = get_check('iis', CONFIG) - check.check(instances[0]) - metrics = check.get_metrics() - service_checks = check.get_service_checks() - time.sleep(1) - - # Second run to get the rates - check.check(instances[0]) - metrics = check.get_metrics() - service_checks = check.get_service_checks() - - base_metrics = [m[0] for m in check.METRICS] - ret_metrics = [m[0] for m in metrics] - ret_tags = [m[3]['tags'] for m in metrics] - - # Make sure each metric was captured - for metric in base_metrics: - self.assertTrue(metric in ret_metrics, "not reporting %s" % metric) - - # Make sure everything is tagged correctly - for tags in ret_tags: - self.assertEquals(['mytag1', 'mytag2', 'site:Default Web Site'], tags) - - # Make sure that we get a service check - self.assertEquals(len(service_checks),1) - self.assertEquals(check.SERVICE_CHECK, service_checks[0]['check']) - self.assertEquals(['site:Default Web Site'], service_checks[0]['tags']) - - -if __name__ == "__main__": - unittest.main() +from mock import Mock + +# project +from checks import AgentCheck +from tests.common import AgentCheckTest + + +Win32_PerfFormattedData_W3SVC_WebService_attr = { + 'AnonymousUsersPersec': 0, + 'BytesReceivedPersec': "0", + 'BytesSentPersec': "0", + 'BytesTotalPersec': "0", + 'CGIRequestsPersec': 0, + 'ConnectionAttemptsPersec': 0, + 'CopyRequestsPersec': 0, + 'CurrentAnonymousUsers': 0, + 'CurrentBlockedAsyncIORequests': 0, + 'Currentblockedbandwidthbytes': 0, + 'CurrentCALcountforauthenticatedusers': 0, + 'CurrentCALcountforSSLconnections': 0, + 'CurrentCGIRequests': 0, + 'CurrentConnections': 0, + 'CurrentISAPIExtensionRequests': 0, + 'CurrentNonAnonymousUsers': 0, + 'DeleteRequestsPersec': 0, + 'FilesPersec': 0, + 'FilesReceivedPersec': 0, + 'FilesSentPersec': 0, + 'GetRequestsPersec': 0, + 'HeadRequestsPersec': 0, + 'ISAPIExtensionRequestsPersec': 0, + 'LockedErrorsPersec': 0, + 'LockRequestsPersec': 0, + 'LogonAttemptsPersec': 0, + 'MaximumAnonymousUsers': 0, + 'MaximumCALcountforauthenticatedusers': 0, + 'MaximumCALcountforSSLconnections': 0, + 'MaximumCGIRequests': 0, + 'MaximumConnections': 0, + 'MaximumISAPIExtensionRequests': 0, + 'MaximumNonAnonymousUsers': 0, + 'MeasuredAsyncIOBandwidthUsage': 0, + 'MkcolRequestsPersec': 0, + 'MoveRequestsPersec': 0, + 'Name': "Default Web Site", + 'NonAnonymousUsersPersec': 0, + 'NotFoundErrorsPersec': 0, + 'OptionsRequestsPersec': 0, + 'OtherRequestMethodsPersec': 0, + 'PostRequestsPersec': 0, + 'PropfindRequestsPersec': 0, + 'ProppatchRequestsPersec': 0, + 'PutRequestsPersec': 0, + 'SearchRequestsPersec': 0, + 'ServiceUptime': 251, + 'TotalAllowedAsyncIORequests': 0, + 'TotalAnonymousUsers': 0, + 'TotalBlockedAsyncIORequests': 0, + 'Totalblockedbandwidthbytes': 0, + 'TotalBytesReceived': "0", + 'TotalBytesSent': "0", + 'TotalBytesTransferred': "0", + 'TotalCGIRequests': 0, + 'TotalConnectionAttemptsallinstances': 0, + 'TotalCopyRequests': 0, + 'TotalcountoffailedCALrequestsforauthenticatedusers': 0, + 'TotalcountoffailedCALrequestsforSSLconnections': 0, + 'TotalDeleteRequests': 0, + 'TotalFilesReceived': 0, + 'TotalFilesSent': 0, + 'TotalFilesTransferred': 0, + 'TotalGetRequests': 0, + 'TotalHeadRequests': 0, + 'TotalISAPIExtensionRequests': 0, + 'TotalLockedErrors': 0, + 'TotalLockRequests': 0, + 'TotalLogonAttempts': 0, + 'TotalMethodRequests': 0, + 'TotalMethodRequestsPersec': 0, + 'TotalMkcolRequests': 0, + 'TotalMoveRequests': 0, + 'TotalNonAnonymousUsers': 0, + 'TotalNotFoundErrors': 0, + 'TotalOptionsRequests': 0, + 'TotalOtherRequestMethods': 0, + 'TotalPostRequests': 0, + 'TotalPropfindRequests': 0, + 'TotalProppatchRequests': 0, + 'TotalPutRequests': 0, + 'TotalRejectedAsyncIORequests': 0, + 'TotalSearchRequests': 0, + 'TotalTraceRequests': 0, + 'TotalUnlockRequests': 0, + 'TraceRequestsPersec': 0, + 'UnlockRequestsPersec': 0, +} + + +class Mocked_Win32_PerfFormattedData_W3SVC_WebService(object): + """ + Generate Mocked instance of Win32_PerfFormattedData_W3SVC_WebService + """ + def __init__(self, **entries): + self.__dict__.update(entries) + + +class Mocked_WMI(Mock): + """ + Mock WMI methods for test purpose + """ + def Win32_PerfFormattedData_W3SVC_WebService(self): + """ + Returns mock match Win32_PerfFormattedData_W3SVC_WebService + """ + return [Mocked_Win32_PerfFormattedData_W3SVC_WebService( + **Win32_PerfFormattedData_W3SVC_WebService_attr)] + + +class IISSTestCase(AgentCheckTest): + CHECK_NAME = 'iis' + + WIN_SERVICES_CONFIG = { + 'host': ".", + 'tags': ["mytag1", "mytag2"], + 'sites': ["Default Web Site", "Failing site"] + } + + def test_check(self): + """ + Returns the right metrics and service checks + """ + # Mocking `wmi` Python package + import sys + sys.modules['wmi'] = Mocked_WMI() + + # Run check + config = { + 'instances': [self.WIN_SERVICES_CONFIG] + } + + self.run_check_twice(config) + + # Test metrics + for mname, _, _ in self.check.METRICS: + self.assertMetric(mname, tags=["mytag1", "mytag2", "site:Default Web Site"], count=1) + + # Test service checks + self.assertServiceCheck('iis.site_up', status=AgentCheck.OK, + tags=["site:Default Web Site"], count=1) + self.assertServiceCheck('iis.site_up', status=AgentCheck.CRITICAL, + tags=["site:Failing site"], count=1) + + self.coverage_report()