andrijapanicsb commented on code in PR #7170:
URL: https://github.com/apache/cloudstack/pull/7170#discussion_r1133924071
##########
test/integration/smoke/test_host_control_state.py:
##########
@@ -250,3 +255,220 @@ def test_router_host_control_state(self):
self.enable_host(host_id)
self.verify_router_host_control_state(router.id, "Enabled")
+
+
+class TestAutoEnableDisableHost(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.testClient = super(TestAutoEnableDisableHost,
cls).getClsTestClient()
+ cls.apiclient = cls.testClient.getApiClient()
+ cls.services = cls.testClient.getParsedTestDataConfig()
+ # Get Zone, Domain and templates
+ cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
+ cls.hypervisor = cls.testClient.getHypervisorInfo()
+ cls.hostConfig =
cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__
+ if cls.hypervisor.lower() not in ['kvm']:
+ cls.hypervisorNotSupported = True
+ return
+
+ cls.logger = logging.getLogger('TestAutoEnableDisableHost')
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestAutoEnableDisableHost, cls).tearDownClass()
+
+ def tearDown(self):
+ super(TestAutoEnableDisableHost, self).tearDown()
+
+ def get_ssh_client(self, ip, username, password, retries=10):
+ """ Setup ssh client connection and return connection """
+ try:
+ ssh_client = SshClient(ip, 22, username, password, retries)
+ except Exception as e:
+ raise unittest.SkipTest("Unable to create ssh connection: " % e)
+
+ self.assertIsNotNone(
+ ssh_client, "Failed to setup ssh connection to ip=%s" % ip)
+
+ return ssh_client
+
+ def wait_until_host_is_in_state(self, hostid, resourcestate, interval=3,
retries=20):
+ def check_resource_state():
+ response = Host.list(
+ self.apiclient,
+ id=hostid
+ )
+ if isinstance(response, list):
+ if response[0].resourcestate == resourcestate:
+ self.logger.debug('Host with id %s is in resource state =
%s' % (hostid, resourcestate))
+ return True, None
+ else:
+ self.logger.debug("Waiting for host " + hostid +
+ " to reach state " + resourcestate +
+ ", with current state " +
response[0].resourcestate)
+ return False, None
+
+ done, _ = wait_until(interval, retries, check_resource_state)
+ if not done:
+ raise Exception("Failed to wait for host %s to be on resource
state %s" % (hostid, resourcestate))
+ return True
+
+ def update_config(self, enable_feature):
+ cmd = updateConfiguration.updateConfigurationCmd()
+ cmd.name = "enable.kvm.host.auto.enable.disable"
+ cmd.value = enable_feature
+
+ response = self.apiclient.updateConfiguration(cmd)
+ self.debug("updated the parameter %s with value %s" % (response.name,
response.value))
+
+ def update_health_check_script(self, ip_address, username, password,
exit_code):
+ health_check_script_path = "/etc/cloudstack/agent/healthcheck.sh"
+ health_check_agent_property = "agent.health.check.script.path"
+ agent_properties_file_path = "/etc/cloudstack/agent/agent.properties"
+
+ ssh_client = self.get_ssh_client(ip_address, username, password)
+ ssh_client.execute("echo 'exit %s' > %s" % (exit_code,
health_check_script_path))
+ ssh_client.execute("chmod +x %s" % health_check_script_path)
+ ssh_client.execute("echo '%s=%s' >> %s" %
(health_check_agent_property, health_check_script_path,
+ agent_properties_file_path))
+ ssh_client.execute("service cloudstack-agent restart")
+
+ def remove_host_health_check(self, ip_address, username, password):
+ health_check_script_path = "/etc/cloudstack/agent/healthcheck.sh"
+ ssh_client = self.get_ssh_client(ip_address, username, password)
+ ssh_client.execute("rm -f %s" % health_check_script_path)
+
+ def select_host_for_health_checks(self):
+ clusters = list_clusters(
+ self.apiclient,
+ zoneid=self.zone.id
+ )
+ if not clusters:
+ return None
+
+ for cluster in clusters:
+ list_hosts_response = list_hosts(
+ self.apiclient,
+ clusterid=cluster.id,
+ type="Routing",
+ resourcestate="Enabled"
+ )
+ assert isinstance(list_hosts_response, list)
+ if not list_hosts_response or len(list_hosts_response) < 1:
+ continue
+ return list_hosts_response[0]
+ return None
+
+ def update_host_allocation_state(self, id, enable):
+ cmd = updateHost.updateHostCmd()
+ cmd.id = id
+ cmd.allocationstate = "Enable" if enable else "Disable"
+ response = self.apiclient.updateHost(cmd)
+ self.assertEqual(response.resourcestate, "Enabled" if enable else
"Disabled")
+
+ @attr(tags=["basic", "advanced"], required_hardware="false")
+ @skipTestIf("hypervisorNotSupported")
+ def test_01_auto_enable_disable_kvm_host(self):
+ """Test to auto-enable and auto-disable a KVM host based on health
check results
+
+ # Validate the following:
+ # 1. Enable the KVM Auto Enable/Disable Feature
+ # 2. Set a health check script that fails and observe the host is
Disabled
+ # 3. Make the health check script succeed and observe the host is
Enabled
+ """
+
+ selected_host = self.select_host_for_health_checks()
+ if not selected_host:
+ self.skipTest("Cannot find a KVM host to test the
auto-enable-disable feature")
+
+ username = self.hostConfig["username"]
+ password = self.hostConfig["password"]
+
+ # Enable the Auto Enable/Disable Configuration
+ self.update_config("true")
+
+ # Set health check script for failure
+ self.update_health_check_script(selected_host.ipaddress, username,
password, 1)
+ self.wait_until_host_is_in_state(selected_host.id, "Disabled", 5, 200)
+
+ # Set health check script for success
+ self.update_health_check_script(selected_host.ipaddress, username,
password, 0)
+
+ self.wait_until_host_is_in_state(selected_host.id, "Enabled", 5, 200)
+
+ @attr(tags=["basic", "advanced"], required_hardware="false")
+ @skipTestIf("hypervisorNotSupported")
+ def test_02_disable_host_overrides_auto_enable_kvm_host(self):
+ """Test to override the auto-enabling of a KVM host by an administrator
+
+ # Validate the following:
+ # 1. Enable the KVM Auto Enable/Disable Feature
+ # 2. Set a health check script that succeeds and observe the host is
Enabled
+ # 3. Make the host Disabled
+ # 4. Verify the host does not get auto-enabled after the previous step
+ """
+
+ selected_host = self.select_host_for_health_checks()
+ if not selected_host:
+ self.skipTest("Cannot find a KVM host to test the
auto-enable-disable feature")
+
+ username = self.hostConfig["username"]
+ password = self.hostConfig["password"]
+
+ # Enable the Auto Enable/Disable Configuration
+ self.update_config("true")
+
+ # Set health check script for failure
+ self.update_health_check_script(selected_host.ipaddress, username,
password, 0)
+ self.wait_until_host_is_in_state(selected_host.id, "Enabled", 5, 200)
+
+ # Manually disable the host
+ self.update_host_allocation_state(selected_host.id, False)
+
+ # Wait for more than the ping interval
+ time.sleep(70)
+
+ # Verify the host continues on Disabled state
+ self.wait_until_host_is_in_state(selected_host.id, "Disabled", 5, 200)
+
+ # Restore the host to Enabled state
+ self.remove_host_health_check(selected_host.ipaddress, username,
password)
+ self.update_host_allocation_state(selected_host.id, True)
+
+ @attr(tags=["basic", "advanced"], required_hardware="false")
+ @skipTestIf("hypervisorNotSupported")
+ def test_03_enable_host_does_not_override_auto_disable_kvm_host(self):
+ """Test to override the auto-disabling of a KVM host by an
administrator
+
+ # Validate the following:
+ # 1. Enable the KVM Auto Enable/Disable Feature
+ # 2. Set a health check script that fails and observe the host is
Disabled
+ # 3. Make the host Enabled
+ # 4. Verify the host does not get auto-disabled after the previous step
Review Comment:
This is not per the specs - if the host is manually enabled (by admin), and
the health script still returns false/failure - then the host should be
disabled again.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]