Exemplo n.º 1
0
 def _replaceChoiceBlocks(self, muleTagList : TagList) -> TagList:
     if not isinstance(muleTagList, TagList):
         raise TypeError('Invalid parameter passed to MuleLines _replaceChoiceBlocks')
     inChoiceBlock = False
     
     for pair in muleTagList.pairs():
         # Determine the edges of the choice block, and remove everything in between.
         if pair.getTag() == 'choice':
             inChoiceBlock = True
             
         elif pair.getTag() == '/choice':
             inChoiceBlock = False
             pair.setTag('choicePlaceholder')
             
         if inChoiceBlock:
             muleTagList.remove(pair)
             
     return muleTagList
    def __init__(self, name):
        originalName = name

        # Simply popping the last tag as a group name wouldn't work because of P2P release with multiple dashes in it:
        # Let Me In 2010 DVDRIP READNFO XViD-T0XiC-iNK

        self.Group = ""

        name = name.lower()
        name = name.replace(".", " ")
        name = name.strip()

        # Check if there is a group name in the release name.
        if name.rfind('-') == -1 or name.endswith("-"):
            self.Tags = TagList(name.split(" "))
        else:
            name = name.replace("-", " ")
            name = name.strip()
            self.Tags = TagList(name.split(" "))
            if self.__HandleSpecialGroupName(["d", "z0n3"]):
                pass
            elif self.__HandleSpecialGroupName(["t0xic", "ink"]):
                pass
            elif self.__HandleSpecialGroupName(["vh", "prod"]):
                pass
            elif name.endswith(
                    " h 264"
            ):  # For release names without group names. E.g.: Critters.1986.720p.WEB-DL.AAC2.0.H.264
                pass
            else:
                self.Group = self.Tags.List.pop()

        if len(self.Tags.List) <= 0:
            raise PtpUploaderException(
                "Release name '%s' doesn't contain any tags." % originalName)

        # This is not perfect (eg.: The Legend of 1900), but it doesn't matter if the real year will be included in the tags.
        self.TagsAfterYear = TagList([])
        for i in range(len(self.Tags.List)):
            if re.match(r"\d\d\d\d", self.Tags.List[i]):
                self.TagsAfterYear.List = self.Tags.List[i + 1:]
                break

        self.Scene = self.Group in Settings.SceneReleaserGroup
Exemplo n.º 3
0
 def _generateMUnitTestFlows(self, choiceOperations : [], mUnitBaseTagList : TagList) -> []:
     if not isinstance(choiceOperations, list) or not isinstance(mUnitBaseTagList, TagList):
         raise TypeError('Invalid parameter types passed to MuleLines _generateMUnitTestFlows')
     outputFlows = []
     
     # Create a flow for each choice operation. (Later support should include multiple operations)
     for choiceTagList in choiceOperations:
         mUnitCopy = mUnitBaseTagList.copy()
         pair = mUnitCopy.getPair('choicePlaceholder')
         pairIndex = mUnitCopy.index(pair)
         
         for choicePair in choiceTagList.pairs():
             pairIndex += 1  # Increment index for each pair to maintain correct order
             mUnitCopy.insertAtIndex(pairIndex, choicePair)
         outputFlows.append(mUnitCopy)    
          
     return outputFlows
Exemplo n.º 4
0
 def _extractChoiceOperations(self, flowTagList : TagList) -> []:
     if not isinstance(flowTagList, TagList):
         raise TypeError('Invalid parameter type passed to MuleLines _extractChoiceOperations')
     
     choiceOperations = []
     caseOperations = TagList()
     inChoiceClause = False
     for pair in flowTagList.pairs():
         if pair.getTag() == 'when' or pair.getTag() == 'otherwise':
             inChoiceClause = True
             
         elif pair.getTag() == '/when' or pair.getTag() == '/otherwise':
             inChoiceClause = False
             choiceOperations.append(caseOperations.copy())
             caseOperations.clear()
             
         elif inChoiceClause:
             caseOperations.append(pair)
             
     return choiceOperations
Exemplo n.º 5
0
 def _isolateFlows(self) -> []:
     flows = []
     inFlow = False
     flowList = TagList()
     
     for pair in self._muleTagList.pairs():
         # If within a flow or sub-flow block, add the pair to the outputList
         if pair.getTag() == 'flow' or pair.getTag() == 'sub-flow':
             inFlow = True
             flowList.append(pair)
             
         elif pair.getTag() == '/flow' or pair.getTag() == '/sub-flow':
             flowList.append(pair)
             flows.append(flowList.copy())
             flowList.clear()  # Clear the flowList to handle next flow
             inFlow = False
             
         elif inFlow:
             flowList.append(pair)
             
     return flows
Exemplo n.º 6
0
 def __init__(self):
     self._inputFileName = ""
     self._muleFileLines = []
     self._muleTagList = TagList()
     self._mUnitTagList = TagList()
Exemplo n.º 7
0
    def _convertMuletoMUnit(self, muleFlowTagList : TagList) -> TagList:
        if not isinstance(muleFlowTagList, TagList):
            raise TypeError('Invalid parameter passed to MuleLines _convertMuletoMUnit')
        self._replaceChoiceBlocks(muleFlowTagList)  # Replace choice blocks with choicePlaceholder
        
        # Values used for tracking info throughout the method
        muleFlowName = ""
        mUnitTagList = TagList()
        afterChoiceBlock = True  # Used to determine certain tag types
        flowContainsDatabase = False  # Used to create before and after flows for DB mocking
        flowContainsFTP = False
        
        # Define generic OrderedDicts for commonly used tag attributes
        noAttributes = OrderedDict({'closeAtEnd': False})
        mockReturn = OrderedDict({'closeAtEnd': False, 'payload': '#[]'})
        mockAttribute = OrderedDict({'closeAtEnd': True, 'name': 'name'})
        mockWhen = OrderedDict({'closeAtEnd': False, 'doc:name': 'Mock'})
                
        # Iterate through the Mule XML tags and attributes to create MUnit tags and attributes.
        if muleFlowTagList.containsTag('choicePlaceholder'):
            afterChoiceBlock = False

        # Check if a DB connector is in the flow
        if (muleFlowTagList.containsTag('db:select') or muleFlowTagList.containsTag('db:insert') or
             muleFlowTagList.containsTag('db:update') or muleFlowTagList.containsTag('db:delete') or 
             muleFlowTagList.containsTag('db:stored-procedure') or muleFlowTagList.containsTag('db:bulk-execute')
             or muleFlowTagList.containsTag('db:execute-ddl')):
            
            flowContainsDatabase = True
            
            # Create before suite block to start a DB mock
            beforeAttributes = OrderedDict({'closeAtEnd': False, 'name': 'before-DB',
                                            'description': 'Start DB Server'})
            mUnitTagList.append(TagPair('munit:before-suite', beforeAttributes))
            
            startAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': '', 'doc:name': 'Start DB'})
            mUnitTagList.append(TagPair('dbserver:start-db-server', startAttributes))
            mUnitTagList.append(TagPair('/munit:before-suite', noAttributes))
            
        # Check if FTP connector is in the flow
        if muleFlowTagList.containsTag('ftp:outbound-endpoint'):
            flowContainsFTP = True
            
            # Add FTP before-suite block to start an FTP mock
            beforeAttributes = OrderedDict({'closeAtEnd': False, 'name': 'before-FTP',
                                            'description': 'Start DB Server'})
            mUnitTagList.append(TagPair('munit:before-suite', beforeAttributes))
            startAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': '', 'doc:name': 'Start FTP'})
            mUnitTagList.append(TagPair('dbserver:start-db-server', startAttributes))
            mUnitTagList.append(TagPair('/munit:before-suite', noAttributes))
            
        # Iterate the TagPairs in the mule flow
        flowPairs = muleFlowTagList.pairs()
        for pair in flowPairs:
            muleAttributes = pair.getAttributes()  # Attributes for the given Mule XML tag
            
            # Handle choicePlaceholder tag       
            if pair.getTag() == 'choicePlaceholder':
                afterChoiceBlock = True
                muleFlowTagList.remove(pair)
                
                # Insert flow ref to Mule flow
                flowRef = OrderedDict({'closeAtEnd': True, 'name': muleFlowName, 'doc:name': 
                                       'Flow-ref to ' + muleFlowName})
                mUnitTagList.append(TagPair('flow-ref', flowRef))
            
            # Handle flow tag
            elif pair.getTag() == 'flow':
                flowAttributes = OrderedDict({'closeAtEnd': False})
                
                if 'name' in muleAttributes:  # Get the name, store it and set MUnit test name
                    muleFlowName = muleAttributes.get('name')
                    flowAttributes['name'] = muleAttributes.get('name') + '-test-'
                    flowAttributes['description'] = 'Unit Test for ' + muleAttributes.get('name')
                
                else:  # Set generic MUnit test name
                    flowAttributes['name'] = 'UnitTestFlow'
                    flowAttributes['description'] = 'Unit Test Flow for unnamed Mule Flow'
                    
                mUnitTagList.append(TagPair('munit:test', flowAttributes)) 
                
                # Place a mock payload if a payload isn't set at the start of the flow 
                nextPairTag = flowPairs[flowPairs.index(pair) + 1].getTag() 
                if (nextPairTag != 'set-payload' and nextPairTag != 'http:listener' 
                    and not 'inbound-endpoint' in nextPairTag):
                    
                    setAttributes = OrderedDict({'closeAtEnd': True, 'payload': '',
                                                 'doc:name': 'Set Initial Test Payload'})
                    mUnitTagList.append(TagPair('munit:set', setAttributes))
                        
            # Handle flow-ref tag       
            elif pair.getTag() == 'flow-ref':  # Create MUnit structure for flow ref
                # Mock flow-ref to sub-flow
                if ('subflow' in muleAttributes['name'].lower() or 'sub-flow' in muleAttributes['name'].lower()
                    or 'sub_flow' in muleAttributes['name'].lower() or 'sub flow' in muleAttributes['name'].lower()):
                   
                    mockVerify = OrderedDict({'closeAtEnd': False, 'messageProcessor': 'mule:sub-flow',
                                              'doc:name': 'Verify Call', 'times': '1'})
                    mUnitTagList.append(TagPair('mock:verify-call', mockVerify))
                    mUnitTagList.append(TagPair('mock:with-attributes', noAttributes))
                    
                    mockAttributeCopy = mockAttribute.copy()
                    mockAttributeCopy['whereValue'] = "#[matchContains('" + muleAttributes['name'] + "')]"
                    mUnitTagList.append(TagPair('mock:with-attribute', mockAttributeCopy))
                    
                    mUnitTagList.append(TagPair('/mock:with-attributes', noAttributes))
                    mUnitTagList.append(TagPair('/mock:verify-call', noAttributes))
                    
                else:  # Mock flow-ref to flow
                    mockWhenCopy = mockWhen.copy()
                    mockWhenCopy['messageProcessor'] = 'mule:flow'
                    mUnitTagList.append(TagPair('mock:when', mockWhenCopy))
                    mUnitTagList.append(TagPair('mock:with-attributes', noAttributes))
                
                    mockAttributeCopy = mockAttribute.copy()
                    mockAttributeCopy['whereValue'] = "#['" + muleAttributes['name'] + "']"
                    mUnitTagList.append(TagPair('mock:with-attribute', mockAttributeCopy))
                    mUnitTagList.append(TagPair('/mock:with-attributes', noAttributes))
                    
                    mUnitTagList.append(TagPair('mock:then-return', mockReturn))
                    mUnitTagList.append(TagPair('mock:invocation-properties', noAttributes))
                    
                    # Leave key and value blank, until it's clear how to accurately populate them
                    mockProperty = OrderedDict({'closeAtEnd': True, 'key': '', 'value': ''})
                    mUnitTagList.append(TagPair('mock:invocation-property', mockProperty))
                    
                    mUnitTagList.append(TagPair('/mock:invocation-properties', noAttributes))
                    mUnitTagList.append(TagPair('/mock:then-return', noAttributes))
                    mUnitTagList.append(TagPair('/mock:when', noAttributes))
            
            # Handle ftp:outbound-endpoint tag
            elif pair.getTag() == 'ftp:outbound-endpoint':
                ftpAttributes = OrderedDict({'closeAtEnd': True, 'file': pair.getAttribute('outputPattern'),
                                             'path': pair.getAttribute('path'), 'config-ref': ''})
                mUnitTagList.append(TagPair('ftpserver:contains-files', ftpAttributes))
                        
            # If at the entrance point to the flow, set a payload if one isn't set after
            elif 'inbound-endpoint' in pair.getTag() or pair.getTag() == 'http:listener':
                if not flowPairs[flowPairs.index(pair) + 1].getTag() == 'set-payload':
                    
                    setAttributes = OrderedDict({'closeAtEnd': True, 'payload': '',
                                                 'doc:name': 'Set Initial Test Payload'})
                    mUnitTagList.append(TagPair('munit:set', setAttributes))

            # Handle set-payload tag
            elif pair.getTag() == 'set-payload':
                if afterChoiceBlock:  # Assert payload value
                    
                    assertPayload = OrderedDict({'closeAtEnd': True, 'message': 'Incorrect payload!',
                                                 'expectedValue': muleAttributes['value']})
                    mUnitTagList.append(TagPair('munit:assert-payload-equals', assertPayload))
                    
                else:  # if before choice block, mock payload value
                    mockWhenCopy = mockWhen.copy()
                    mockWhenCopy['messageProcessor'] = 'mule:set-payload'
                    mUnitTagList.append(TagPair('mock:when', mockWhenCopy))
                    mUnitTagList.append(TagPair('mock:with-attributes', noAttributes))
                    
                    mockAttributeCopy = mockAttribute.copy()
                    mockAttributeCopy['whereValue'] = "#['Set Original Payload']"
                    mockAttributeCopy['name'] = 'doc:name'
                    mUnitTagList.append(TagPair('mock:with-attribute', mockAttributeCopy))
                    mUnitTagList.append(TagPair('/mock:with-attributes', noAttributes))

                    mockReturnCopy = mockReturn.copy()
                    mockReturnCopy['closeAtEnd'] = True
                    mUnitTagList.append(TagPair('mock:then-return', mockReturnCopy))
                    mUnitTagList.append(TagPair('/mock:when', noAttributes))
 
            # Handle /flow tag 
            elif pair.getTag() == '/flow':
                mUnitTagList.append(TagPair('/munit:test', noAttributes))    
                
                # Add DB after-suite case
                if flowContainsDatabase:  # Create mUnit after-suite code to stop the database
                    
                    afterAttributes = OrderedDict({'closeAtEnd': False, 'name': muleFlowName + '-After_Suite_DB',
                                                   'description': 'Stop DB Server'})
                    mUnitTagList.append(TagPair('munit:after-suite', afterAttributes))
                    
                    stopAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': '',
                                                  'doc:name': 'Stop Server'})
                    mUnitTagList.append(TagPair('dbserver:stop-db-server', stopAttributes))
                    mUnitTagList.append(TagPair('/munit:after-suite', noAttributes))
                
                # Add FTP after-suite case
                if flowContainsFTP:
                    
                    afterAttributes = OrderedDict({'closeAtEnd': False, 'name': muleFlowName + '-After_Suite_FTP',
                                                   'description': 'Stop FTP Server'})
                    mUnitTagList.append(TagPair('munit:after-suite', afterAttributes))
                    
                    stopAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': ''})
                    mUnitTagList.append(TagPair('ftpserver:stop-server', stopAttributes))
                    mUnitTagList.append(TagPair('/munit:after-suite', noAttributes))
            
            # Handle /mule tag
            elif pair.getTag() == '/mule':
                mUnitTagList.append(TagPair('/mule', noAttributes))
                
        return mUnitTagList
Exemplo n.º 8
0
class MuleLines:
    # Initialize a list for original mule XML code, and two 
    # TagList objects for existing Mule code and MUnit code to be generated.
    def __init__(self):
        self._inputFileName = ""
        self._muleFileLines = []
        self._muleTagList = TagList()
        self._mUnitTagList = TagList()
        
    # Create an MUnit TagList by parsing the Mule XML tags and properties from the TagList.        
    def createMUnitTests(self) -> None:
        self._generateMUnitDependencies()
        # isolateFlows returns an array of TagLists, which are each a mule flow
        for flow in self._isolateFlows():

            if flow.containsTag('choice'):
                # Convert operations in choice blocks to mUnit code
                mUnitChoiceOperations = self._extractChoiceOperations(flow)
                self._replaceChoiceBlocks(flow)
                
                # Generate multiple test flows if a choice block is present
                for flow in self._generateMUnitTestFlows(mUnitChoiceOperations, flow):
                    mUnitFlow = self._convertMuletoMUnit(flow)  # Convert each test flow to MUnit
                    for pair in mUnitFlow.pairs():
                        self._mUnitTagList.append(pair)
                        
            else:  # Otherwise, create a single test flow
                mUnitFlow = self._convertMuletoMUnit(flow)
                for pair in mUnitFlow.pairs():
                    self._mUnitTagList.append(pair)

        self._mUnitTagList.append(TagPair('/mule', OrderedDict({'closeAtEnd': False})))

    # Converts the mUnitTagList to XML code and writes it to the provided outputFilePath.
    def createMUnitSuiteFile(self, outputFilePath : str) -> None:
        if self._mUnitTagList.isEmpty():
            print('Unable to write to file; no tests available.')
            print('Parse file lines using MuleLines.parseMuleFileLines(fileLines).')
            print('Call MuleLines.createMUnitTests() to create the MUnit Tests for the file.')
        else:
            try:
                file = open(outputFilePath, 'w+')
            except IOError as error:
                print(error.error())
                print('Please input a valid output file path.')
                return
            except:
                print('Unexpected error:', sys.exc_info()[0])
                return
            
            # Write initial XML definition tag to file
            file.write('<?xml version="1.0" encoding="UTF-8"?>\n\n')
            tagDepth = 0
            testNumber = 1
            currentFlow = ""
            
            # Iterate through the TagPairs, create MUnit lines, and write them to the file.
            for pair in self._mUnitTagList.pairs():
                # Create a test number for flows with multiple test cases
                if pair.getTag() == 'munit:test': 
                    if currentFlow != pair.getAttribute('name'):
                        currentFlow = pair.getAttribute('name')
                        testNumber = 1
                        
                    else:
                        testNumber += 1
                        
                # Create the MUnit file lines and write them to the output file.
                mUnitLine = '<' + pair.getTag()
                attributes = pair.getAttributes()
                for attribute in pair.getAttributes():
                    if pair.getTag() == 'munit:test' and attribute == 'name':
                        mUnitLine = (mUnitLine + ' ' + attribute + '="' + attributes.get(attribute) 
                                        + str(testNumber) + '"')
                        
                    elif attribute != 'closeAtEnd':
                        mUnitLine = mUnitLine + ' ' + attribute + '="' + attributes.get(attribute) + '"'
               
                # Add closing braces depending on the tag type
                if pair.getAttribute('closeAtEnd'):
                        mUnitLine += '/>\n'
                        
                else:
                    mUnitLine += '>\n'
                    
                # Insert an additional newline for readability
                if (pair.getTag() == '/munit:test' or pair.getTag() == '/spring:beans' or 
                    pair.getTag() == '/munit:before-suite' or pair.getTag() == '/munit:after-suite'):
                    mUnitLine += '\n'
                    
                # Determine the indentation of current XML tag based on when blocks close
                if pair.getTag()[0] != '/':
                    file.write('\t' * tagDepth + mUnitLine)
                    
                if pair.getTag()[0] == '/':
                    file.write('\t' * (tagDepth - 1) + mUnitLine)
                    tagDepth -= 1
                    
                elif not pair.getAttribute('closeAtEnd'):
                    tagDepth += 1
            file.close()

    # Parse XML lines of Mule code into the _muleTagList for this object.
    def parseMuleFileLines(self, inputFilePath : str) -> None:
        self._extractMuleFileLines(inputFilePath)
        self._inputFileName = os.path.basename(inputFilePath)  # Take only the filename
        
        for line in self._muleFileLines:
            if line[0] == '<' and line[1] != '?' and line[1] != '!':
                splitLine = shlex.split(line)  # Split the line; preserves spaces in quoted strings.
                attrDict = OrderedDict()
                
                if len(splitLine) > 1:  # Map additional attributes to attrDict
                    for item in splitLine[1:]:  # Skip the tag in the line
                        attrAndValue = item.split('=')
                        
                        # Add a closeAtEnd attribute, for use in writing the final output file
                        if attrAndValue[1][-2:] == '/>':
                            attrDict['closeAtEnd'] = True
                            attrDict[attrAndValue[0]] = attrAndValue[1][:-2]  # Strip closing bracket
                            
                        elif attrAndValue[1][-1:] == '>':
                            attrDict['closeAtEnd'] = False
                            attrDict[attrAndValue[0]] = attrAndValue[1][:-1]  # Strip closing bracket
                        
                        else:  # Add to the dict if it's a middle attribute
                            attrDict[attrAndValue[0]] = attrAndValue[1]
                    
                    self._muleTagList.append(TagPair(splitLine[0].lower().strip('<'), attrDict))
                    
                else:  # Add a closeAtEnd attribute, for use in writing the final output file
                    if splitLine[0][:2] == '</':
                        attrDict['closeAtEnd'] = False
                    
                    else:
                        attrDict['closeAtEnd'] = True
                    
                    self._muleTagList.append(TagPair(splitLine[0].lower().strip('<').strip('>'), attrDict))
    
    # Convert a mule flow to a TagList of MUnit code.
    # Can raise a TypeError if incorrect parameter types are provided.
    def _convertMuletoMUnit(self, muleFlowTagList : TagList) -> TagList:
        if not isinstance(muleFlowTagList, TagList):
            raise TypeError('Invalid parameter passed to MuleLines _convertMuletoMUnit')
        self._replaceChoiceBlocks(muleFlowTagList)  # Replace choice blocks with choicePlaceholder
        
        # Values used for tracking info throughout the method
        muleFlowName = ""
        mUnitTagList = TagList()
        afterChoiceBlock = True  # Used to determine certain tag types
        flowContainsDatabase = False  # Used to create before and after flows for DB mocking
        flowContainsFTP = False
        
        # Define generic OrderedDicts for commonly used tag attributes
        noAttributes = OrderedDict({'closeAtEnd': False})
        mockReturn = OrderedDict({'closeAtEnd': False, 'payload': '#[]'})
        mockAttribute = OrderedDict({'closeAtEnd': True, 'name': 'name'})
        mockWhen = OrderedDict({'closeAtEnd': False, 'doc:name': 'Mock'})
                
        # Iterate through the Mule XML tags and attributes to create MUnit tags and attributes.
        if muleFlowTagList.containsTag('choicePlaceholder'):
            afterChoiceBlock = False

        # Check if a DB connector is in the flow
        if (muleFlowTagList.containsTag('db:select') or muleFlowTagList.containsTag('db:insert') or
             muleFlowTagList.containsTag('db:update') or muleFlowTagList.containsTag('db:delete') or 
             muleFlowTagList.containsTag('db:stored-procedure') or muleFlowTagList.containsTag('db:bulk-execute')
             or muleFlowTagList.containsTag('db:execute-ddl')):
            
            flowContainsDatabase = True
            
            # Create before suite block to start a DB mock
            beforeAttributes = OrderedDict({'closeAtEnd': False, 'name': 'before-DB',
                                            'description': 'Start DB Server'})
            mUnitTagList.append(TagPair('munit:before-suite', beforeAttributes))
            
            startAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': '', 'doc:name': 'Start DB'})
            mUnitTagList.append(TagPair('dbserver:start-db-server', startAttributes))
            mUnitTagList.append(TagPair('/munit:before-suite', noAttributes))
            
        # Check if FTP connector is in the flow
        if muleFlowTagList.containsTag('ftp:outbound-endpoint'):
            flowContainsFTP = True
            
            # Add FTP before-suite block to start an FTP mock
            beforeAttributes = OrderedDict({'closeAtEnd': False, 'name': 'before-FTP',
                                            'description': 'Start DB Server'})
            mUnitTagList.append(TagPair('munit:before-suite', beforeAttributes))
            startAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': '', 'doc:name': 'Start FTP'})
            mUnitTagList.append(TagPair('dbserver:start-db-server', startAttributes))
            mUnitTagList.append(TagPair('/munit:before-suite', noAttributes))
            
        # Iterate the TagPairs in the mule flow
        flowPairs = muleFlowTagList.pairs()
        for pair in flowPairs:
            muleAttributes = pair.getAttributes()  # Attributes for the given Mule XML tag
            
            # Handle choicePlaceholder tag       
            if pair.getTag() == 'choicePlaceholder':
                afterChoiceBlock = True
                muleFlowTagList.remove(pair)
                
                # Insert flow ref to Mule flow
                flowRef = OrderedDict({'closeAtEnd': True, 'name': muleFlowName, 'doc:name': 
                                       'Flow-ref to ' + muleFlowName})
                mUnitTagList.append(TagPair('flow-ref', flowRef))
            
            # Handle flow tag
            elif pair.getTag() == 'flow':
                flowAttributes = OrderedDict({'closeAtEnd': False})
                
                if 'name' in muleAttributes:  # Get the name, store it and set MUnit test name
                    muleFlowName = muleAttributes.get('name')
                    flowAttributes['name'] = muleAttributes.get('name') + '-test-'
                    flowAttributes['description'] = 'Unit Test for ' + muleAttributes.get('name')
                
                else:  # Set generic MUnit test name
                    flowAttributes['name'] = 'UnitTestFlow'
                    flowAttributes['description'] = 'Unit Test Flow for unnamed Mule Flow'
                    
                mUnitTagList.append(TagPair('munit:test', flowAttributes)) 
                
                # Place a mock payload if a payload isn't set at the start of the flow 
                nextPairTag = flowPairs[flowPairs.index(pair) + 1].getTag() 
                if (nextPairTag != 'set-payload' and nextPairTag != 'http:listener' 
                    and not 'inbound-endpoint' in nextPairTag):
                    
                    setAttributes = OrderedDict({'closeAtEnd': True, 'payload': '',
                                                 'doc:name': 'Set Initial Test Payload'})
                    mUnitTagList.append(TagPair('munit:set', setAttributes))
                        
            # Handle flow-ref tag       
            elif pair.getTag() == 'flow-ref':  # Create MUnit structure for flow ref
                # Mock flow-ref to sub-flow
                if ('subflow' in muleAttributes['name'].lower() or 'sub-flow' in muleAttributes['name'].lower()
                    or 'sub_flow' in muleAttributes['name'].lower() or 'sub flow' in muleAttributes['name'].lower()):
                   
                    mockVerify = OrderedDict({'closeAtEnd': False, 'messageProcessor': 'mule:sub-flow',
                                              'doc:name': 'Verify Call', 'times': '1'})
                    mUnitTagList.append(TagPair('mock:verify-call', mockVerify))
                    mUnitTagList.append(TagPair('mock:with-attributes', noAttributes))
                    
                    mockAttributeCopy = mockAttribute.copy()
                    mockAttributeCopy['whereValue'] = "#[matchContains('" + muleAttributes['name'] + "')]"
                    mUnitTagList.append(TagPair('mock:with-attribute', mockAttributeCopy))
                    
                    mUnitTagList.append(TagPair('/mock:with-attributes', noAttributes))
                    mUnitTagList.append(TagPair('/mock:verify-call', noAttributes))
                    
                else:  # Mock flow-ref to flow
                    mockWhenCopy = mockWhen.copy()
                    mockWhenCopy['messageProcessor'] = 'mule:flow'
                    mUnitTagList.append(TagPair('mock:when', mockWhenCopy))
                    mUnitTagList.append(TagPair('mock:with-attributes', noAttributes))
                
                    mockAttributeCopy = mockAttribute.copy()
                    mockAttributeCopy['whereValue'] = "#['" + muleAttributes['name'] + "']"
                    mUnitTagList.append(TagPair('mock:with-attribute', mockAttributeCopy))
                    mUnitTagList.append(TagPair('/mock:with-attributes', noAttributes))
                    
                    mUnitTagList.append(TagPair('mock:then-return', mockReturn))
                    mUnitTagList.append(TagPair('mock:invocation-properties', noAttributes))
                    
                    # Leave key and value blank, until it's clear how to accurately populate them
                    mockProperty = OrderedDict({'closeAtEnd': True, 'key': '', 'value': ''})
                    mUnitTagList.append(TagPair('mock:invocation-property', mockProperty))
                    
                    mUnitTagList.append(TagPair('/mock:invocation-properties', noAttributes))
                    mUnitTagList.append(TagPair('/mock:then-return', noAttributes))
                    mUnitTagList.append(TagPair('/mock:when', noAttributes))
            
            # Handle ftp:outbound-endpoint tag
            elif pair.getTag() == 'ftp:outbound-endpoint':
                ftpAttributes = OrderedDict({'closeAtEnd': True, 'file': pair.getAttribute('outputPattern'),
                                             'path': pair.getAttribute('path'), 'config-ref': ''})
                mUnitTagList.append(TagPair('ftpserver:contains-files', ftpAttributes))
                        
            # If at the entrance point to the flow, set a payload if one isn't set after
            elif 'inbound-endpoint' in pair.getTag() or pair.getTag() == 'http:listener':
                if not flowPairs[flowPairs.index(pair) + 1].getTag() == 'set-payload':
                    
                    setAttributes = OrderedDict({'closeAtEnd': True, 'payload': '',
                                                 'doc:name': 'Set Initial Test Payload'})
                    mUnitTagList.append(TagPair('munit:set', setAttributes))

            # Handle set-payload tag
            elif pair.getTag() == 'set-payload':
                if afterChoiceBlock:  # Assert payload value
                    
                    assertPayload = OrderedDict({'closeAtEnd': True, 'message': 'Incorrect payload!',
                                                 'expectedValue': muleAttributes['value']})
                    mUnitTagList.append(TagPair('munit:assert-payload-equals', assertPayload))
                    
                else:  # if before choice block, mock payload value
                    mockWhenCopy = mockWhen.copy()
                    mockWhenCopy['messageProcessor'] = 'mule:set-payload'
                    mUnitTagList.append(TagPair('mock:when', mockWhenCopy))
                    mUnitTagList.append(TagPair('mock:with-attributes', noAttributes))
                    
                    mockAttributeCopy = mockAttribute.copy()
                    mockAttributeCopy['whereValue'] = "#['Set Original Payload']"
                    mockAttributeCopy['name'] = 'doc:name'
                    mUnitTagList.append(TagPair('mock:with-attribute', mockAttributeCopy))
                    mUnitTagList.append(TagPair('/mock:with-attributes', noAttributes))

                    mockReturnCopy = mockReturn.copy()
                    mockReturnCopy['closeAtEnd'] = True
                    mUnitTagList.append(TagPair('mock:then-return', mockReturnCopy))
                    mUnitTagList.append(TagPair('/mock:when', noAttributes))
 
            # Handle /flow tag 
            elif pair.getTag() == '/flow':
                mUnitTagList.append(TagPair('/munit:test', noAttributes))    
                
                # Add DB after-suite case
                if flowContainsDatabase:  # Create mUnit after-suite code to stop the database
                    
                    afterAttributes = OrderedDict({'closeAtEnd': False, 'name': muleFlowName + '-After_Suite_DB',
                                                   'description': 'Stop DB Server'})
                    mUnitTagList.append(TagPair('munit:after-suite', afterAttributes))
                    
                    stopAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': '',
                                                  'doc:name': 'Stop Server'})
                    mUnitTagList.append(TagPair('dbserver:stop-db-server', stopAttributes))
                    mUnitTagList.append(TagPair('/munit:after-suite', noAttributes))
                
                # Add FTP after-suite case
                if flowContainsFTP:
                    
                    afterAttributes = OrderedDict({'closeAtEnd': False, 'name': muleFlowName + '-After_Suite_FTP',
                                                   'description': 'Stop FTP Server'})
                    mUnitTagList.append(TagPair('munit:after-suite', afterAttributes))
                    
                    stopAttributes = OrderedDict({'closeAtEnd': True, 'config-ref': ''})
                    mUnitTagList.append(TagPair('ftpserver:stop-server', stopAttributes))
                    mUnitTagList.append(TagPair('/munit:after-suite', noAttributes))
            
            # Handle /mule tag
            elif pair.getTag() == '/mule':
                mUnitTagList.append(TagPair('/mule', noAttributes))
                
        return mUnitTagList
    
    # Extracts operations performed in a choice block in the provided flow.
    # Returns a TagList containing the choice operations.
    # Can raise a TypeError if an incorrect parameter type is provided.
    def _extractChoiceOperations(self, flowTagList : TagList) -> []:
        if not isinstance(flowTagList, TagList):
            raise TypeError('Invalid parameter type passed to MuleLines _extractChoiceOperations')
        
        choiceOperations = []
        caseOperations = TagList()
        inChoiceClause = False
        for pair in flowTagList.pairs():
            if pair.getTag() == 'when' or pair.getTag() == 'otherwise':
                inChoiceClause = True
                
            elif pair.getTag() == '/when' or pair.getTag() == '/otherwise':
                inChoiceClause = False
                choiceOperations.append(caseOperations.copy())
                caseOperations.clear()
                
            elif inChoiceClause:
                caseOperations.append(pair)
                
        return choiceOperations
    
    # Reads the specified file and returns a list of file lines.
    # Splits whitespace and takes only lines beginning in tags
    def _extractMuleFileLines(self, inputFilePath : str) -> None:
        with open(inputFilePath, 'r') as file:
            self._muleFileLines = file.readlines()
        self._muleFileLines = list(filter(None, [x.lstrip(' ').strip() for x in self._muleFileLines]))
       
        for line in self._muleFileLines:
            if line[0] != "<":
                self._muleFileLines.remove(line)

    # Extracts all spring imports and values from the Mule TagList and adds them to the MUnit TagList
    def _extractSpringInternals(self) -> None:
        for pair in self._muleTagList.pairs():
            if ('spring' in pair.getTag() and pair.getTag() != 'spring:beans' 
                and pair.getTag() != '/spring:beans'):
                self._mUnitTagList.append(pair)

    # Add standard xml definition and MUnit dependencies.
    # Grabs any spring:bean dependencies, as well as Mule xmlns dependency attributes.
    def _generateMUnitDependencies(self) -> None:
        # Set mule tag and attributes
        muleAttributes = OrderedDict()
        muleAttributes['closeAtEnd'] = False
        muleAttributes['xmlns'] = 'http://www.mulesoft.org/schema/mule/core'
        muleAttributes['\n\txmlns:mock'] = 'http://www.mulesoft.org/schema/mule/mock'
        muleAttributes['xmlns:munit'] = 'http://www.mulesoft.org/schema/mule/munit'
        muleAttributes['\n\txmlns:doc'] = 'http://www.mulesoft.org/schema/mule/documentation'
        muleAttributes['xmlns:spring'] = 'http://www.springframework.org/schema/beans'
        muleAttributes['\n\txmlns:core'] = 'http://www.mulesoft.org/schema/mule/core'
        muleAttributes['version'] = 'EE-3.7.3'
        muleAttributes['\n\txmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'
        muleAttributes['\n\txsi:schemaLocation'] = """http://www.mulesoft.org/schema/mule/mock 
    http://www.mulesoft.org/schema/mule/mock/current/mule-mock.xsd http://www.mulesoft.org/schema/mule/munit 
    http://www.mulesoft.org/schema/mule/munit/current/mule-munit.xsd http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-current.xsd http://www.mulesoft.org/schema/mule/core 
    http://www.mulesoft.org/schema/mule/core/current/mule.xsd"""
        self._mUnitTagList.append(TagPair('mule', muleAttributes))
        
        # Set munit:config tag and attributes
        configAttributes = OrderedDict({'closeAtEnd': True, 'name': 'munit', 'doc:name': 'Munit Configuration'})
        self._mUnitTagList.append(TagPair('munit:config', configAttributes))
        
        # Set spring tags and attributes
        self._mUnitTagList.append(TagPair('spring:beans', OrderedDict({'closeAtEnd': False})))
        
        # Add a spring import for the file we're testing, and copy any spring internal values from the file
        springInternalAttributes = OrderedDict({'closeAtEnd': True, 'resource': 
                                                'classpath:' + self._inputFileName})
        self._mUnitTagList.append(TagPair('spring:import', springInternalAttributes))
        
        self._extractSpringInternals()  # Extract spring tags and insert them into the MUnit TagList
        self._mUnitTagList.append(TagPair('/spring:beans', OrderedDict({'closeAtEnd': False})))
        
    # Generates MUnit Test Flows given the operations performed in a choice block 
    # and a TagList of a flow containing a choicePlaceholder tag.
    # Can raise a type error if invalid parameter types are provided.
    def _generateMUnitTestFlows(self, choiceOperations : [], mUnitBaseTagList : TagList) -> []:
        if not isinstance(choiceOperations, list) or not isinstance(mUnitBaseTagList, TagList):
            raise TypeError('Invalid parameter types passed to MuleLines _generateMUnitTestFlows')
        outputFlows = []
        
        # Create a flow for each choice operation. (Later support should include multiple operations)
        for choiceTagList in choiceOperations:
            mUnitCopy = mUnitBaseTagList.copy()
            pair = mUnitCopy.getPair('choicePlaceholder')
            pairIndex = mUnitCopy.index(pair)
            
            for choicePair in choiceTagList.pairs():
                pairIndex += 1  # Increment index for each pair to maintain correct order
                mUnitCopy.insertAtIndex(pairIndex, choicePair)
            outputFlows.append(mUnitCopy)    
             
        return outputFlows
        
    # Iterates through the muleTagList and returns a list of TagLists, where each
    # returned TagList is a mule flow.
    def _isolateFlows(self) -> []:
        flows = []
        inFlow = False
        flowList = TagList()
        
        for pair in self._muleTagList.pairs():
            # If within a flow or sub-flow block, add the pair to the outputList
            if pair.getTag() == 'flow' or pair.getTag() == 'sub-flow':
                inFlow = True
                flowList.append(pair)
                
            elif pair.getTag() == '/flow' or pair.getTag() == '/sub-flow':
                flowList.append(pair)
                flows.append(flowList.copy())
                flowList.clear()  # Clear the flowList to handle next flow
                inFlow = False
                
            elif inFlow:
                flowList.append(pair)
                
        return flows
    
    # Replace choice blocks in the mule TagList with a choice placeholder.
    # Can raise a TypeError if incorrect parameter types are provided.
    def _replaceChoiceBlocks(self, muleTagList : TagList) -> TagList:
        if not isinstance(muleTagList, TagList):
            raise TypeError('Invalid parameter passed to MuleLines _replaceChoiceBlocks')
        inChoiceBlock = False
        
        for pair in muleTagList.pairs():
            # Determine the edges of the choice block, and remove everything in between.
            if pair.getTag() == 'choice':
                inChoiceBlock = True
                
            elif pair.getTag() == '/choice':
                inChoiceBlock = False
                pair.setTag('choicePlaceholder')
                
            if inChoiceBlock:
                muleTagList.remove(pair)
                
        return muleTagList
Exemplo n.º 9
0
    def MakeListOfListsFromString(extensions):
        list = Settings.MakeListFromExtensionString(extensions)
        for i in range(len(list)):
            list[i] = TagList(list[i].split(" "))

        return list
class ReleaseNameParser:
    def __init__(self, name):
        originalName = name

        # Simply popping the last tag as a group name wouldn't work because of P2P release with multiple dashes in it:
        # Let Me In 2010 DVDRIP READNFO XViD-T0XiC-iNK

        self.Group = ""

        name = name.lower()
        name = name.replace(".", " ")
        name = name.strip()

        # Check if there is a group name in the release name.
        if name.rfind('-') == -1 or name.endswith("-"):
            self.Tags = TagList(name.split(" "))
        else:
            name = name.replace("-", " ")
            name = name.strip()
            self.Tags = TagList(name.split(" "))
            if self.__HandleSpecialGroupName(["d", "z0n3"]):
                pass
            elif self.__HandleSpecialGroupName(["t0xic", "ink"]):
                pass
            elif self.__HandleSpecialGroupName(["vh", "prod"]):
                pass
            elif name.endswith(
                    " h 264"
            ):  # For release names without group names. E.g.: Critters.1986.720p.WEB-DL.AAC2.0.H.264
                pass
            else:
                self.Group = self.Tags.List.pop()

        if len(self.Tags.List) <= 0:
            raise PtpUploaderException(
                "Release name '%s' doesn't contain any tags." % originalName)

        # This is not perfect (eg.: The Legend of 1900), but it doesn't matter if the real year will be included in the tags.
        self.TagsAfterYear = TagList([])
        for i in range(len(self.Tags.List)):
            if re.match(r"\d\d\d\d", self.Tags.List[i]):
                self.TagsAfterYear.List = self.Tags.List[i + 1:]
                break

        self.Scene = self.Group in Settings.SceneReleaserGroup

    def __HandleSpecialGroupName(self, groupNameAsTagList):
        if self.Tags.RemoveTagsFromEndIfPossible(groupNameAsTagList):
            self.Group = "-".join(groupNameAsTagList)
            return True

        return False

    def GetSourceAndFormat(self, releaseInfo):
        if releaseInfo.IsCodecSet():
            releaseInfo.Logger.info(
                "Codec '%s' is already set, not getting from release name." %
                releaseInfo.Codec)
        elif self.Tags.IsContainsTag("xvid"):
            releaseInfo.Codec = "XviD"
        elif self.Tags.IsContainsTag("divx"):
            releaseInfo.Codec = "DivX"
        elif self.Tags.IsContainsTag("x264"):
            releaseInfo.Codec = "x264"
        elif self.Tags.IsContainsTag("avc") or self.Tags.IsContainsTag(
                "h264") or self.Tags.IsContainsTags(["h", "264"]):
            releaseInfo.Codec = "H.264"
        elif self.Tags.IsContainsTag("mpeg2") or self.Tags.IsContainsTags(
            ["mpeg", "2"]):
            releaseInfo.Codec = "MPEG-2"
        elif self.Tags.IsContainsTag("vc1") or self.Tags.IsContainsTags(
            ["vc", "1"]):
            releaseInfo.Codec = "VC-1"
        else:
            raise PtpUploaderException(
                "Can't figure out codec from release name '%s'." %
                releaseInfo.ReleaseName)

        if releaseInfo.IsSourceSet():
            releaseInfo.Logger.info(
                "Source '%s' is already set, not getting from release name." %
                releaseInfo.Source)
        elif self.Tags.IsContainsTag("dvdrip"):
            releaseInfo.Source = "DVD"
        elif self.Tags.IsContainsTag("bdrip") or self.Tags.IsContainsTag(
                "bluray") or self.Tags.IsContainsTags(["blu", "ray"]):
            releaseInfo.Source = "Blu-ray"
        elif self.Tags.IsContainsTag("hddvd"):
            releaseInfo.Source = "HD-DVD"
        elif self.Tags.IsContainsTag("hdtv"):
            releaseInfo.Source = "HDTV"
        elif self.Tags.IsContainsTag("dvdscr"):
            releaseInfo.Source = "DVD-Screener"
        elif self.Tags.IsContainsTag("webdl") or self.Tags.IsContainsTags(
            ["web", "dl"]):
            releaseInfo.Source = "WEB"
        elif self.Tags.IsContainsTag("brrip"):
            raise PtpUploaderException("BRRips are not allowed.")
        else:
            raise PtpUploaderException(
                "Can't figure out source from release name '%s'." %
                releaseInfo.ReleaseName)

        if releaseInfo.IsResolutionTypeSet():
            releaseInfo.Logger.info(
                "Resolution type '%s' is already set, not getting from release name."
                % releaseInfo.ResolutionType)
        elif self.Tags.IsContainsTag("720p"):
            releaseInfo.ResolutionType = "720p"
        elif self.Tags.IsContainsTag("1080p"):
            releaseInfo.ResolutionType = "1080p"
        elif self.Tags.IsContainsTag("1080i"):
            releaseInfo.ResolutionType = "1080i"
        else:
            releaseInfo.ResolutionType = "Other"

        if len(releaseInfo.RemasterTitle) <= 0 and self.Tags.IsContainsTag(
                "remux"):
            releaseInfo.RemasterTitle = "Remux"

    @staticmethod
    def __IsTagListContainAnythingFromListOfTagList(tagList, listOfTagList):
        for listOfTagListElement in listOfTagList:
            if tagList.IsContainsTags(listOfTagListElement.List):
                return str(listOfTagListElement)

        return None

    def IsAllowed(self):
        if self.Group in Settings.IgnoreReleaserGroup:
            return "Group '%s' is in your ignore list." % self.Group

        if len(Settings.AllowReleaseTag) > 0:
            match = ReleaseNameParser.__IsTagListContainAnythingFromListOfTagList(
                self.Tags, Settings.AllowReleaseTag)
            if match is None:
                return "Ignored because didn't match your allowed tags setting."

        match = ReleaseNameParser.__IsTagListContainAnythingFromListOfTagList(
            self.Tags, Settings.IgnoreReleaseTag)
        if match is not None:
            return "'%s' is on your ignore list." % match

        if len(self.TagsAfterYear.List) > 0:
            match = ReleaseNameParser.__IsTagListContainAnythingFromListOfTagList(
                self.TagsAfterYear, Settings.IgnoreReleaseTagAfterYear)
            if match is not None:
                return "'%s' is on your ignore list." % match
        else:
            match = ReleaseNameParser.__IsTagListContainAnythingFromListOfTagList(
                self.Tags, Settings.IgnoreReleaseTagAfterYear)
            if match is not None:
                return "'%s' is on your ignore list." % match

        return None