class TestAgentStatusBuilder(PyonTestCase):

    def setUp(self):
        self.ASB = AgentStatusBuilder(Mock())


    def test_crush_list(self):

        some_values = []
        self.assertEqual(DeviceStatusType.STATUS_UNKNOWN, self.ASB._crush_status_list(some_values))
        def add_and_check(onestatus):
            oldsize = len(some_values)
            some_values.append(onestatus)
            self.assertEqual(oldsize + 1, len(some_values))
            self.assertEqual(onestatus, self.ASB._crush_status_list(some_values))

        # each successive addition here should become the returned status -- they are done in increasing importance
        add_and_check(DeviceStatusType.STATUS_UNKNOWN)
        add_and_check(DeviceStatusType.STATUS_OK)
        add_and_check(DeviceStatusType.STATUS_WARNING)
        add_and_check(DeviceStatusType.STATUS_CRITICAL)

    def test_crush_dict(self):

        statuses = {AggregateStatusType.AGGREGATE_COMMS    : DeviceStatusType.STATUS_CRITICAL,
                    AggregateStatusType.AGGREGATE_POWER    : DeviceStatusType.STATUS_WARNING,
                    AggregateStatusType.AGGREGATE_DATA     : DeviceStatusType.STATUS_OK,
                    AggregateStatusType.AGGREGATE_LOCATION : DeviceStatusType.STATUS_UNKNOWN}

        ret = self.ASB._crush_status_dict(statuses)
        self.assertEqual(DeviceStatusType.STATUS_CRITICAL, ret)


    def test_set_status_computed_attributes(self):
        # set_status_computed_attributes(self, computed_attrs, values_dict=None, availability=None, reason=None)

        container = DotDict()

        log.debug("check null values")
        self.ASB.set_status_computed_attributes_notavailable(container,"this is the reason")

        for attr, enumval in reverse_mapping.iteritems():
            self.assertTrue(hasattr(container, attr))
            attrval = getattr(container, attr)
            self.assertIsInstance(attrval, ComputedIntValue)
            self.assertEqual(ComputedValueAvailability.NOTAVAILABLE, attrval.status)
            self.assertEqual("this is the reason", attrval.reason)

        log.debug("check provided values")

        statuses = {AggregateStatusType.AGGREGATE_COMMS    : DeviceStatusType.STATUS_CRITICAL,
                    AggregateStatusType.AGGREGATE_POWER    : DeviceStatusType.STATUS_WARNING,
                    AggregateStatusType.AGGREGATE_DATA     : DeviceStatusType.STATUS_OK,
                    AggregateStatusType.AGGREGATE_LOCATION : DeviceStatusType.STATUS_UNKNOWN}

        self.ASB.set_status_computed_attributes(container, statuses, ComputedValueAvailability.PROVIDED, "na")



        for attr, enumval in reverse_mapping.iteritems():
            self.assertTrue(hasattr(container, attr))
            attrval = getattr(container, attr)
            self.assertIsInstance(attrval, ComputedIntValue)
            self.assertEqual(ComputedValueAvailability.PROVIDED, attrval.status)
            self.assertEqual(statuses[enumval], attrval.value)


    def test_get_device_agent(self):
        # we expect to fail
        for bad in [None, "0"]:
            handle, reason = self.ASB.get_device_agent(bad)
            self.assertIsNone(handle)
            self.assertEqual(type(""), type("reason"))

        for exn in [Unauthorized, NotFound, AttributeError]:
            def make_exception(*args, **kwargs):
                raise exn()
            self.ASB._get_agent_client = make_exception
            handle, reason = self.ASB.get_device_agent("anything")
            self.assertIsNone(handle)
            self.assertNotEqual("", reason)

        # override resource agent client and try again
        self.ASB._get_agent_client = lambda *args, **kwargs : "happy"

        handle, reason = self.ASB.get_device_agent("anything")
        self.assertEqual("happy", handle)


    def test_compute_status_list(self):

        bad = self.ASB.compute_status_list(None, [1,2,3])
        self.assertIsInstance(bad, ComputedListValue)

        statusd1 = {AggregateStatusType.AGGREGATE_COMMS    : DeviceStatusType.STATUS_CRITICAL,
                    AggregateStatusType.AGGREGATE_POWER    : DeviceStatusType.STATUS_WARNING,
                    AggregateStatusType.AGGREGATE_DATA     : DeviceStatusType.STATUS_OK,
                    AggregateStatusType.AGGREGATE_LOCATION : DeviceStatusType.STATUS_UNKNOWN}

        statusd2 = {AggregateStatusType.AGGREGATE_POWER    : DeviceStatusType.STATUS_WARNING,
                    AggregateStatusType.AGGREGATE_DATA     : DeviceStatusType.STATUS_OK,
                    AggregateStatusType.AGGREGATE_LOCATION : DeviceStatusType.STATUS_UNKNOWN}

        childstatus = {"d1": statusd1, "d2": statusd2}

        ret = self.ASB.compute_status_list(childstatus, ["d1", "d2"])
        self.assertIsInstance(ret, ComputedListValue)
        self.assertEqual(ComputedValueAvailability.PROVIDED, ret.status)
        self.assertEqual([DeviceStatusType.STATUS_CRITICAL, DeviceStatusType.STATUS_WARNING], ret.value)
class TestAgentStatusBuilder(PyonTestCase):
    def setUp(self):
        self.ASB = AgentStatusBuilder(Mock())

    def test_crush_list(self):

        some_values = []
        self.assertEqual(DeviceStatusType.STATUS_UNKNOWN,
                         self.ASB._crush_status_list(some_values))

        def add_and_check(onestatus):
            oldsize = len(some_values)
            some_values.append(onestatus)
            self.assertEqual(oldsize + 1, len(some_values))
            self.assertEqual(onestatus,
                             self.ASB._crush_status_list(some_values))

        # each successive addition here should become the returned status -- they are done in increasing importance
        add_and_check(DeviceStatusType.STATUS_UNKNOWN)
        add_and_check(DeviceStatusType.STATUS_OK)
        add_and_check(DeviceStatusType.STATUS_WARNING)
        add_and_check(DeviceStatusType.STATUS_CRITICAL)

    def test_crush_dict(self):

        statuses = {
            AggregateStatusType.AGGREGATE_COMMS:
            DeviceStatusType.STATUS_CRITICAL,
            AggregateStatusType.AGGREGATE_POWER:
            DeviceStatusType.STATUS_WARNING,
            AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_OK,
            AggregateStatusType.AGGREGATE_LOCATION:
            DeviceStatusType.STATUS_UNKNOWN
        }

        ret = self.ASB._crush_status_dict(statuses)
        self.assertEqual(DeviceStatusType.STATUS_CRITICAL, ret)

    def test_set_status_computed_attributes(self):
        # set_status_computed_attributes(self, computed_attrs, values_dict=None, availability=None, reason=None)

        container = DotDict()

        log.debug("check null values")
        self.ASB.set_status_computed_attributes_notavailable(
            container, "this is the reason")

        for attr, enumval in reverse_mapping.iteritems():
            self.assertTrue(hasattr(container, attr))
            attrval = getattr(container, attr)
            self.assertIsInstance(attrval, ComputedIntValue)
            self.assertEqual(ComputedValueAvailability.NOTAVAILABLE,
                             attrval.status)
            self.assertEqual("this is the reason", attrval.reason)

        log.debug("check provided values")

        statuses = {
            AggregateStatusType.AGGREGATE_COMMS:
            DeviceStatusType.STATUS_CRITICAL,
            AggregateStatusType.AGGREGATE_POWER:
            DeviceStatusType.STATUS_WARNING,
            AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_OK,
            AggregateStatusType.AGGREGATE_LOCATION:
            DeviceStatusType.STATUS_UNKNOWN
        }

        self.ASB.set_status_computed_attributes(
            container, statuses, ComputedValueAvailability.PROVIDED, "na")

        for attr, enumval in reverse_mapping.iteritems():
            self.assertTrue(hasattr(container, attr))
            attrval = getattr(container, attr)
            self.assertIsInstance(attrval, ComputedIntValue)
            self.assertEqual(ComputedValueAvailability.PROVIDED,
                             attrval.status)
            self.assertEqual(statuses[enumval], attrval.value)

    def test_get_device_agent(self):
        # we expect to fail
        for bad in [None, "0"]:
            handle, reason = self.ASB.get_device_agent(bad)
            self.assertIsNone(handle)
            self.assertEqual(type(""), type("reason"))

        for exn in [Unauthorized, NotFound, AttributeError]:

            def make_exception(*args, **kwargs):
                raise exn()

            self.ASB._get_agent_client = make_exception
            handle, reason = self.ASB.get_device_agent("anything")
            self.assertIsNone(handle)
            self.assertNotEqual("", reason)

        # override resource agent client and try again
        self.ASB._get_agent_client = lambda *args, **kwargs: "happy"

        handle, reason = self.ASB.get_device_agent("anything")
        self.assertEqual("happy", handle)

    def test_compute_status_list(self):

        bad = self.ASB.compute_status_list(None, [1, 2, 3])
        self.assertIsInstance(bad, ComputedListValue)

        statusd1 = {
            AggregateStatusType.AGGREGATE_COMMS:
            DeviceStatusType.STATUS_CRITICAL,
            AggregateStatusType.AGGREGATE_POWER:
            DeviceStatusType.STATUS_WARNING,
            AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_OK,
            AggregateStatusType.AGGREGATE_LOCATION:
            DeviceStatusType.STATUS_UNKNOWN
        }

        statusd2 = {
            AggregateStatusType.AGGREGATE_POWER:
            DeviceStatusType.STATUS_WARNING,
            AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_OK,
            AggregateStatusType.AGGREGATE_LOCATION:
            DeviceStatusType.STATUS_UNKNOWN
        }

        childstatus = {"d1": statusd1, "d2": statusd2}

        ret = self.ASB.compute_status_list(childstatus, ["d1", "d2"])
        self.assertIsInstance(ret, ComputedListValue)
        self.assertEqual(ComputedValueAvailability.PROVIDED, ret.status)
        self.assertEqual([
            DeviceStatusType.STATUS_CRITICAL, DeviceStatusType.STATUS_WARNING
        ], ret.value)