def test_weighted_sum_single_function(self): fn_tuples = [(1.0, offset), ] hostinfo_list = self.zone_manager.get_all_host_data(None).items() # host1: free_ram_mb=0 # host2: free_ram_mb=1536 # host3: free_ram_mb=3072 # host4: free_ram_mb=8192 # [offset, ]= # [10000, 11536, 13072, 18192] # so, host1 should win: options = {} weighted_host = least_cost.weighted_sum(fn_tuples, hostinfo_list, options) self.assertEqual(weighted_host.weight, 10000) self.assertEqual(weighted_host.host, 'host1')
def test_weighted_sum_single_function(self): fn_tuples = [ (1.0, offset), ] hostinfo_list = self.zone_manager.get_all_host_data(None).items() # host1: free_ram_mb=0 # host2: free_ram_mb=1536 # host3: free_ram_mb=3072 # host4: free_ram_mb=8192 # [offset, ]= # [10000, 11536, 13072, 18192] # so, host1 should win: options = {} weighted_host = least_cost.weighted_sum(fn_tuples, hostinfo_list, options) self.assertEqual(weighted_host.weight, 10000) self.assertEqual(weighted_host.host, 'host1')
def test_weighted_sum_happy_day(self): fn_tuples = [(1.0, offset), (1.0, scale)] hostinfo_list = self.zone_manager.get_all_host_data(None).items() # host1: free_ram_mb=0 # host2: free_ram_mb=1536 # host3: free_ram_mb=3072 # host4: free_ram_mb=8192 # [offset, scale]= # [10000, 11536, 13072, 18192] # [0, 768, 1536, 4096] # adjusted [ 1.0 * x + 1.0 * y] = # [10000, 12304, 14608, 22288] # so, host1 should win: options = {} weighted_host = least_cost.weighted_sum(fn_tuples, hostinfo_list, options) self.assertEqual(weighted_host.weight, 10000) self.assertEqual(weighted_host.host, 'host1')
def _schedule(self, elevated, topic, request_spec, *args, **kwargs): """Returns a list of hosts that meet the required specs, ordered by their fitness. """ if topic != "compute": msg = _("Scheduler only understands Compute nodes (for now)") raise NotImplementedError(msg) instance_type = request_spec.get("instance_type", None) if not instance_type: msg = _("Scheduler only understands InstanceType-based" \ "provisioning.") raise NotImplementedError(msg) cost_functions = self.get_cost_functions() ram_requirement_mb = instance_type['memory_mb'] disk_requirement_gb = instance_type['local_gb'] options = self._get_configuration_options() # Find our local list of acceptable hosts by repeatedly # filtering and weighing our options. Each time we choose a # host, we virtually consume resources on it so subsequent # selections can adjust accordingly. # unfiltered_hosts_dict is {host : ZoneManager.HostInfo()} unfiltered_hosts_dict = self.zone_manager.get_all_host_data(elevated) unfiltered_hosts = unfiltered_hosts_dict.items() num_instances = request_spec.get('num_instances', 1) selected_hosts = [] for num in xrange(num_instances): # Filter local hosts based on requirements ... filtered_hosts = self._filter_hosts(topic, request_spec, unfiltered_hosts, options) if not filtered_hosts: # Can't get any more locally. break LOG.debug(_("Filtered %(filtered_hosts)s") % locals()) # weighted_host = WeightedHost() ... the best # host for the job. weighted_host = least_cost.weighted_sum(cost_functions, filtered_hosts, options) LOG.debug(_("Weighted %(weighted_host)s") % locals()) selected_hosts.append(weighted_host) # Now consume the resources so the filter/weights # will change for the next instance. weighted_host.hostinfo.consume_resources(disk_requirement_gb, ram_requirement_mb) # Next, tack on the host weights from the child zones if not request_spec.get('local_zone', False): json_spec = json.dumps(request_spec) all_zones = self._zone_get_all(elevated) child_results = self._call_zone_method(elevated, "select", specs=json_spec, zones=all_zones) selected_hosts.extend(self._adjust_child_weights( child_results, all_zones)) selected_hosts.sort(key=operator.attrgetter('weight')) return selected_hosts[:num_instances]
def _schedule(self, elevated, topic, request_spec, *args, **kwargs): """Returns a list of hosts that meet the required specs, ordered by their fitness. """ if topic != "compute": msg = _("Scheduler only understands Compute nodes (for now)") raise NotImplementedError(msg) instance_type = request_spec.get("instance_type", None) if not instance_type: msg = _("Scheduler only understands InstanceType-based" \ "provisioning.") raise NotImplementedError(msg) cost_functions = self.get_cost_functions() ram_requirement_mb = instance_type['memory_mb'] disk_requirement_gb = instance_type['local_gb'] options = self._get_configuration_options() # Find our local list of acceptable hosts by repeatedly # filtering and weighing our options. Each time we choose a # host, we virtually consume resources on it so subsequent # selections can adjust accordingly. # unfiltered_hosts_dict is {host : ZoneManager.HostInfo()} unfiltered_hosts_dict = self.zone_manager.get_all_host_data(elevated) unfiltered_hosts = unfiltered_hosts_dict.items() num_instances = request_spec.get('num_instances', 1) selected_hosts = [] for num in xrange(num_instances): # Filter local hosts based on requirements ... filtered_hosts = self._filter_hosts(topic, request_spec, unfiltered_hosts, options) if not filtered_hosts: # Can't get any more locally. break LOG.debug(_("Filtered %(filtered_hosts)s") % locals()) # weighted_host = WeightedHost() ... the best # host for the job. weighted_host = least_cost.weighted_sum(cost_functions, filtered_hosts, options) LOG.debug(_("Weighted %(weighted_host)s") % locals()) selected_hosts.append(weighted_host) # Now consume the resources so the filter/weights # will change for the next instance. weighted_host.hostinfo.consume_resources(disk_requirement_gb, ram_requirement_mb) # Next, tack on the host weights from the child zones if not request_spec.get('local_zone', False): json_spec = json.dumps(request_spec) all_zones = self._zone_get_all(elevated) child_results = self._call_zone_method(elevated, "select", specs=json_spec, zones=all_zones) selected_hosts.extend( self._adjust_child_weights(child_results, all_zones)) selected_hosts.sort(key=operator.attrgetter('weight')) return selected_hosts[:num_instances]