Example #1
0
    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
Example #2
0
 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
Example #3
0
 def _BuildHostsChoosePanel(self, simulator):
     """ """
     for p in self.hostChoosePanels:
         p.Destroy()
     self.hostChoosePanels = []
     self.checkBoxInformations = {}
     self.hostCheckBoxes = []
     
     self.hostsBoxSizer.Layout()
     
     hosts = simulator.context.hosts
     hostsIndexes = {} 
     for h in hosts:
         name = h.original_name()
         indexes = name_indexes(h.name)
         index = indexes[0]
         
         if name not in hostsIndexes or index > hostsIndexes[name]:
             hostsIndexes[name] = index
             
     for hostName in hostsIndexes:
         
         panel = wx.Panel(self)
         panelSizer = wx.BoxSizer(wx.HORIZONTAL)
         
         ch = wx.CheckBox(panel, label=hostName, size=(120, 20))
         textCtrl = wx.TextCtrl(panel, size=(200, 20))
         textCtrl.SetValue("0")
         
         rangeLabel = "Available range: 0"
         if hostsIndexes[hostName] > 0:
             rangeLabel += " - %d" % hostsIndexes[hostName] 
         maxLbl = wx.StaticText(panel, label=rangeLabel)
         
         panelSizer.Add(ch, 0, wx.ALL | wx.ALIGN_CENTER)
         panelSizer.Add(wx.StaticText(self), 1, wx.ALL | wx.ALIGN_RIGHT)
         panelSizer.Add(textCtrl, 0, wx.ALL | wx.ALIGN_CENTER)
         panelSizer.Add(maxLbl, 0, wx.ALL | wx.ALIGN_CENTER)
         panel.SetSizer(panelSizer)
         self.hostsBoxSizer.Add(panel, 1, wx.ALL)
         
         self.checkBoxInformations[ch] = (hostName, textCtrl)
         self.hostChoosePanels.append(panel)
         self.hostCheckBoxes.append(ch)
         
     self.hostsBoxSizer.Layout()
     self.Layout()
Example #4
0
    def _GetSelectedHosts(self, simulator):
        """ Returns list of hosts selected by the user """
        def ValidateHostsRange(indexesRange):
            """ """
            return re.match(r'\d(-\d)?(,\d(-\d)?)*', indexesRange)

        def GetIndexesFromRange(indexesRange):
            """ Extracts numbers list of hosts from range text """
            indexes = []
            ranges = indexesRange.split(',')
            for r in ranges:
                parts = r.split('-')
                if len(parts) == 1:
                    indexes.append(int(parts[0]))
                else:
                    for i in range(int(parts[0]), int(parts[1]) + 1):
                        indexes.append(i)
            return indexes

        hosts = []
        for ch in self.hostCheckBoxes:
            if not ch.IsChecked():
                continue
            hostName, hostRangeTextCtrl = self.checkBoxInformations[ch]
            indexesRange = hostRangeTextCtrl.GetValue()
            if not ValidateHostsRange(indexesRange):
                wx.MessageBox(
                    "Range '%s' for host '%s' is invalid. Valid example: 0,12,20-25,30."
                    % (indexesRange, hostName), 'Error', wx.OK | wx.ICON_ERROR)
                break
            else:
                indexes = GetIndexesFromRange(indexesRange)
                for h in simulator.context.hosts:
                    hostIndexes = name_indexes(h.name)
                    if h.original_name(
                    ) == hostName and hostIndexes[0] in indexes:
                        hosts.append(h)
        return hosts
Example #5
0
 def _GetSelectedHosts(self, simulator):
     """ Returns list of hosts selected by user """
     
     def ValidateHostsRange(indexesRange):
         """ """
         return re.match(r'\d(-\d)?(,\d(-\d)?)*', indexesRange)
     
     def GetIndexesFromRange(indexesRange):
         """ Extracts numbers list of hosts from range text """
         indexes = []
         ranges = indexesRange.split(',')
         for r in ranges:
             parts = r.split('-')
             if len(parts) == 1:
                 indexes.append(int(parts[0]))
             else:
                 for i in range(int(parts[0]), int(parts[1])+1):
                     indexes.append(i)
         return indexes
     
     hosts = []
     for ch in self.hostCheckBoxes:
         if not ch.IsChecked():
             continue
         hostName, hostRangeTextCtrl = self.checkBoxInformations[ch]
         indexesRange = hostRangeTextCtrl.GetValue()
         if not ValidateHostsRange(indexesRange):
             wx.MessageBox("Range '%s' for host '%s' is invalid. Valid example: 0,12,20-25,30." 
                           % (indexesRange, hostName), 'Error', wx.OK | wx.ICON_ERROR)
             break
         else:
             indexes = GetIndexesFromRange(indexesRange)
             for h in simulator.context.hosts:
                 hostIndexes = name_indexes(h.name)
                 if h.original_name() == hostName and hostIndexes[0] in indexes:
                     hosts.append(h)
     return hosts
Example #6
0
    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
Example #7
0
 def indexes(self):
     """
     Return name indexes of channel 
     """
     return name_indexes(self.name)