def _start_agents(self, agent_host, agent_ports): """Start agents on different ports. When agents register sequentially, the order of events of onHostAdded is not guaranteed. For example, if agent A, B then C register, they wont be inserted into the hierarchy in that order, a possible order can be B, A then C. Thus, we wait on hosts that we think will own a leaf scheduler before registering more agents that will go under the same leaf. """ agent_ids = [] for ind in xrange(len(agent_ports)): config = self.runtime.get_agent_config(agent_host, agent_ports[ind], self.chairman_host, self.chairman_port) res = self.runtime.start_agent(config) agent_client = res[1] config_req = THost.GetConfigRequest() config = agent_client.get_host_config(config_req).hostConfig agent_id = config.agent_id if ind % self.leaf_fanout == 0: self.wait_for_registration(agent_id) agent_ids.append(agent_id) return agent_ids
def test_host_config_after_provision(self): """ Test if the agent returns the correct HostConfig after being provisioned """ host_config_request = Host.GetConfigRequest() res = self.host_client.get_host_config(host_config_request) self.assertEqual(res.result, GetConfigResultCode.OK) hostConfig = res.hostConfig datastores = [ds.name for ds in hostConfig.datastores] containsDs = [ ds for ds in self.get_all_datastores() if ds in datastores ] self.assertEqual(containsDs, self.get_all_datastores()) networks = [net.id for net in hostConfig.networks] self.assertEqual(networks, self.vim_client.get_networks()) self.assertEqual(hostConfig.address, ServerAddress(host=self.server, port=8835)) self.assertTrue(hostConfig.management_only) # get_host_config reports datastore id for image datastore even if it # was provisioned with a datastore name. image_datastore_name = self.get_image_datastore() image_datastore_id = None for ds in hostConfig.datastores: if ds.name == image_datastore_name: image_datastore_id = ds.id self.assertEqual( list(hostConfig.image_datastore_ids)[0], image_datastore_id)
def test_get_root_scheduler(self): """Test root scheduler introspection""" (root_host, root_port) = get_service_leader(self.zk_client, ROOT_SCHEDULER_SERVICE) # Verify that an empty root scheduler is constructed # correctly root_sch = get_root_scheduler(root_host, root_port) assert_that(root_sch.id, is_(ROOT_SCHEDULER_ID)) assert_that(root_sch.type, is_(ROOT_SCHEDULER_TYPE)) assert_that(len(root_sch.children), is_(0)) assert_that(root_sch.owner, not_none()) root_owner = root_sch.owner assert_that(root_owner.id, is_(ROOT_SCHEDULER_ID)) assert_that(root_owner.address, is_(root_host)) assert_that(root_owner.port, is_(root_port)) assert_that(root_owner.parent, is_(None)) # Start an agent agent_host = 'localhost' agent_port = 20000 config = self.runtime.get_agent_config(agent_host, agent_port, self.chairman_host, self.chairman_port) res = self.runtime.start_agent(config) agent_client = res[1] # Wait for the root scheduler to be configured _wait_for_configuration(self.root_sch_client, 1) new_root_sch = get_root_scheduler(root_host, root_port) assert_that(len(new_root_sch.children), is_(1)) req = THost.GetConfigRequest() agent_id = agent_client.get_host_config(req).hostConfig.agent_id leaf = new_root_sch.children.values()[0] assert_that(leaf.type, is_(LEAF_SCHEDULER_TYPE)) assert_that(leaf.parent, is_(new_root_sch)) assert_that(len(leaf.children), is_(0)) assert_that(leaf.owner.id, is_(agent_id)) assert_that(leaf.owner.address, is_(agent_host)) assert_that(leaf.owner.port, is_(agent_port)) assert_that(leaf.owner.parent, is_(leaf)) deleted = threading.Event() def _deleted(children): if not children: deleted.set() self.zk_client.ChildrenWatch(ROOT_SCHEDULER_SERVICE, _deleted) stop_service(self.runtime.root_procs[0]) # Wait for the leader to leave deleted.wait(30) emoty_root = get_root_scheduler(root_host, root_port) assert_that(emoty_root, is_(emoty_root))
def _validate_post_boostrap_config(self, req): """ Validates that the post boostrap config is the same as the one we had requested for. """ host_config_request = Host.GetConfigRequest() res = self.host_client.get_host_config(host_config_request) # XXX Fix me the host config should return more useful info datastores = req.datastores self.assertEqual([ds.name for ds in res.hostConfig.datastores], datastores)
def _validate_post_boostrap_config(self, req): """ Validates that the post boostrap config is the same as the one we had requested for. """ host_config_request = Host.GetConfigRequest() res = self.host_client.get_host_config(host_config_request) # XXX Fix me the host config should return more useful info avail_zone = req.availability_zone self.assertEqual(res.hostConfig.availability_zone, avail_zone)
def _find_configured_datastore_in_host_config(self): config_request = Host.GetConfigRequest() config_response = self.host_client.get_host_config(config_request) assert_that(config_response.hostConfig.datastores, not_none()) assert_that(config_response.hostConfig.datastores, is_not(empty())) logger.debug("Configured test image datastore %s" % self.get_image_datastore()) for datastore_item in config_response.hostConfig.datastores: if datastore_item.name == self.get_image_datastore(): return datastore_item self.fail("datastore list returned by agent does not contain %s" % self.get_image_datastore())
def configure_host(self): config_req = Host.GetConfigRequest() host_config = self.host_client.get_host_config(config_req).hostConfig leaf_scheduler = SchedulerRole(stable_uuid("leaf scheduler")) leaf_scheduler.parent_id = stable_uuid("parent scheduler") leaf_scheduler.hosts = [host_config.agent_id] config_request = ConfigureRequest(stable_uuid("leaf scheduler"), Roles([leaf_scheduler])) self.host_client.configure(config_request)
def test_management_only_parse(self): # Default option for management_only is False request = Host.GetConfigRequest() response = self.host_client.get_host_config(request) assert_that(response.result, equal_to(Host.GetConfigResultCode.OK)) assert_that(response.hostConfig.management_only, equal_to(False)) # Restart agent with --management-only option, test the flag is set # to True self.runtime.stop_agent(self.proc) new_config = self.config.copy() new_config["--management-only"] = None res = self.runtime.start_agent(new_config) self.proc, self.host_client, self.control_client = res request = Host.GetConfigRequest() response = self.host_client.get_host_config(request) assert_that(response.result, equal_to(Host.GetConfigResultCode.OK)) assert_that(response.hostConfig.management_only, equal_to(True))
def test_get_leaf_scheduler(self): """Test agent introspection""" agent_host = 'localhost' agent_port = 20000 # Agent not online leaf = get_leaf_scheduler(agent_host, agent_port) assert_that(leaf, is_(None)) # Start an agent with an invalid chairman, so that it doesn't # get configured, because we want to configure it manually config = self.runtime.get_agent_config(agent_host, agent_port, "localhost", 24234) res = self.runtime.start_agent(config) agent_client = res[1] # Agent is online but not a leaf scheduler leaf = get_leaf_scheduler(agent_host, agent_port) assert_that(leaf, is_(None)) leafId1 = stable_uuid("leaf scheduler") config_req = THost.GetConfigRequest() host_config = agent_client.get_host_config(config_req).hostConfig leaf_scheduler = SchedulerRole(leafId1) leaf_scheduler.parent_id = stable_uuid("parent scheduler") leaf_scheduler.hosts = [host_config.agent_id] leaf_scheduler.host_children = [ ChildInfo(id=host_config.agent_id, address=agent_host, port=agent_port) ] config_request = ConfigureRequest(leafId1, Roles([leaf_scheduler])) resp = agent_client.configure(config_request) assert_that(resp.result, is_(ConfigureResultCode.OK)) leaf = get_leaf_scheduler(agent_host, agent_port) assert_that(leaf.id, not_none()) assert_that(leaf.type, is_(LEAF_SCHEDULER_TYPE)) assert_that(len(leaf.children), is_(1)) # Verify the owner host owner_host = leaf.owner assert_that(owner_host, not_none()) assert_that(owner_host.id, is_(host_config.agent_id)) assert_that(owner_host.address, is_(agent_host)) assert_that(owner_host.port, is_(agent_port)) assert_that(owner_host.parent, is_(leaf))
def test_provision_without_datastores(self): """ Test that the host uses all the datastores when it gets provisioned without any datastores specified. """ # provision the host without datastores datastores = self.get_all_datastores() self.provision_hosts(datastores=[], image_ds=datastores[0]) # verify that the host configuration contains all the datastores. req = Host.GetConfigRequest() res = self.create_client().get_host_config(req) self.assertEqual(len(res.hostConfig.datastores), len(self.vim_client.get_all_datastores()))
def test_get_host_config(self): """Test that the agent responds with Host configuration""" request = Host.GetConfigRequest() response = self.host_client.get_host_config(request) assert_that(response.hostConfig.agent_id, matches_regexp("[0-9a-f-]{36}")) datastores = response.hostConfig.datastores assert_that(datastores, has_length(len(self.get_all_datastores()))) for datastore in datastores: assert_that(self.get_all_datastores(), has_item(datastore.name)) assert_that(datastore.type, not_none()) self._validate_datastore_id(datastores[0].id) assert_that(response.hostConfig.networks, not_none()) vm_networks = [network for network in response.hostConfig.networks if NetworkType.VM in network.types] assert_that(len(vm_networks), greater_than_or_equal_to(1))
def test_place_on_datastore_tag(self): host_config_request = Host.GetConfigRequest() res = self.host_client.get_host_config(host_config_request) self.assertEqual(res.result, GetConfigResultCode.OK) datastores = res.hostConfig.datastores for datastore in datastores: tag = self._type_to_tag(datastore.type) if not tag: continue vm_wrapper = VmWrapper(self.host_client) # Test place disks with only datastore constraint disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], []) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints) # Test place disks with datastore and datastore tag constraint disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], [tag]) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints, expect=PlaceResultCode.OK) # Test place disks with the wrong datastore tag for other_tag in self._other_tags(tag): disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], [other_tag]) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints, expect=PlaceResultCode.NO_SUCH_RESOURCE)
def test_datastore_parse(self): """Test that the agent parses datastore args""" self.runtime.stop_agent(self.proc) new_config = self.config.copy() new_config["--datastores"] = " ds1,ds2, ds3, ds4 " res = self.runtime.start_agent(new_config) self.proc, self.host_client, self.control_client = res request = Host.GetConfigRequest() response = self.host_client.get_host_config(request) datastore_ids = [ds.id for ds in response.hostConfig.datastores] expected_ids = [ str(uuid.uuid5(uuid.NAMESPACE_DNS, name)) for name in ["ds1", "ds2", "ds3", "ds4"] ] assert_that(datastore_ids, equal_to(expected_ids))
def test_demote_agent_from_leaf_scheduler(self): request = GetSchedulersRequest() response = self.control_client.get_schedulers(request) # Agent starts without any schedulers assert_that(len(response.schedulers), is_(0)) # Configure the agent with a leaf scheduler leafId1 = stable_uuid("leaf scheduler") config_req = Host.GetConfigRequest() host_config = self.client.get_host_config(config_req).hostConfig leaf_scheduler = SchedulerRole(leafId1) leaf_scheduler.parent_id = stable_uuid("parent scheduler") leaf_scheduler.hosts = [host_config.agent_id] leaf_scheduler.host_children = [ChildInfo(id=host_config.agent_id, address="localhost", port=8835)] config_request = ConfigureRequest( leafId1, Roles([leaf_scheduler])) self.client.configure(config_request) request = GetSchedulersRequest() response = self.control_client.get_schedulers(request) # Verify that the agent has been configured assert_that(len(response.schedulers), is_(1)) assert_that(response.schedulers[0].role.id, is_(leafId1)) # Demote agent from leaf scheduler config_request = ConfigureRequest( leafId1, Roles([])) self.client.configure(config_request) # Verify that the agent isn't a scheduler request = GetSchedulersRequest() response = self.control_client.get_schedulers(request) assert_that(len(response.schedulers), is_(0))
def _get_agent_id(self): host_config_request = Host.GetConfigRequest() res = self.host_client.get_host_config(host_config_request) return res.hostConfig.agent_id