Tempest plugin for os-win project.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_cluster.py 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # Copyright 2017 Cloudbase Solutions SRL
  2. # All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. import time
  16. from oslo_log import log as logging
  17. from tempest.lib import exceptions as lib_exc
  18. from oswin_tempest_plugin.clients import wsman
  19. from oswin_tempest_plugin import config
  20. from oswin_tempest_plugin import exceptions
  21. from oswin_tempest_plugin.tests._mixins import migrate
  22. from oswin_tempest_plugin.tests._mixins import resize
  23. from oswin_tempest_plugin.tests import test_base
  24. CONF = config.CONF
  25. LOG = logging.getLogger(__name__)
  26. class HyperVClusterTest(migrate._MigrateMixin,
  27. migrate._LiveMigrateMixin,
  28. resize._ResizeMixin,
  29. test_base.TestBase):
  30. """The test suite for the Hyper-V Cluster.
  31. This test suite will test the functionality of the Hyper-V Cluster Driver
  32. in OpenStack. The tests will force a failover on its newly created
  33. instance, and asserts the following:
  34. * the instance moves to another host.
  35. * the nova instance's host is properly updated.
  36. * the instance's network connection still works.
  37. * different nova operations can be performed properly.
  38. This test suite relies on the fact that there are at least 2 compute nodes
  39. available, that they are clustered, and have WSMan configured.
  40. The test suite contains the following tests:
  41. * test_check_clustered_vm
  42. * test_check_migration
  43. * test_check_resize
  44. * test_check_resize_negative
  45. """
  46. _BIGGER_FLAVOR = {'disk': 1}
  47. @classmethod
  48. def skip_checks(cls):
  49. super(HyperVClusterTest, cls).skip_checks()
  50. # check if the cluster Tests can be run.
  51. if not CONF.hyperv.cluster_enabled:
  52. msg = 'Hyper-V cluster tests are disabled.'
  53. raise cls.skipException(msg)
  54. if not CONF.hyperv_host_auth.username:
  55. msg = ('No Hyper-V host username has been provided. '
  56. 'Skipping cluster tests.')
  57. raise cls.skipException(msg)
  58. if not CONF.compute.min_compute_nodes >= 2:
  59. msg = 'Expected at least 2 compute nodes.'
  60. raise cls.skipException(msg)
  61. def _failover_server(self, server_name, host_ip):
  62. """Triggers the failover for the given server on the given host."""
  63. resource_name = "Virtual Machine %s" % server_name
  64. cmd = "Test-ClusterResourceFailure -Name '%s'" % resource_name
  65. # NOTE(claudiub): we issue the failover command twice, because on
  66. # the first failure, the Hyper-V Cluster will prefer the current
  67. # node, and will try to reactivate the VM on the it, and it will
  68. # succeed. On the 2nd failure, the VM will failover to another
  69. # node. Also, there needs to be a delay between commands, so the
  70. # original failover has time to finish.
  71. wsman.run_hv_host_wsman_ps(host_ip, cmd)
  72. time.sleep(CONF.hyperv.failover_sleep_interval)
  73. wsman.run_hv_host_wsman_ps(host_ip, cmd)
  74. def _wait_for_failover(self, server, original_host):
  75. """Waits for the given server to failover to another host.
  76. :raises TimeoutException: if the given server did not failover to
  77. another host within the configured "CONF.hyperv.failover_timeout"
  78. interval.
  79. """
  80. LOG.debug('Waiting for server %(server)s to failover from '
  81. 'compute node %(host)s',
  82. dict(server=server['id'], host=original_host))
  83. start_time = int(time.time())
  84. timeout = CONF.hyperv.failover_timeout
  85. while True:
  86. elapsed_time = int(time.time()) - start_time
  87. admin_server = self._get_server_as_admin(server)
  88. current_host = admin_server['OS-EXT-SRV-ATTR:host']
  89. if current_host != original_host:
  90. LOG.debug('Server %(server)s failovered from compute node '
  91. '%(host)s in %(seconds)s seconds.',
  92. dict(server=server['id'], host=original_host,
  93. seconds=elapsed_time))
  94. return
  95. if elapsed_time >= timeout:
  96. msg = ('Server %(server)s did not failover in the given '
  97. 'amount of time (%(timeout)s s).')
  98. raise lib_exc.TimeoutException(
  99. msg % dict(server=server['id'], timeout=timeout))
  100. time.sleep(CONF.hyperv.failover_sleep_interval)
  101. def _get_hypervisor(self, hostname):
  102. hypervisors = self.admin_hypervisor_client.list_hypervisors(
  103. detail=True)['hypervisors']
  104. hypervisor = [h for h in hypervisors if
  105. h['hypervisor_hostname'] == hostname]
  106. if not hypervisor:
  107. raise exceptions.NotFoundException(resource=hostname,
  108. res_type='hypervisor')
  109. return hypervisor[0]
  110. def _create_server(self, flavor=None):
  111. server_tuple = super(HyperVClusterTest, self)._create_server(flavor)
  112. server = server_tuple.server
  113. admin_server = self._get_server_as_admin(server)
  114. server_name = admin_server['OS-EXT-SRV-ATTR:instance_name']
  115. hostname = admin_server['OS-EXT-SRV-ATTR:host']
  116. host_ip = self._get_hypervisor(hostname)['host_ip']
  117. self._failover_server(server_name, host_ip)
  118. self._wait_for_failover(server, hostname)
  119. return server_tuple
  120. def test_clustered_vm(self):
  121. server_tuple = self._create_server()
  122. self._check_server_connectivity(server_tuple)