RIFT OSM R1 Initial Submission
[osm/SO.git] / rwmon / test / utest_rwmon.py
diff --git a/rwmon/test/utest_rwmon.py b/rwmon/test/utest_rwmon.py
new file mode 100644 (file)
index 0000000..83356c0
--- /dev/null
@@ -0,0 +1,258 @@
+#!/usr/bin/env python3
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import os
+import unittest
+import xmlrunner
+
+import rw_peas
+
+import gi
+gi.require_version("RwcalYang", "1.0")
+gi.require_version("RwMon", "1.0")
+gi.require_version("RwmonYang", "1.0")
+gi.require_version("RwTypes", "1.0")
+
+
+from gi.repository import (
+        RwmonYang,
+        RwcalYang,
+        RwTypes,
+        )
+
+
+class TestNullDataSource(unittest.TestCase):
+    def setUp(self):
+        plugin = rw_peas.PeasPlugin("rwmon_mock", 'RwMon-1.0')
+        self.plugin = plugin.get_interface("Monitoring")
+
+        self.account = RwcalYang.CloudAccount()
+        self.vim_id = "test-vim-id"
+
+    def test_null_data_source(self):
+        """
+        By default, the NFVI metrics plugin mock installs a 'null'
+        implementation that simply returns empty NFVI structures.
+
+        """
+        status, metrics = self.plugin.nfvi_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics, RwmonYang.NfviMetrics())
+
+        status, metrics = self.plugin.nfvi_vcpu_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics, RwmonYang.NfviMetrics_Vcpu())
+
+        status, metrics = self.plugin.nfvi_memory_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics, RwmonYang.NfviMetrics_Memory())
+
+        status, metrics = self.plugin.nfvi_storage_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics, RwmonYang.NfviMetrics_Storage())
+
+        status, result = self.plugin.nfvi_metrics_available(self.account)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertTrue(result)
+
+
+class TestMockDataSource(unittest.TestCase):
+    def setUp(self):
+        plugin = rw_peas.PeasPlugin("rwmon_mock", 'RwMon-1.0')
+        self.plugin = plugin.get_interface("Monitoring")
+        self.plugin.set_impl(MockDataSource())
+
+        self.account = RwcalYang.CloudAccount()
+        self.vim_id = "test-vim-id"
+
+    def test_mock_data_source(self):
+        """
+        This test installs a mock data source implementation in the plugin,
+        which returns known values. This test simply checks the expected values
+        are indeed returned.
+
+        """
+        expected_vcpu_metrics = RwmonYang.NfviMetrics_Vcpu()
+        expected_vcpu_metrics.utilization = 50.0
+        expected_vcpu_metrics.total = 100
+
+        status, metrics = self.plugin.nfvi_vcpu_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics.total, expected_vcpu_metrics.total)
+        self.assertEqual(metrics.utilization, expected_vcpu_metrics.utilization)
+
+        expected_memory_metrics = RwmonYang.NfviMetrics_Memory()
+        expected_memory_metrics.used = 90
+        expected_memory_metrics.total = 100
+        expected_memory_metrics.utilization = 90/100
+
+        status, metrics = self.plugin.nfvi_memory_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics.used, expected_memory_metrics.used)
+        self.assertEqual(metrics.total, expected_memory_metrics.total)
+        self.assertEqual(metrics.utilization, expected_memory_metrics.utilization)
+
+        expected_storage_metrics = RwmonYang.NfviMetrics_Storage()
+        expected_storage_metrics.used = 300
+        expected_storage_metrics.total = 500
+        expected_storage_metrics.utilization = 300/500
+
+        status, metrics = self.plugin.nfvi_storage_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics.used, expected_storage_metrics.used)
+        self.assertEqual(metrics.total, expected_storage_metrics.total)
+        self.assertEqual(metrics.utilization, expected_storage_metrics.utilization)
+
+        status, metrics = self.plugin.nfvi_metrics(self.account, self.vim_id)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertEqual(metrics.vcpu.total, expected_vcpu_metrics.total)
+        self.assertEqual(metrics.vcpu.utilization, expected_vcpu_metrics.utilization)
+        self.assertEqual(metrics.storage.used, expected_storage_metrics.used)
+        self.assertEqual(metrics.storage.total, expected_storage_metrics.total)
+        self.assertEqual(metrics.storage.utilization, expected_storage_metrics.utilization)
+        self.assertEqual(metrics.memory.used, expected_memory_metrics.used)
+        self.assertEqual(metrics.memory.total, expected_memory_metrics.total)
+        self.assertEqual(metrics.memory.utilization, expected_memory_metrics.utilization)
+
+        status, result = self.plugin.nfvi_metrics_available(self.account)
+        self.assertEqual(status, RwTypes.RwStatus.SUCCESS)
+        self.assertTrue(result)
+
+
+class TestMockAlarms(unittest.TestCase):
+    def setUp(self):
+        plugin = rw_peas.PeasPlugin("rwmon_mock", 'RwMon-1.0')
+
+        self.mock = MockAlarmInterface()
+        self.plugin = plugin.get_interface("Monitoring")
+        self.plugin.set_impl(self.mock)
+
+        self.account = RwcalYang.CloudAccount()
+        self.alarm = RwmonYang.Alarm(name='test-alarm')
+        self.vim_id = 'test-vim-id'
+
+    def test(self):
+        """
+        This test uses a simple, mock implementation of the alarm interface to
+        check that create, update, delete, and list work correctly.
+
+        """
+        # In the beginning, there were no alarms
+        _, alarms = self.plugin.do_alarm_list(self.account)
+        self.assertEqual(0, len(alarms))
+
+        # Create two alarms
+        self.plugin.do_alarm_create(self.account, self.vim_id, RwmonYang.Alarm())
+        self.plugin.do_alarm_create(self.account, self.vim_id, RwmonYang.Alarm())
+
+        _, alarms = self.plugin.do_alarm_list(self.account)
+        self.assertEqual(2, len(alarms))
+
+        # The alarms should have no names
+        alarms.sort(key=lambda a: a.alarm_id)
+        self.assertEqual('test-alarm-id-1', alarms[0].alarm_id)
+        self.assertEqual('test-alarm-id-2', alarms[1].alarm_id)
+        self.assertTrue(all(a.name is None for a in alarms))
+
+        # Give names to the alarms
+        alarms[0].name = 'test-alarm'
+        alarms[1].name = 'test-alarm'
+        self.plugin.do_alarm_update(self.account, alarms[0])
+        self.plugin.do_alarm_update(self.account, alarms[1])
+        self.assertTrue(all(a.name == 'test-alarm' for a in alarms))
+
+        # Delete the alarms
+        self.plugin.do_alarm_delete(self.account, alarms[0].alarm_id)
+        self.plugin.do_alarm_delete(self.account, alarms[1].alarm_id)
+        _, alarms = self.plugin.do_alarm_list(self.account)
+        self.assertEqual(0, len(alarms))
+
+
+class MockAlarmInterface(object):
+    """
+    This class is mock impementation for the alarm interface on the monitoring
+    plugin.
+    """
+
+    def __init__(self):
+        self.count = 0
+        self.alarms = dict()
+
+    def alarm_create(self, account, vim_id, alarm):
+        self.count += 1
+        alarm_id = 'test-alarm-id-{}'.format(self.count)
+        alarm.alarm_id = alarm_id
+        self.alarms[alarm_id] = alarm
+
+    def alarm_update(self, account, alarm):
+        assert alarm.alarm_id is not None
+        self.alarms[alarm.alarm_id] = alarm
+
+    def alarm_delete(self, account, alarm_id):
+        del self.alarms[alarm_id]
+
+    def alarm_list(self, account):
+        return list(self.alarms.values())
+
+
+class MockDataSource(object):
+    """
+    This class implements the data source interface used by the monitoring
+    plugin and provides mock data for testing.
+    """
+
+    def nfvi_metrics(self, account, vm_id):
+        metrics = RwmonYang.NfviMetrics()
+        metrics.vcpu = self.nfvi_vcpu_metrics(account, vm_id)
+        metrics.memory = self.nfvi_memory_metrics(account, vm_id)
+        metrics.storage = self.nfvi_storage_metrics(account, vm_id)
+        return metrics
+
+    def nfvi_vcpu_metrics(self, account, vm_id):
+        metrics = RwmonYang.NfviMetrics_Vcpu()
+        metrics.total = 100
+        metrics.utilization = 50.0
+        return metrics
+
+    def nfvi_memory_metrics(self, account, vm_id):
+        metrics = RwmonYang.NfviMetrics_Memory()
+        metrics.used = 90
+        metrics.total = 100
+        metrics.utilization = 90/100
+        return metrics
+
+    def nfvi_storage_metrics(self, account, vm_id):
+        metrics = RwmonYang.NfviMetrics_Storage()
+        metrics.used = 300
+        metrics.total = 500
+        metrics.utilization = 300/500
+        return metrics
+
+    def nfvi_metrics_available(self, account):
+        return True
+
+
+def main():
+    runner = xmlrunner.XMLTestRunner(output=os.environ["RIFT_MODULE_TEST"])
+    unittest.main(testRunner=runner)
+
+
+if __name__ == '__main__':
+    main()
+
+# vim: sw=4