def find_channel(self, name): """ Search for and retuen assigned channel by name (including indexes) """ original_channel_name = original_name(name) indexes = name_indexes(name) if original_channel_name not in self._channels_map: return None channels = self._channels_map[original_channel_name] if len(channels) == 0: return None for ch in channels: # Check if channels has the same original name if ch.original_name() == name: i = 0 #Check if channels have the same indexes ch_indexes = ch.indexes() while i < len(indexes): if indexes[i] != ch_indexes[i]: break i += 1 # If while loop was broken if i < len(indexes): continue else: # All indexes were the same return ch return None
def _predefined_id_function__populate(call_function_expression, host, populator, context=None): existing_host_name = getattr(call_function_expression, '_host_name', None) if existing_host_name is not None: return call_function_expression arguments = call_function_expression.arguments if len(arguments) == 0: expr_host_name = host.name else: expr_host_name = arguments[0].identifier if expr_host_name == original_name(expr_host_name): expr_host_name += ".0" setattr(call_function_expression, '_host_name', expr_host_name) return call_function_expression
def get_or_create_channel(existing_channels, channel_name): """ Get existing channel by name or create new channel. """ # Find repeated channel with indexes by name channel = find_channel(existing_channels, channel_name) # If repeated channel with indexes does not exist if channel is None: # Find first channel (zero indexes) with original name of repeated channel channel = find_channel(existing_channels, original_name(channel_name) + '.0.0') if channel is None: raise EnvironmentDefinitionException("Channel '%s' undefined." % original_name(channel_name)) channel = channel.clone() indexes = name_indexes(channel_name) for i in range(0, len(indexes)): channel.add_name_index(indexes[i]) indexes = name_indexes(channel.name) for i in range(len(indexes), 2): channel.add_name_index(0) existing_channels.append(channel) return channel
def original_name(self): """""" return original_name(self.name)
def _build_metrics_manager(self, store, hosts, version): """ Build and return metrics manager. """ host_metrics = [] for metrics_data in store.metrics_datas: blocks = [] # Build list of metrics blocks for block in metrics_data.blocks: params = block.header.params[1:] service_params = block.header.services_params metrics_block = metrics.Block(params, service_params) for metric in block.metrics: m = metrics.Metric(metric.arguments[0], metric.arguments[1:len(params)+1], metric.arguments[len(params)+1:]) metrics_block.add_metric(m) blocks.append(metrics_block) # get or create host metrics with given name hm = None for existing_hm in host_metrics: if existing_hm.name == metrics_data.name: hm = existing_hm break if hm is None: hm = metrics.HostMetrics(metrics_data.name) host_metrics.append(hm) if metrics_data.plus or metrics_data.star: if metrics_data.plus: hm.plus_blocks = blocks else: # star hm.star_blocks = blocks # If host metrics does not have normal block # Search for them and assign if found in host metrics # with simple name (not qualified like hm1.1) if len(hm.normal_blocks) == 0: hm_original_name = original_name(hm.name) hm_original = None for existing_hm in host_metrics: if original_name(existing_hm.name) == hm_original_name \ and existing_hm != hm: hm_original = existing_hm break if hm_original: hm.normal_blocks = hm_original.normal_blocks else: # metrics_data normal hm_original_name = original_name(hm.name) # Assign normal block to all host metrics with the same original name for existing_hm in host_metrics: if original_name(existing_hm.name) == hm_original_name: # Assign notmal block to all host metrics with the same original name # (including the current one - possibly created) existing_hm.normal_blocks = blocks # Connect host metrics with hosts for metrics_set in version.metrics_sets: for h in hosts: if h.original_name() == metrics_set.host_name: for host_metric in host_metrics: if host_metric.name == metrics_set.configuration_name: host_metric.connected_hosts.append(h) break return metrics.Manager(host_metrics)
def _build_channels(self, store, version, built_hosts): """ Validate, build and return simulation channels build from parsed channels. Includes channel repetitions. """ def find_channel(channels, name): """ Find channel by name. """ for ch in channels: if ch.name == name: return ch return None def find_built_host(built_hosts, name): for h in built_hosts: if h.name == name: return h return None def find_parsed_process(instructions_list, process_name): for instr in instructions_list: if not isinstance(instr, HostProcess): continue if instr.name == process_name: return instr return None def get_or_create_channel(existing_channels, channel_name): """ Get existing channel by name or create new channel. """ # Find repeated channel with indexes by name channel = find_channel(existing_channels, channel_name) # If repeated channel with indexes does not exist if channel is None: # Find first channel (zero indexes) with original name of repeated channel channel = find_channel(existing_channels, original_name(channel_name) + '.0.0') if channel is None: raise EnvironmentDefinitionException("Channel '%s' undefined." % original_name(channel_name)) channel = channel.clone() indexes = name_indexes(channel_name) for i in range(0, len(indexes)): channel.add_name_index(indexes[i]) indexes = name_indexes(channel.name) for i in range(len(indexes), 2): channel.add_name_index(0) existing_channels.append(channel) return channel built_channels = [] original_channels = [] for parsed_channel in store.channels: channel = communication.Channel(parsed_channel.name, parsed_channel.buffor_size) channel.add_name_index(0) channel.add_name_index(0) built_channels.append(channel) original_channels.append(channel) # Hosts numbers dict keeps the last used number of repeated channel for hosts. # For example: # run A(*){5} { ... } - will create channels ch1.1, ch1.2, ch1.3, ch1.4 and ch1.5 # run A(ch1,ch2){2} { ... } - will create channels for next numers which are ch1.6, ch2.6 and ch1.7, ch2.7 hosts_numbers = {} for run_host in version.run_hosts: parsed_host = store.find_host(run_host.host_name) # Load all channels names that host can use # Firstly it is checked in version, secondly in parsed host # List channel_names contains clean channel names (ch1, ch2) channel_names = [] if run_host.all_channels_active: if parsed_host.all_channels_active: channel_names += [ c.original_name() for c in original_channels ] else: channel_names += [ c for c in parsed_host.active_channels ] else: channel_names += [ c for c in run_host.active_channels ] # channel_names - clean names of channels that host can use if parsed_host.name not in hosts_numbers: hosts_numbers[parsed_host.name] = 0 host_first_number = hosts_numbers[parsed_host.name] # HOST-CHANNELS ASSIGNATION # Algorithm: # - For each channel name # - Check if channel is repeated # - Get the name of repeated shannel # - If yes: # - Find channel with repeated name with indexes # - If channel with indexes does not exist: # - Find channel with original name (zero indexes) # - Clone it and add indexes # - Add new channel to built channels # - If no for channel_name in channel_names: # Calculate the name of repeated channel (if it is repeated) # with indexes repeated_name = "" for repeated_channel in run_host.repeated_channels: repeated_channel_basename = original_name(repeated_channel) if channel_name == repeated_channel_basename: indexes = name_indexes(repeated_channel) if len(indexes) > 0: repeated_name = repeated_channel_basename + '.' + str(indexes[0]) + '.0' else: repeated_name += repeated_channel_basename + '.0.0' break # If channel is repeated if repeated_name != "": channel = get_or_create_channel(built_channels, repeated_name) # Assign channel to hosts created on the base of this "run host" for i in range(0, run_host.repetitions): host_number = host_first_number + i host_name = run_host.host_name + '.' + str(host_number) built_host = find_built_host(built_hosts, host_name) built_host.connect_with_channel(channel) else: # Channel is not repeated # New channel is created for each channel name # starting from the lately used number (hosts_numbers) for i in range(0, run_host.repetitions): host_number = host_first_number + i host_name = run_host.host_name + '.' + str(host_number) new_channel_name = channel_name + '.' + str(host_number) + '.0' channel = get_or_create_channel(built_channels, new_channel_name) built_host = find_built_host(built_hosts, host_name) built_host.connect_with_channel(channel) # PROCESS-CHANNEL ASSIGNATION # Update process-channel assignations in each build host # created on the base of this "run host" for i in range(0, run_host.repetitions): # Process numbers dict keeps the last used number of repeated channel for processes. # Works the same like hosts_numbers for hosts. processes_numbers = {} host_number = host_first_number + i host_name = run_host.host_name + '.' + str(host_number) built_host = find_built_host(built_hosts, host_name) parsed_host = store.find_host(built_host.original_name()) instruction_index = 0 for run_process in run_host.run_processes: # Find next process om host's instructions list while instruction_index < len(built_host.instructions_list): if isinstance(built_host.instructions_list[instruction_index], Process): break instruction_index += 1 # If no process found raise exception if instruction_index >= len(built_host.instructions_list): raise EnvironmentDefinitionException("Process '%s' not found in host '%s'." % (run_process.process_name, built_host.name)) if run_process.process_name not in processes_numbers: processes_numbers[run_process.process_name] = 0 # Get number of next channel for this process name process_first_number = processes_numbers[run_process.process_name] # Get process for this "run process" parsed_process = find_parsed_process(parsed_host.instructions_list, run_process.process_name) process_channel_names = [] # Get channel names uded by process if parsed_process.all_channels_active: process_channel_names = channel_names else: for process_channel_name in parsed_process.active_channels: process_channel_names.append(process_channel_name) for process_channel_name in process_channel_names: # Calculate the name of repeated channel (if it is repeated) # with indexes process_channel_repeated_name = "" # Name of repeated channel (may be with indexes) for repeated_channel in run_process.repeated_channels: process_channel_repeated_name_basename = original_name(repeated_channel) if process_channel_name == process_channel_repeated_name_basename: process_channel_repeated_name = repeated_channel # If channel is repeated if process_channel_repeated_name != "": repeated_indexes = name_indexes(process_channel_repeated_name) # If repeated channel is the same, that host is connected with (no indexes) if len(repeated_indexes) == 0: channel = built_host.find_channel(process_channel_repeated_name) # If host does not have channel with this name if channel is None: # Generate channel name for this process ch_name = original_name(process_channel_repeated_name) + '.' +\ str(host_number) + '.' + str(process_first_number) channel = get_or_create_channel(built_channels, ch_name) elif len(repeated_indexes) == 1: # Repeated index is the process index in channels (second index) # # Repeated channel has defined numer of channel from channels of current host # (for different copies of hosts, these are different channels) # For example: Repeated channel name ch1.1 in host A.5 means that all messages # from all copies of process will be sent through channel ch1.x.1 # (where x is the number of channel ch1 in hist A.5 - firstly it would be propably 5) channel = built_host.find_channel(original_name(process_channel_repeated_name)) if channel: # Host has channel with this original name # Lets check if its second index (process index) is the same # with repeated index ch_indexes = channel.indexes() # If channel proces index (2nd) is different from repeated index if ch_indexes[1] != repeated_indexes[0]: ch_name = original_name(process_channel_repeated_name) + '.' +\ str(ch_indexes[0]) + '.' + str(repeated_indexes[0]) channel = get_or_create_channel(built_channels, ch_name) else: # Channel is not connected with host # Generate channel name for this process and host ch_name = original_name(process_channel_repeated_name) + '.' +\ str(host_number) + '.' + str(repeated_indexes[0]) channel = get_or_create_channel(built_channels, ch_name) elif len(repeated_indexes) == 2: ch_name = process_channel_repeated_name channel = get_or_create_channel(built_channels, ch_name) else: raise EnvironmentDefinitionException( 'Invalid repeated channel definition %s in process %s (host %s).'\ % (process_channel_repeated_name, run_process.process_name, built_host.name)) # Connect repeated channel with all repeated processes # Repeated processes are found as list of next instructions in host's instructions list for i in range(0, run_process.repetitions): built_process = built_host.instructions_list[instruction_index+i] if not isinstance(built_process, Process): raise EnvironmentDefinitionException( 'Isntruction nr %d of host %s expected to be process.'\ % (instruction_index+i, built_host.name)) built_process.connect_with_channel(channel) else: # Channel is not repeated current_host_channel_index = host_number # Check if host is connected with any channel of this original name channel = built_host.find_channel(original_name(process_channel_name)) if channel: # Get current host channel index # from the second index of found channel indexes ch_indexes = channel.indexes() current_host_channel_index = ch_indexes[0] for i in range(0, run_process.repetitions): # Generate the channel name for all repetitions process_number = process_first_number + i # Search for channel with generated name or create one ch_name = original_name(process_channel_name) + '.' +\ str(current_host_channel_index) + '.' + str(process_number) channel = get_or_create_channel(built_channels, ch_name) # Connect channel with process built_process = built_host.instructions_list[instruction_index+i] if not isinstance(built_process, Process): raise EnvironmentDefinitionException( 'Isntruction nr %d of host %s expected to be process.'\ % (instruction_index+i, built_host.name)) built_process.connect_with_channel(channel) # Update process numbers dict processes_numbers[run_process.process_name] += run_process.repetitions instruction_index += run_process.repetitions # Update hosts numbers dict hosts_numbers[run_host.host_name] += run_host.repetitions return built_channels
def _build_metrics_manager(self, store, hosts, version): """ Build and return metrics manager. """ host_metrics = [] for metrics_data in store.metrics_datas: blocks = [] # Build list of metrics blocks for block in metrics_data.blocks: params = block.header.params[1:] service_params = block.header.services_params metrics_block = metrics.Block(params, service_params) for metric in block.metrics: m = metrics.Metric(metric.arguments[0], metric.arguments[1:len(params) + 1], metric.arguments[len(params) + 1:]) metrics_block.add_metric(m) blocks.append(metrics_block) # get or create host metrics with given name hm = None for existing_hm in host_metrics: if existing_hm.name == metrics_data.name: hm = existing_hm break if hm is None: hm = metrics.HostMetrics(metrics_data.name) host_metrics.append(hm) if metrics_data.plus or metrics_data.star: if metrics_data.plus: hm.plus_blocks = blocks else: # star hm.star_blocks = blocks # If host metrics does not have normal block # Search for them and assign if found in host metrics # with simple name (not qualified like hm1.1) if len(hm.normal_blocks) == 0: hm_original_name = original_name(hm.name) hm_original = None for existing_hm in host_metrics: if original_name(existing_hm.name) == hm_original_name \ and existing_hm != hm: hm_original = existing_hm break if hm_original: hm.normal_blocks = hm_original.normal_blocks else: # metrics_data normal hm_original_name = original_name(hm.name) # Assign normal block to all host metrics with the same original name for existing_hm in host_metrics: if original_name(existing_hm.name) == hm_original_name: # Assign notmal block to all host metrics with the same original name # (including the current one - possibly created) existing_hm.normal_blocks = blocks # Connect host metrics with hosts for metrics_set in version.metrics_sets: for h in hosts: if h.original_name() == metrics_set.host_name: for host_metric in host_metrics: if host_metric.name == metrics_set.configuration_name: host_metric.connected_hosts.append(h) break return metrics.Manager(host_metrics)
def original_name(self): """ Return original name of channel - without indexes. """ return original_name(self.name)