From f13eb8ed49ddbe18afbc31c23dba95a84c81a1a3 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Tue, 25 Jun 2024 15:24:41 +0900 Subject: [PATCH] Add integration tests for heartbeat An integration test is to verify if default configuration of controller disables periodic heartbeat of the controller, and the other is to verify if the node gets disconnected when did not receive heartbeat since threshold from node. Signed-off-by: Joonyoung Shim --- tests/bluechi_test/config.py | 6 +++ .../tier0/bluechi-heartbeat-disabled/main.fmf | 3 ++ .../python/is_node_connected.py | 27 ++++++++++++ .../test_bluechi_heartbeat_disabled.py | 38 +++++++++++++++++ .../main.fmf | 3 ++ .../python/is_node_disconnected.py | 27 ++++++++++++ ...est_bluechi_heartbeat_node_disconnected.py | 41 +++++++++++++++++++ 7 files changed, 145 insertions(+) create mode 100644 tests/tests/tier0/bluechi-heartbeat-disabled/main.fmf create mode 100644 tests/tests/tier0/bluechi-heartbeat-disabled/python/is_node_connected.py create mode 100644 tests/tests/tier0/bluechi-heartbeat-disabled/test_bluechi_heartbeat_disabled.py create mode 100644 tests/tests/tier0/bluechi-heartbeat-node-disconnected/main.fmf create mode 100644 tests/tests/tier0/bluechi-heartbeat-node-disconnected/python/is_node_disconnected.py create mode 100644 tests/tests/tier0/bluechi-heartbeat-node-disconnected/test_bluechi_heartbeat_node_disconnected.py diff --git a/tests/bluechi_test/config.py b/tests/bluechi_test/config.py index e8360b5198..ee5995104d 100644 --- a/tests/bluechi_test/config.py +++ b/tests/bluechi_test/config.py @@ -32,6 +32,8 @@ def __init__( name: str = "bluechi-controller", port: str = "8420", allowed_node_names: List[str] = [], + heartbeat_interval: str = "0", + node_heartbeat_threshold: str = "6000", log_level: str = "DEBUG", log_target: str = "journald", log_is_quiet: bool = False, @@ -41,6 +43,8 @@ def __init__( self.name = name self.port = port self.allowed_node_names = allowed_node_names + self.heartbeat_interval = heartbeat_interval + self.node_heartbeat_threshold = node_heartbeat_threshold self.log_level = log_level self.log_target = log_target self.log_is_quiet = log_is_quiet @@ -53,6 +57,8 @@ def serialize(self) -> str: return f"""[bluechi-controller] ControllerPort={self.port} AllowedNodeNames={allowed_node_names} +HeartbeatInterval={self.heartbeat_interval} +NodeHeartbeatThreshold={self.node_heartbeat_threshold} LogLevel={self.log_level} LogTarget={self.log_target} LogIsQuiet={self.log_is_quiet} diff --git a/tests/tests/tier0/bluechi-heartbeat-disabled/main.fmf b/tests/tests/tier0/bluechi-heartbeat-disabled/main.fmf new file mode 100644 index 0000000000..184c2b40cc --- /dev/null +++ b/tests/tests/tier0/bluechi-heartbeat-disabled/main.fmf @@ -0,0 +1,3 @@ +summary: Test if default configuration of controller disables periodic heartbeat of + the controller +id: a04517f6-8be1-468b-8dc0-f9674690f73f diff --git a/tests/tests/tier0/bluechi-heartbeat-disabled/python/is_node_connected.py b/tests/tests/tier0/bluechi-heartbeat-disabled/python/is_node_connected.py new file mode 100644 index 0000000000..8b16d025d0 --- /dev/null +++ b/tests/tests/tier0/bluechi-heartbeat-disabled/python/is_node_connected.py @@ -0,0 +1,27 @@ +# +# Copyright Contributors to the Eclipse BlueChi project +# +# SPDX-License-Identifier: LGPL-2.1-or-later + +import time +import unittest + +from bluechi.api import Node + + +class TestIsNodeConnected(unittest.TestCase): + def test_is_node_connected(self): + n = Node("node-foo") + assert n.status == "online" + + timestamp = n.last_seen_timestamp + + # verify that the node remains connected and LastSeenTimespamp is not + # updated after more than NodeHeartbeatThreshold seconds have elapsed + time.sleep(6.5) + assert n.status == "online" + assert n.last_seen_timestamp == timestamp + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/tests/tier0/bluechi-heartbeat-disabled/test_bluechi_heartbeat_disabled.py b/tests/tests/tier0/bluechi-heartbeat-disabled/test_bluechi_heartbeat_disabled.py new file mode 100644 index 0000000000..9ab93f1610 --- /dev/null +++ b/tests/tests/tier0/bluechi-heartbeat-disabled/test_bluechi_heartbeat_disabled.py @@ -0,0 +1,38 @@ +# +# Copyright Contributors to the Eclipse BlueChi project +# +# SPDX-License-Identifier: LGPL-2.1-or-later + +import os +from typing import Dict + +from bluechi_test.config import BluechiAgentConfig, BluechiControllerConfig +from bluechi_test.machine import BluechiAgentMachine, BluechiControllerMachine +from bluechi_test.test import BluechiTest + + +def exec(ctrl: BluechiControllerMachine, nodes: Dict[str, BluechiAgentMachine]): + node_foo = nodes["node-foo"] + + result, output = node_foo.run_python(os.path.join("python", "is_node_connected.py")) + if result != 0: + raise Exception(output) + + +def test_bluechi_heartbeat_disabled( + bluechi_test: BluechiTest, + bluechi_ctrl_default_config: BluechiControllerConfig, + bluechi_node_default_config: BluechiAgentConfig, +): + + bluechi_node_default_config.node_name = "node-foo" + bluechi_node_default_config.heartbeat_interval = "0" + + bluechi_ctrl_default_config.allowed_node_names = [ + bluechi_node_default_config.node_name + ] + + bluechi_test.set_bluechi_controller_config(bluechi_ctrl_default_config) + bluechi_test.add_bluechi_agent_config(bluechi_node_default_config) + + bluechi_test.run(exec) diff --git a/tests/tests/tier0/bluechi-heartbeat-node-disconnected/main.fmf b/tests/tests/tier0/bluechi-heartbeat-node-disconnected/main.fmf new file mode 100644 index 0000000000..745433d523 --- /dev/null +++ b/tests/tests/tier0/bluechi-heartbeat-node-disconnected/main.fmf @@ -0,0 +1,3 @@ +summary: Test if the node gets disconnected when did not receive heartbeat since + threshold from node +id: 0b087ba3-25fc-46b0-9c01-31bc2edf5209 diff --git a/tests/tests/tier0/bluechi-heartbeat-node-disconnected/python/is_node_disconnected.py b/tests/tests/tier0/bluechi-heartbeat-node-disconnected/python/is_node_disconnected.py new file mode 100644 index 0000000000..575b0f8fa8 --- /dev/null +++ b/tests/tests/tier0/bluechi-heartbeat-node-disconnected/python/is_node_disconnected.py @@ -0,0 +1,27 @@ +# +# Copyright Contributors to the Eclipse BlueChi project +# +# SPDX-License-Identifier: LGPL-2.1-or-later + +import time +import unittest + +from bluechi.api import Node + + +class TestIsNodeDisconnected(unittest.TestCase): + def test_is_node_disconnected(self): + n = Node("node-foo") + assert n.status == "online" + + timestamp = n.last_seen_timestamp + + # verify that the node is disconnected and LastSeenTimespamp is not + # updated after more than NodeHeartbeatThreshold seconds have elapsed + time.sleep(6.5) + assert n.status == "offline" + assert n.last_seen_timestamp == timestamp + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/tests/tier0/bluechi-heartbeat-node-disconnected/test_bluechi_heartbeat_node_disconnected.py b/tests/tests/tier0/bluechi-heartbeat-node-disconnected/test_bluechi_heartbeat_node_disconnected.py new file mode 100644 index 0000000000..e9351a3c65 --- /dev/null +++ b/tests/tests/tier0/bluechi-heartbeat-node-disconnected/test_bluechi_heartbeat_node_disconnected.py @@ -0,0 +1,41 @@ +# +# Copyright Contributors to the Eclipse BlueChi project +# +# SPDX-License-Identifier: LGPL-2.1-or-later + +import os +from typing import Dict + +from bluechi_test.config import BluechiAgentConfig, BluechiControllerConfig +from bluechi_test.machine import BluechiAgentMachine, BluechiControllerMachine +from bluechi_test.test import BluechiTest + + +def exec(ctrl: BluechiControllerMachine, nodes: Dict[str, BluechiAgentMachine]): + node_foo = nodes["node-foo"] + + result, output = node_foo.run_python( + os.path.join("python", "is_node_disconnected.py") + ) + if result != 0: + raise Exception(output) + + +def test_bluechi_heartbeat_node_disconnected( + bluechi_test: BluechiTest, + bluechi_ctrl_default_config: BluechiControllerConfig, + bluechi_node_default_config: BluechiAgentConfig, +): + + bluechi_node_default_config.node_name = "node-foo" + bluechi_node_default_config.heartbeat_interval = "0" + + bluechi_ctrl_default_config.allowed_node_names = [ + bluechi_node_default_config.node_name + ] + bluechi_ctrl_default_config.heartbeat_interval = "2000" + + bluechi_test.set_bluechi_controller_config(bluechi_ctrl_default_config) + bluechi_test.add_bluechi_agent_config(bluechi_node_default_config) + + bluechi_test.run(exec)