# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for Mob* Monitor checkfile manager."""

from __future__ import print_function

import imp
import mock
import os
import subprocess
import time
import threading

from cherrypy.process import plugins
from chromite.lib import cros_test_lib
from chromite.mobmonitor.checkfile import manager

# Test health check and related attributes
class TestHealthCheck(object):
  """Test health check."""

  def Check(self):
    """Stub Check."""
    return 0

  def Diagnose(self, _errcode):
    """Stub Diagnose."""
    return ('Unknown Error.', [])


class TestHealthCheckHasAttributes(object):
  """Test health check with attributes."""

  CHECK_INTERVAL_SEC = 10

  def Check(self):
    """Stub Check."""
    return 0

  def Diagnose(self, _errcode):
    """Stub Diagnose."""
    return ('Unknown Error.', [])


class TestHealthCheckUnhealthy(object):
  """Unhealthy test health check."""

  def __init__(self):
    self.x = -1

  def Check(self):
    """Stub Check."""
    return self.x

  def Diagnose(self, errcode):
    """Stub Diagnose."""
    if errcode == -1:
      return ('Stub Error.', [self.Repair])
    return ('Unknown Error.', [])

  def Repair(self):
    self.x = 0


class TestHealthCheckMultipleActions(object):
  """Unhealthy check with many actions that have different parameters."""

  def __init__(self):
    self.x = -1

  def Check(self):
    """Stub Check."""
    return self.x

  def Diagnose(self, errcode):
    """Stub Diagnose."""
    if errcode == -1:
      return ('Stub Error.', [self.NoParams, self.PositionalParams,
                              self.DefaultParams, self.MixedParams])
    return ('Unknown Error.', [])

  def NoParams(self):
    """NoParams Action."""
    self.x = 0

  # pylint: disable=unused-argument
  def PositionalParams(self, x, y, z):
    """PositionalParams Action."""
    self.x = 0

  def DefaultParams(self, x=1, y=2, z=3):
    """DefaultParams Action."""
    self.x = 0

  def MixedParams(self, x, y, z=1):
    """MixedParams Action."""
    self.x = 0
  # pylint: enable=unused-argument


class TestHealthCheckQuasihealthy(object):
  """Quasi-healthy test health check."""

  def Check(self):
    """Stub Check."""
    return 1

  def Diagnose(self, errcode):
    """Stub Diagnose."""
    if errcode == 1:
      return ('Stub Error.', [self.RepairStub])
    return ('Unknown Error.', [])

  def RepairStub(self):
    """Stub repair action."""


class TestHealthCheckBroken(object):
  """Broken test health check."""

  def Check(self):
    """Stub Check."""
    raise ValueError()

  def Diagnose(self, _errcode):
    """A broken Diagnose function. A proper return should be a pair."""
    raise ValueError()


def TestAction():
  return True


TEST_SERVICE_NAME = 'test-service'
TEST_MTIME = 100
TEST_EXEC_TIME = 400
CHECKDIR = '.'

# Strings that are used to mock actual check modules.
CHECKFILE_MANY_SIMPLE = '''
SERVICE = 'test-service'

class MyHealthCheck2(object):
  def Check(self):
    return 0

  def Diagnose(self, errcode):
    return ('Unknown error.', [])

class MyHealthCheck3(object):
  def Check(self):
    return 0

  def Diagnose(self, errcode):
    return ('Unknown error.', [])

class MyHealthCheck4(object):
  def Check(self):
    return 0

  def Diagnose(self, errcode):
    return ('Unknown error.', [])
'''

CHECKFILE_MANY_SIMPLE_ONE_BAD = '''
SERVICE = 'test-service'

class MyHealthCheck(object):
  def Check(self):
    return 0

  def Diagnose(self, errcode):
    return ('Unknown error.', [])

class NotAHealthCheck(object):
  def Diagnose(self, errcode):
    return ('Unknown error.', [])

class MyHealthCheck2(object):
  def Check(self):
    return 0

  def Diagnose(self, errcode):
    return ('Unknown error.', [])
'''

NOT_A_CHECKFILE = '''
class NotAHealthCheck(object):
  def NotCheckNorDiagnose(self):
    return -1
'''

ANOTHER_NOT_A_CHECKFILE = '''
class AnotherNotAHealthCheck(object):
  def AnotherNotCheckNorDiagnose(self):
    return -2
'''

ACTION_FILE = '''
def TestAction():
  return True

def AnotherAction():
  return False
'''


class RunCommand(threading.Thread):
  """Helper class for executing the Mob* Monitor with a timeout."""

  def __init__(self, cmd, timeout):
    threading.Thread.__init__(self)
    self.cmd = cmd
    self.timeout = timeout
    self.p = None

    self.proc_stdout = None
    self.proc_stderr = None

  def run(self):
    self.p = subprocess.Popen(self.cmd, stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)
    self.proc_stdout, self.proc_stderr = self.p.communicate()

  def Stop(self):
    self.join(self.timeout)

    if self.is_alive():
      self.p.terminate()
      self.join(self.timeout)

      if self.is_alive():
        self.p.kill()
        self.join(self.timeout)

    return self.proc_stdout


class CheckFileManagerHelperTest(cros_test_lib.MockTestCase):
  """Unittests for CheckFileManager helper functions."""

  def testMapHealthcheckStatusToDict(self):
    """Test mapping a manager.HEALTHCHECK_STATUS to a dict."""
    def _func():
      pass

    status = manager.HEALTHCHECK_STATUS('test', False, 'desc', [_func])
    expect = {'name': 'test', 'health': False, 'description': 'desc',
              'actions': ['_func']}
    self.assertEquals(expect, manager.MapHealthcheckStatusToDict(status))

  def testMapServiceStatusToDict(self):
    """Test mapping a manager.SERVICE_STATUS to a dict."""
    def _func():
      pass

    hcstatus = manager.HEALTHCHECK_STATUS('test', False, 'desc', [_func])
    hcexpect = {'name': 'test', 'health': False, 'description': 'desc',
                'actions': ['_func']}
    status = manager.SERVICE_STATUS('test-service', False, [hcstatus])
    expect = {'service': 'test-service', 'health': False,
              'healthchecks': [hcexpect]}
    self.assertEquals(expect, manager.MapServiceStatusToDict(status))

  def testMapActionInfoToDict(self):
    """Test mapping a manager.ACTION_INFO to a dict."""
    actioninfo = manager.ACTION_INFO('test', 'test', [1], {'a': 1})
    expect = {'action': 'test', 'info': 'test', 'args': [1],
              'kwargs': {'a': 1}}
    self.assertEquals(expect, manager.MapActionInfoToDict(actioninfo))

  def testIsHealthcheckHealthy(self):
    """Test checking whether health check statuses are healthy."""
    # Test a healthy health check.
    hch = manager.HEALTHCHECK_STATUS('healthy', True, manager.NULL_DESCRIPTION,
                                     manager.EMPTY_ACTIONS)
    self.assertTrue(manager.isHealthcheckHealthy(hch))

    # Test a quasi-healthy health check.
    hcq = manager.HEALTHCHECK_STATUS('quasi-healthy', True, 'Quasi-Healthy',
                                     ['QuasiAction'])
    self.assertFalse(manager.isHealthcheckHealthy(hcq))

    # Test an unhealthy health check.
    hcu = manager.HEALTHCHECK_STATUS('unhealthy', False, 'Unhealthy',
                                     ['UnhealthyAction'])
    self.assertFalse(manager.isHealthcheckHealthy(hcu))

    # Test an object that is not a health check status.
    s = manager.SERVICE_STATUS('service_status', True, [])
    self.assertFalse(manager.isHealthcheckHealthy(s))

  def testIsServiceHealthy(self):
    """Test checking whether service statuses are healthy."""
    # Define some health check statuses.
    hch = manager.HEALTHCHECK_STATUS('healthy', True, manager.NULL_DESCRIPTION,
                                     manager.EMPTY_ACTIONS)
    hcq = manager.HEALTHCHECK_STATUS('quasi-healthy', True, 'Quasi-Healthy',
                                     ['QuasiAction'])
    hcu = manager.HEALTHCHECK_STATUS('unhealthy', False, 'Unhealthy',
                                     ['UnhealthyAction'])

    # Test a healthy service.
    s = manager.SERVICE_STATUS('healthy', True, [])
    self.assertTrue(manager.isServiceHealthy(s))

    # Test a quasi-healthy service.
    s = manager.SERVICE_STATUS('quasi-healthy', True, [hch, hcq])
    self.assertFalse(manager.isServiceHealthy(s))

    # Test an unhealthy service.
    s = manager.SERVICE_STATUS('unhealthy', False, [hcu])
    self.assertFalse(manager.isServiceHealthy(s))

    # Test an object that is not a service status.
    self.assertFalse(manager.isServiceHealthy(hch))

  def testDetermineHealthcheckStatusHealthy(self):
    """Test DetermineHealthCheckStatus on a healthy check."""
    hcname = TestHealthCheck.__name__
    testhc = TestHealthCheck()
    expected = manager.HEALTHCHECK_STATUS(hcname, True,
                                          manager.NULL_DESCRIPTION,
                                          manager.EMPTY_ACTIONS)
    self.assertEquals(expected,
                      manager.DetermineHealthcheckStatus(hcname, testhc))

  def testDeterminHealthcheckStatusUnhealthy(self):
    """Test DetermineHealthcheckStatus on an unhealthy check."""
    hcname = TestHealthCheckUnhealthy.__name__
    testhc = TestHealthCheckUnhealthy()
    desc, actions = testhc.Diagnose(testhc.Check())
    expected = manager.HEALTHCHECK_STATUS(hcname, False, desc, actions)
    self.assertEquals(expected,
                      manager.DetermineHealthcheckStatus(hcname, testhc))

  def testDetermineHealthcheckStatusQuasihealth(self):
    """Test DetermineHealthcheckStatus on a quasi-healthy check."""
    hcname = TestHealthCheckQuasihealthy.__name__
    testhc = TestHealthCheckQuasihealthy()
    desc, actions = testhc.Diagnose(testhc.Check())
    expected = manager.HEALTHCHECK_STATUS(hcname, True, desc, actions)
    self.assertEquals(expected,
                      manager.DetermineHealthcheckStatus(hcname, testhc))

  def testDetermineHealthcheckStatusBrokenCheck(self):
    """Test DetermineHealthcheckStatus raises on a broken health check."""
    hcname = TestHealthCheckBroken.__name__
    testhc = TestHealthCheckBroken()
    result = manager.DetermineHealthcheckStatus(hcname, testhc)

    self.assertEquals(hcname, result.name)
    self.assertFalse(result.health)
    self.assertFalse(result.actions)

  def testIsHealthCheck(self):
    """Test that IsHealthCheck properly asserts the health check interface."""

    class NoAttrs(object):
      """Test health check missing 'check' and 'diagnose' methods."""

    class NoCheckAttr(object):
      """Test health check missing 'check' method."""
      def Diagnose(self, errcode):
        pass

    class NoDiagnoseAttr(object):
      """Test health check missing 'diagnose' method."""
      def Check(self):
        pass

    class GoodHealthCheck(object):
      """Test health check that implements 'check' and 'diagnose' methods."""
      def Check(self):
        pass

      def Diagnose(self, errcode):
        pass

    self.assertFalse(manager.IsHealthCheck(NoAttrs()))
    self.assertFalse(manager.IsHealthCheck(NoCheckAttr()))
    self.assertFalse(manager.IsHealthCheck(NoDiagnoseAttr()))
    self.assertTrue(manager.IsHealthCheck(GoodHealthCheck()))

  def testApplyHealthCheckAttributesNoAttrs(self):
    """Test that we can apply attributes to a health check."""
    testhc = TestHealthCheck()
    result = manager.ApplyHealthCheckAttributes(testhc)
    self.assertEquals(result.CHECK_INTERVAL_SEC,
                      manager.CHECK_INTERVAL_DEFAULT_SEC)

  def testApplyHealthCheckAttributesHasAttrs(self):
    """Test that we do not override an acceptable attribute."""
    testhc = TestHealthCheckHasAttributes()
    check_interval = testhc.CHECK_INTERVAL_SEC
    result = manager.ApplyHealthCheckAttributes(testhc)
    self.assertEquals(result.CHECK_INTERVAL_SEC, check_interval)

  def testImportFileAllHealthChecks(self):
    """Test that health checks and service name are collected."""
    self.StartPatcher(mock.patch('os.path.splitext'))
    os.path.splitext.return_value = '/path/to/test_check.py'

    self.StartPatcher(mock.patch('os.path.getmtime'))
    os.path.getmtime.return_value = TEST_MTIME

    checkmodule = imp.new_module('test_check')
    exec CHECKFILE_MANY_SIMPLE in checkmodule.__dict__
    self.StartPatcher(mock.patch('imp.load_source'))
    imp.load_source.return_value = checkmodule

    healthchecks, mtime = manager.ImportFile(TEST_SERVICE_NAME, '/')

    self.assertEquals(len(healthchecks), 3)
    self.assertEquals(mtime, TEST_MTIME)

  def testImportFileSomeHealthChecks(self):
    """Test importing when not all classes are actually health checks."""
    self.StartPatcher(mock.patch('os.path.splitext'))
    os.path.splitext.return_value = '/path/to/test_check.py'

    self.StartPatcher(mock.patch('os.path.getmtime'))
    os.path.getmtime.return_value = TEST_MTIME

    checkmodule = imp.new_module('test_check')
    exec CHECKFILE_MANY_SIMPLE_ONE_BAD in checkmodule.__dict__
    self.StartPatcher(mock.patch('imp.load_source'))
    imp.load_source.return_value = checkmodule

    healthchecks, mtime = manager.ImportFile(TEST_SERVICE_NAME, '/')

    self.assertEquals(len(healthchecks), 2)
    self.assertEquals(mtime, TEST_MTIME)


class CheckFileManagerTest(cros_test_lib.MockTestCase):
  """Unittests for CheckFileManager."""

  def testCollectionExecutionCallbackCheckfiles(self):
    """Test the CollectionExecutionCallback on collecting checkfiles."""
    self.StartPatcher(mock.patch('os.walk'))
    os.walk.return_value = iter([[CHECKDIR, [TEST_SERVICE_NAME], []]])

    self.StartPatcher(mock.patch('os.listdir'))
    os.listdir.return_value = ['test_check.py']

    self.StartPatcher(mock.patch('os.path.isfile'))
    os.path.isfile.return_value = True

    self.StartPatcher(mock.patch('imp.find_module'))
    imp.find_module.return_value = (None, None, None)
    self.StartPatcher(mock.patch('imp.load_module'))

    myobj = TestHealthCheck()
    manager.ImportFile = mock.Mock(return_value=[[myobj], TEST_MTIME])
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.CollectionExecutionCallback()

    manager.ImportFile.assert_called_once_with(
        TEST_SERVICE_NAME, './%s/test_check.py' % TEST_SERVICE_NAME)

    self.assertTrue(TEST_SERVICE_NAME in cfm.service_checks)
    self.assertEquals(cfm.service_checks[TEST_SERVICE_NAME],
                      {myobj.__class__.__name__: (TEST_MTIME, myobj)})

  def testCollectionExecutionCallbackNoChecks(self):
    """Test the CollectionExecutionCallback with no valid check files."""
    self.StartPatcher(mock.patch('os.walk'))
    os.walk.return_value = iter([['/checkdir/', [], ['test.py']]])

    manager.ImportFile = mock.Mock(return_value=None)
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.CollectionExecutionCallback()

    self.assertFalse(manager.ImportFile.called)

    self.assertFalse(TEST_SERVICE_NAME in cfm.service_checks)

  def testStartCollectionExecution(self):
    """Test the StartCollectionExecution method."""
    plugins.Monitor = mock.Mock()

    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.StartCollectionExecution()

    self.assertTrue(plugins.Monitor.called)

  def testUpdateExistingHealthCheck(self):
    """Test update when a health check exists and is not stale."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    myobj = TestHealthCheck()

    cfm.service_checks[TEST_SERVICE_NAME] = {myobj.__class__.__name__:
                                             (TEST_MTIME, myobj)}

    myobj2 = TestHealthCheck()
    cfm.Update(TEST_SERVICE_NAME, [myobj2], TEST_MTIME)
    self.assertTrue(TEST_SERVICE_NAME in cfm.service_checks)
    self.assertEquals(cfm.service_checks[TEST_SERVICE_NAME],
                      {myobj.__class__.__name__: (TEST_MTIME, myobj)})

  def testUpdateNonExistingHealthCheck(self):
    """Test adding a new health check to the manager."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.service_checks = {}

    myobj = TestHealthCheck()
    cfm.Update(TEST_SERVICE_NAME, [myobj], TEST_MTIME)

    self.assertTrue(TEST_SERVICE_NAME in cfm.service_checks)
    self.assertEquals(cfm.service_checks[TEST_SERVICE_NAME],
                      {myobj.__class__.__name__: (TEST_MTIME, myobj)})

  def testExecuteFresh(self):
    """Test executing a health check when the result is still fresh."""
    self.StartPatcher(mock.patch('time.time'))
    exec_time_offset = TestHealthCheckHasAttributes.CHECK_INTERVAL_SEC / 2
    time.time.return_value = TEST_EXEC_TIME + exec_time_offset

    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.service_checks = {TEST_SERVICE_NAME:
                          {TestHealthCheckHasAttributes.__name__:
                           (TEST_MTIME, TestHealthCheckHasAttributes())}}
    cfm.service_check_results = {
        TEST_SERVICE_NAME: {TestHealthCheckHasAttributes.__name__:
                            (manager.HCEXECUTION_COMPLETED, TEST_EXEC_TIME,
                             None)}}

    cfm.Execute()

    _, exec_time, _ = cfm.service_check_results[TEST_SERVICE_NAME][
        TestHealthCheckHasAttributes.__name__]

    self.assertEquals(exec_time, TEST_EXEC_TIME)

  def testExecuteStale(self):
    """Test executing a health check when the result is stale."""
    self.StartPatcher(mock.patch('time.time'))
    exec_time_offset = TestHealthCheckHasAttributes.CHECK_INTERVAL_SEC * 2
    time.time.return_value = TEST_EXEC_TIME + exec_time_offset

    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.service_checks = {TEST_SERVICE_NAME:
                          {TestHealthCheckHasAttributes.__name__:
                           (TEST_MTIME, TestHealthCheckHasAttributes())}}
    cfm.service_check_results = {
        TEST_SERVICE_NAME: {TestHealthCheckHasAttributes.__name__:
                            (manager.HCEXECUTION_COMPLETED, TEST_EXEC_TIME,
                             None)}}

    cfm.Execute()

    _, exec_time, _ = cfm.service_check_results[TEST_SERVICE_NAME][
        TestHealthCheckHasAttributes.__name__]

    self.assertEquals(exec_time, TEST_EXEC_TIME + exec_time_offset)

  def testExecuteNonExistent(self):
    """Test executing a health check when the result is nonexistent."""
    self.StartPatcher(mock.patch('time.time'))
    time.time.return_value = TEST_EXEC_TIME

    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.service_checks = {TEST_SERVICE_NAME:
                          {TestHealthCheck.__name__:
                           (TEST_MTIME, TestHealthCheck())}}

    cfm.Execute()

    resultsdict = cfm.service_check_results.get(TEST_SERVICE_NAME)
    self.assertTrue(resultsdict is not None)

    exec_status, exec_time, _ = resultsdict.get(TestHealthCheck.__name__,
                                                (None, None, None))
    self.assertTrue(exec_status is not None)
    self.assertTrue(exec_time is not None)

    self.assertEquals(exec_status, manager.HCEXECUTION_COMPLETED)
    self.assertEquals(exec_time, TEST_EXEC_TIME)

  def testExecuteForce(self):
    """Test executing a health check by ignoring the check interval."""
    self.StartPatcher(mock.patch('time.time'))
    exec_time_offset = TestHealthCheckHasAttributes.CHECK_INTERVAL_SEC / 2
    time.time.return_value = TEST_EXEC_TIME + exec_time_offset

    cfm = manager.CheckFileManager(checkdir=CHECKDIR)
    cfm.service_checks = {TEST_SERVICE_NAME:
                          {TestHealthCheckHasAttributes.__name__:
                           (TEST_MTIME, TestHealthCheckHasAttributes())}}
    cfm.service_check_results = {
        TEST_SERVICE_NAME: {TestHealthCheckHasAttributes.__name__:
                            (manager.HCEXECUTION_COMPLETED, TEST_EXEC_TIME,
                             None)}}

    cfm.Execute(force=True)

    _, exec_time, _ = cfm.service_check_results[TEST_SERVICE_NAME][
        TestHealthCheckHasAttributes.__name__]

    self.assertEquals(exec_time, TEST_EXEC_TIME + exec_time_offset)

  def testConsolidateServiceStatesUnhealthy(self):
    """Test consolidating state for a service with unhealthy checks."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    # Setup some test check results
    hcname = TestHealthCheck.__name__
    statuses = [
        manager.HEALTHCHECK_STATUS(hcname, False, 'Failed', ['Repair']),
        manager.HEALTHCHECK_STATUS(hcname, True, 'Quasi', ['RepairQuasi']),
        manager.HEALTHCHECK_STATUS(hcname, True, '', [])]

    cfm.service_check_results.setdefault(TEST_SERVICE_NAME, {})
    for i, status in enumerate(statuses):
      name = '%s_%s' % (hcname, i)
      cfm.service_check_results[TEST_SERVICE_NAME][name] = (
          manager.HCEXECUTION_COMPLETED, TEST_EXEC_TIME,
          status)

    # Run and check the results.
    cfm.ConsolidateServiceStates()
    self.assertTrue(TEST_SERVICE_NAME in cfm.service_states)

    _, health, healthchecks = cfm.service_states[TEST_SERVICE_NAME]
    self.assertFalse(health)
    self.assertEquals(2, len(healthchecks))
    self.assertTrue(all([x in healthchecks for x in statuses[:2]]))

  def testConsolidateServiceStatesQuasiHealthy(self):
    """Test consolidating state for a service with quasi-healthy checks."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    # Setup some test check results
    hcname = TestHealthCheck.__name__
    statuses = [
        manager.HEALTHCHECK_STATUS(hcname, True, 'Quasi', ['RepairQuasi']),
        manager.HEALTHCHECK_STATUS(hcname, True, '', [])]

    cfm.service_check_results.setdefault(TEST_SERVICE_NAME, {})
    for i, status in enumerate(statuses):
      name = '%s_%s' % (hcname, i)
      cfm.service_check_results[TEST_SERVICE_NAME][name] = (
          manager.HCEXECUTION_COMPLETED, TEST_EXEC_TIME,
          status)

    # Run and check the results.
    cfm.ConsolidateServiceStates()
    self.assertTrue(TEST_SERVICE_NAME in cfm.service_states)

    _, health, healthchecks = cfm.service_states[TEST_SERVICE_NAME]
    self.assertTrue(health)
    self.assertEquals(1, len(healthchecks))
    self.assertTrue(statuses[0] in healthchecks)

  def testConsolidateServiceStatesHealthy(self):
    """Test consolidating state for a healthy service."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    # Setup some test check results
    hcname = TestHealthCheck.__name__
    hcname2 = '%s_2' % hcname
    statuses = [
        manager.HEALTHCHECK_STATUS(hcname, True, '', []),
        manager.HEALTHCHECK_STATUS(hcname2, True, '', [])]

    cfm.service_check_results.setdefault(TEST_SERVICE_NAME, {})
    cfm.service_check_results[TEST_SERVICE_NAME][hcname] = (
        manager.HCEXECUTION_COMPLETED, TEST_EXEC_TIME, statuses[0])
    cfm.service_check_results[TEST_SERVICE_NAME][hcname2] = (
        manager.HCEXECUTION_IN_PROGRESS, TEST_EXEC_TIME, statuses[1])

    # Run and check.
    cfm.ConsolidateServiceStates()

    self.assertTrue(TEST_SERVICE_NAME in cfm.service_states)

    _, health, healthchecks = cfm.service_states.get(TEST_SERVICE_NAME)
    self.assertTrue(health)
    self.assertEquals(0, len(healthchecks))

  def testGetServiceList(self):
    """Test the GetServiceList RPC response."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    self.assertEquals([], cfm.GetServiceList())

    status = manager.SERVICE_STATUS(TEST_SERVICE_NAME, True, [])
    cfm.service_states[TEST_SERVICE_NAME] = status

    self.assertEquals([TEST_SERVICE_NAME], cfm.GetServiceList())

  def testGetStatusNonExistent(self):
    """Test the GetStatus RPC response when the service does not exist."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    self.assertFalse(TEST_SERVICE_NAME in cfm.service_states)

    status = manager.SERVICE_STATUS(TEST_SERVICE_NAME, False, [])
    self.assertEquals(status, cfm.GetStatus(TEST_SERVICE_NAME))

  def testGetStatusSingleService(self):
    """Test the GetStatus RPC response for a single service."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    s1name = TEST_SERVICE_NAME
    s2name = '%s_2' % s1name
    status1 = manager.SERVICE_STATUS(s1name, True, [])
    status2 = manager.SERVICE_STATUS(s2name, True, [])
    cfm.service_states[s1name] = status1
    cfm.service_states[s2name] = status2

    self.assertEquals(status1, cfm.GetStatus(s1name))
    self.assertEquals(status2, cfm.GetStatus(s2name))

  def testGetStatusAllServices(self):
    """Test the GetStatus RPC response when no service is specified."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    s1name = TEST_SERVICE_NAME
    s2name = '%s_2' % s1name
    status1 = manager.SERVICE_STATUS(s1name, True, [])
    status2 = manager.SERVICE_STATUS(s2name, True, [])
    cfm.service_states[s1name] = status1
    cfm.service_states[s2name] = status2

    result = cfm.GetStatus('')
    self.assertEquals(2, len(result))
    self.assertTrue(all([x in result for x in [status1, status2]]))

  def testRepairServiceHealthy(self):
    """Test the RepairService RPC when the service is healthy."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    healthy_status = manager.SERVICE_STATUS(TEST_SERVICE_NAME, True, [])
    cfm.service_states[TEST_SERVICE_NAME] = healthy_status

    self.assertEquals(healthy_status, cfm.RepairService(TEST_SERVICE_NAME,
                                                        'HealthcheckName',
                                                        'RepairFuncName',
                                                        [], {}))

  def testRepairServiceNonExistent(self):
    """Test the RepairService RPC when the service does not exist."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    self.assertFalse(TEST_SERVICE_NAME in cfm.service_states)

    expected = manager.SERVICE_STATUS(TEST_SERVICE_NAME, False, [])
    result = cfm.RepairService(TEST_SERVICE_NAME, 'DummyHealthcheck',
                               'DummyAction', [], {})
    self.assertEquals(expected, result)

  def testRepairServiceInvalidAction(self):
    """Test the RepairService RPC when the action is not recognized."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    hcobj = TestHealthCheckUnhealthy()
    cfm.service_checks[TEST_SERVICE_NAME] = {
        hcobj.__class__.__name__: (TEST_MTIME, hcobj)}

    unhealthy_status = manager.SERVICE_STATUS(
        TEST_SERVICE_NAME, False,
        [manager.HEALTHCHECK_STATUS(hcobj.__class__.__name__,
                                    False, 'Always fails', [hcobj.Repair])])
    cfm.service_states[TEST_SERVICE_NAME] = unhealthy_status

    status = cfm.GetStatus(TEST_SERVICE_NAME)
    self.assertFalse(status.health)
    self.assertEquals(1, len(status.healthchecks))

    status = cfm.RepairService(TEST_SERVICE_NAME, hcobj.__class__.__name__,
                               'Blah', [], {})
    self.assertFalse(status.health)
    self.assertEquals(1, len(status.healthchecks))

  def testRepairServiceInvalidActionArguments(self):
    """Test the RepairService RPC when the action arguments are invalid."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    hcobj = TestHealthCheckUnhealthy()
    cfm.service_checks[TEST_SERVICE_NAME] = {
        hcobj.__class__.__name__: (TEST_MTIME, hcobj)}

    unhealthy_status = manager.SERVICE_STATUS(
        TEST_SERVICE_NAME, False,
        [manager.HEALTHCHECK_STATUS(hcobj.__class__.__name__,
                                    False, 'Always fails', [hcobj.Repair])])
    cfm.service_states[TEST_SERVICE_NAME] = unhealthy_status

    status = cfm.GetStatus(TEST_SERVICE_NAME)
    self.assertFalse(status.health)
    self.assertEquals(1, len(status.healthchecks))

    status = cfm.RepairService(TEST_SERVICE_NAME, hcobj.__class__.__name__,
                               'Repair', [1, 2, 3], {})
    self.assertFalse(status.health)
    self.assertEquals(1, len(status.healthchecks))

  def testRepairService(self):
    """Test the RepairService RPC to repair an unhealthy service."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    hcobj = TestHealthCheckUnhealthy()
    cfm.service_checks[TEST_SERVICE_NAME] = {
        hcobj.__class__.__name__: (TEST_MTIME, hcobj)}

    unhealthy_status = manager.SERVICE_STATUS(
        TEST_SERVICE_NAME, False,
        [manager.HEALTHCHECK_STATUS(hcobj.__class__.__name__,
                                    False, 'Always fails', [hcobj.Repair])])
    cfm.service_states[TEST_SERVICE_NAME] = unhealthy_status

    status = cfm.GetStatus(TEST_SERVICE_NAME)
    self.assertFalse(status.health)
    self.assertEquals(1, len(status.healthchecks))

    status = cfm.RepairService(TEST_SERVICE_NAME,
                               hcobj.__class__.__name__,
                               hcobj.Repair.__name__,
                               [], {})
    self.assertTrue(status.health)
    self.assertEquals(0, len(status.healthchecks))

  def testActionInfoServiceNonExistent(self):
    """Test the ActionInfo RPC when the service does not exist."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    self.assertFalse(TEST_SERVICE_NAME in cfm.service_states)

    expect = manager.ACTION_INFO('test', 'Service not recognized.',
                                 [], {})
    result = cfm.ActionInfo(TEST_SERVICE_NAME, 'test', 'test')
    self.assertEquals(expect, result)

  def testActionInfoServiceHealthy(self):
    """Test the ActionInfo RPC when the service is healthy."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    healthy_status = manager.SERVICE_STATUS(TEST_SERVICE_NAME, True, [])
    cfm.service_states[TEST_SERVICE_NAME] = healthy_status

    expect = manager.ACTION_INFO('test', 'Service is healthy.',
                                 [], {})
    result = cfm.ActionInfo(TEST_SERVICE_NAME, 'test', 'test')
    self.assertEquals(expect, result)

  def testActionInfoActionNonExistent(self):
    """Test the ActionInfo RPC when the action does not exist."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    hcobj = TestHealthCheckUnhealthy()
    cfm.service_checks[TEST_SERVICE_NAME] = {
        hcobj.__class__.__name__: (TEST_MTIME, hcobj)}

    unhealthy_status = manager.SERVICE_STATUS(
        TEST_SERVICE_NAME, False,
        [manager.HEALTHCHECK_STATUS(hcobj.__class__.__name__,
                                    False, 'Always fails', [hcobj.Repair])])
    cfm.service_states[TEST_SERVICE_NAME] = unhealthy_status

    expect = manager.ACTION_INFO('test', 'Action not recognized.', [], {})
    result = cfm.ActionInfo(TEST_SERVICE_NAME, hcobj.__class__.__name__,
                            'test')
    self.assertEquals(expect, result)

  def testActionInfo(self):
    """Test the ActionInfo RPC to collect information on a repair action."""
    cfm = manager.CheckFileManager(checkdir=CHECKDIR)

    hcobj = TestHealthCheckMultipleActions()
    hcname = hcobj.__class__.__name__
    actions = [hcobj.NoParams, hcobj.PositionalParams, hcobj.DefaultParams,
               hcobj.MixedParams]

    cfm.service_checks[TEST_SERVICE_NAME] = {hcname: (TEST_MTIME, hcobj)}

    unhealthy_status = manager.SERVICE_STATUS(
        TEST_SERVICE_NAME, False,
        [manager.HEALTHCHECK_STATUS(hcname, False, 'Always fails', actions)])
    cfm.service_states[TEST_SERVICE_NAME] = unhealthy_status

    # Test ActionInfo when the action has no parameters.
    expect = manager.ACTION_INFO('NoParams', 'NoParams Action.', [], {})
    self.assertEquals(expect,
                      cfm.ActionInfo(TEST_SERVICE_NAME, hcname, 'NoParams'))

    # Test ActionInfo when the action has only positional parameters.
    expect = manager.ACTION_INFO('PositionalParams', 'PositionalParams Action.',
                                 ['x', 'y', 'z'], {})
    self.assertEquals(expect,
                      cfm.ActionInfo(TEST_SERVICE_NAME,
                                     hcname, 'PositionalParams'))

    # Test ActionInfo when the action has only default parameters.
    expect = manager.ACTION_INFO('DefaultParams', 'DefaultParams Action.',
                                 [], {'x': 1, 'y': 2, 'z': 3})
    self.assertEquals(expect,
                      cfm.ActionInfo(TEST_SERVICE_NAME,
                                     hcname, 'DefaultParams'))

    # Test ActionInfo when the action has positional and default parameters.
    expect = manager.ACTION_INFO('MixedParams', 'MixedParams Action.',
                                 ['x', 'y'], {'z': 1})
    self.assertEquals(expect, cfm.ActionInfo(TEST_SERVICE_NAME,
                                             hcname, 'MixedParams'))
