diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:48:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:48:59 +0000 |
commit | d835b2cae8abc71958b69362162e6a70c3d7ef63 (patch) | |
tree | 81052e3d2ce3e1bcda085f73d925e9d6257dec15 /test/unittests/test_ratrace.py | |
parent | Initial commit. (diff) | |
download | crmsh-upstream.tar.xz crmsh-upstream.zip |
Adding upstream version 4.6.0.upstream/4.6.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/unittests/test_ratrace.py')
-rw-r--r-- | test/unittests/test_ratrace.py | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/test/unittests/test_ratrace.py b/test/unittests/test_ratrace.py new file mode 100644 index 0000000..6734b89 --- /dev/null +++ b/test/unittests/test_ratrace.py @@ -0,0 +1,131 @@ +import unittest +from lxml import etree +try: + from unittest import mock +except ImportError: + import mock +from crmsh import cibconfig +from crmsh.ui_context import Context +from crmsh.ui_resource import RscMgmt +from crmsh.ui_root import Root + + +class TestRATrace(unittest.TestCase): + """Unit tests for enabling/disabling RA tracing.""" + + context = Context(Root()) + factory = cibconfig.cib_factory + + def setUp(self): + self.factory._push_state() + + def tearDown(self): + self.factory._pop_state() + + @mock.patch('logging.Logger.error') + def test_ratrace_resource(self, mock_error): + """Check setting RA tracing for a resource.""" + xml = '''<primitive class="ocf" id="r1" provider="pacemaker" type="Dummy"/>''' + obj = self.factory.create_from_node(etree.fromstring(xml)) + + # Trace the resource. + RscMgmt()._trace_resource(self.context, obj.obj_id, obj, '/var/lib/heartbeat/trace_ra') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-start-0', 'r1-stop-0']) + self.assertEqual(obj.node.xpath('operations/op[@id="r1-start-0"]/instance_attributes/nvpair[@name="trace_ra"]/@value'), ['1']) + self.assertEqual(obj.node.xpath('operations/op[@id="r1-stop-0"]/instance_attributes/nvpair[@name="trace_ra"]/@value'), ['1']) + + # Untrace the resource. + RscMgmt()._untrace_resource(self.context, obj.obj_id, obj) + self.assertEqual(obj.node.xpath('operations/op/@id'), []) + self.assertEqual(obj.node.xpath('.//*[@name="trace_ra"]'), []) + + @mock.patch('logging.Logger.error') + def test_ratrace_op(self, mock_error): + """Check setting RA tracing for a specific operation.""" + xml = '''<primitive class="ocf" id="r1" provider="pacemaker" type="Dummy"> + <operations> + <op id="r1-monitor-10" interval="10" name="monitor"/> + </operations> + </primitive>''' + obj = self.factory.create_from_node(etree.fromstring(xml)) + + # Trace the operation. + RscMgmt()._trace_op(self.context, obj.obj_id, obj, 'monitor', '/var/lib/heartbeat/trace_ra') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-monitor-10']) + self.assertEqual(obj.node.xpath('operations/op[@id="r1-monitor-10"]/instance_attributes/nvpair[@name="trace_ra"]/@value'), ['1']) + + # Untrace the operation. + RscMgmt()._untrace_op(self.context, obj.obj_id, obj, 'monitor') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-monitor-10']) + self.assertEqual(obj.node.xpath('.//*[@name="trace_ra"]'), []) + + # Try untracing a non-existent operation. + with self.assertRaises(ValueError) as err: + RscMgmt()._untrace_op(self.context, obj.obj_id, obj, 'invalid-op') + self.assertEqual(str(err.exception), "Operation invalid-op not found in r1") + + @mock.patch('logging.Logger.error') + def test_ratrace_new(self, mock_error): + """Check setting RA tracing for an operation that is not in CIB.""" + xml = '''<primitive class="ocf" id="r1" provider="pacemaker" type="Dummy"> + </primitive>''' + obj = self.factory.create_from_node(etree.fromstring(xml)) + + # Trace a regular operation that is not yet defined in CIB. The request + # should succeed and introduce an op node for the operation. + RscMgmt()._trace_op(self.context, obj.obj_id, obj, 'start', '/var/lib/heartbeat/trace_ra') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-start-0']) + self.assertEqual(obj.node.xpath('operations/op[@id="r1-start-0"]/instance_attributes/nvpair[@name="trace_ra"]/@value'), ['1']) + + # Try tracing the monitor operation in the same way. The request should + # get rejected because no explicit interval is specified. + with self.assertRaises(ValueError) as err: + RscMgmt()._trace_op(self.context, obj.obj_id, obj, 'monitor', '/var/lib/heartbeat/trace_ra') + self.assertEqual(str(err.exception), "No monitor operation configured for r1") + + @mock.patch('logging.Logger.error') + def test_ratrace_op_stateful(self, mock_error): + """Check setting RA tracing for an operation on a stateful resource.""" + xml = '''<primitive class="ocf" id="r1" provider="pacemaker" type="Dummy"> + <operations> + <op id="r1-monitor-10" interval="10" name="monitor" role="Master"/> + <op id="r1-monitor-11" interval="11" name="monitor" role="Slave"/> + </operations> + </primitive>''' + obj = self.factory.create_from_node(etree.fromstring(xml)) + + # Trace the operation. + RscMgmt()._trace_op(self.context, obj.obj_id, obj, 'monitor', '/var/lib/heartbeat/trace_ra') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-monitor-10', 'r1-monitor-11']) + self.assertEqual(obj.node.xpath('operations/op[@id="r1-monitor-10"]/instance_attributes/nvpair[@name="trace_ra"]/@value'), ['1']) + self.assertEqual(obj.node.xpath('operations/op[@id="r1-monitor-11"]/instance_attributes/nvpair[@name="trace_ra"]/@value'), ['1']) + + # Untrace the operation. + RscMgmt()._untrace_op(self.context, obj.obj_id, obj, 'monitor') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-monitor-10', 'r1-monitor-11']) + self.assertEqual(obj.node.xpath('.//*[@name="trace_ra"]'), []) + + @mock.patch('logging.Logger.error') + def test_ratrace_op_interval(self, mock_error): + """Check setting RA tracing for an operation+interval.""" + xml = '''<primitive class="ocf" id="r1" provider="pacemaker" type="Dummy"> + <operations> + <op id="r1-monitor-10" interval="10" name="monitor"/> + </operations> + </primitive>''' + obj = self.factory.create_from_node(etree.fromstring(xml)) + + # Trace the operation. + RscMgmt()._trace_op_interval(self.context, obj.obj_id, obj, 'monitor', '10', '/var/lib/heartbeat/trace_ra') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-monitor-10']) + self.assertEqual(obj.node.xpath('operations/op[@id="r1-monitor-10"]/instance_attributes/nvpair[@name="trace_ra"]/@value'), ['1']) + + # Untrace the operation. + RscMgmt()._untrace_op_interval(self.context, obj.obj_id, obj, 'monitor', '10') + self.assertEqual(obj.node.xpath('operations/op/@id'), ['r1-monitor-10']) + self.assertEqual(obj.node.xpath('.//*[@name="trace_ra"]'), []) + + # Try untracing a non-existent operation. + with self.assertRaises(ValueError) as err: + RscMgmt()._untrace_op_interval(self.context, obj.obj_id, obj, 'invalid-op', '10') + self.assertEqual(str(err.exception), "Operation invalid-op with interval 10 not found in r1") |