Example #1
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'name':
            if self.name != '':
                parseError( 'Name already set: {0}'.format( self.name ) )
            if not isValidName( value ):
                parseError( '"{0}" is not a valid name'.format( value ) )
            if value in self.scenario.getObjectsDict('file'):
                parseError( 'File object called {0} already exists'.format( value ) )
            self.name = value
        elif key == "rootHash":
            Campaign.logger.log( "Warning: The rootHash parameter to a file is deprecated due to ambiguity. Please use rootHash[1] instead." )
            if 1 in self.rootHashes:
                parseError( 'Root hash for chunksize 1 already set: {0}'.format( self.rootHash ) )
            if not isinstance( value, basestring ) or len( value ) != 40 or reduce( lambda x, y: x or not ( ( y >= '0' and y <= '9' ) or ( y >= 'A' and y <= 'F' ) or ( y >= 'a' and y <= 'f' ) ), value, False ):
                parseError( 'Valid root hashes consist of exactly 40 hexadecimal digits, unlike "{0}"'.format( value ) )
            self.rootHash = value
            self.rootHashes[1] = value
        elif key[:9] == 'rootHash[' and key[-1:] == ']':
            chunksize = key[9:-1]
            if chunksize[-1:] == 'L':
                if not isPositiveInt(chunksize[:-1], True):
                    parseError( 'The chunksize of a root hash must be a positive non-zero integer, possibly postfixed by L for legacy root hashes.' )
            else:
                if not isPositiveInt(chunksize, True):
                    parseError( 'The chunksize of a root hash must be a positive non-zero integer, possibly postfixed by L for legacy root hashes.' )
                chunksize = int(chunksize)
            if chunksize in self.rootHashes:
                parseError( 'The root hash for chunksize {0} has already been set: {1}'.format( chunksize, self.rootHashes[chunksize] ) )
            if not isinstance( value, basestring ) or len( value ) != 40 or reduce( lambda x, y: x or not ( ( y >= '0' and y <= '9' ) or ( y >= 'A' and y <= 'F' ) or ( y >= 'a' and y <= 'f' ) ), value, False ):
                parseError( 'Valid root hashes consist of exactly 40 hexadecimal digits, unlike "{0}"'.format( value ) )
            self.rootHashes[chunksize] = value
            if chunksize == 1:
                self.rootHash = value 
        elif key == "metaFile":
            if self.metaFile:
                parseError( 'Meta file already set: {0}'.format( self.metaFile ) )
            if not os.path.exists( value ):
                parseError( 'Meta file {0} seems not to exist'.format( value ) )
            self.metaFile = value
        else:
            parseError( 'Unknown parameter name: {0}'.format( key ) )
Example #2
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'listenAddress':
            if self.listenAddress:
                parseError( "listenAddress is already set: {0}".format( self.listenAddress ) )
            if containsSpace(value):
                parseError( "listenAddress may not contain any whitespace" )
            self.listenAddress = value
        elif key == 'listenPort':
            if self.listenPort:
                parseError( "listenPort is already set: {0}".format( self.listenPort ) )
            if not isPositiveInt( value, True ):
                parseError( "listenPort must be a positive integer" )
            self.listenPort = int(value)
        elif key == 'tracker':
            if self.tracker:
                parseError( "tracker is already set: {0}".format( self.tracker ) )
            if containsSpace(value):
                parseError( "tracker may not contain any whitespace" )
            self.tracker = value
        elif key == 'wait':
            if self.wait:
                parseError( "wait is already set: {0}".format( self.wait ) )
            if not isPositiveInt( value, True ):
                parseError( "wait must be a positive integer" )
            self.wait = int(value)
        elif key == 'chunkSize':
            if self.chunkSize:
                parseError( "chunck size is already set: {0}".format( self.chunkSize ) )
            if not isPositiveInt( value, True ):
                parseError( "chunck size must be a positive integer" )
            if int(value) % 1024 != 0:
                parseError( "chunk sizes not divisible by 1024 are not supported" )                
            self.chunkSize = int(value)
        else:
            client.parseSetting(self, key, value)
Example #3
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'path':
            if not os.path.exists( value ):
                parseError( "File or directory '{0}' does not exist".format( value ) )
            if self.path:
                parseError( "A file or directory was already given" )
            self.path = value
        elif key == 'torrent' or key == 'generateTorrent':
            if key == 'torrent':
                Campaign.logger.log( "Please do not use the torrent parameter of file:local anymore. It is deprecated. Use generateTorrent instead." )
            if value == 'yes':
                self.generateTorrent = True
        elif key == 'generateRootHash':
            fallback = False
            if value[-1:] == 'L':
                if not isPositiveInt(value[:-1], True):
                    fallback = True
            else:
                if not isPositiveInt(value, True):
                    fallback = True
                else:
                    value = int(value)
            if fallback:
                Campaign.logger.log( "Warning! Chunksize {0} was detected as the value of a generateRootHash parameter to a file:local. This is not a valid chunksize (which would be a positive non-zero integer possible postfixed by L) and is replaced by 1 for backwards compatibility. This behavior will disappear in 2.5.0.".format( value ) )
                value = 1
            if value in self.generateRootHashes:
                parseError( "Generation of root hashes for chunksize {0} was already requested.".format( value ) )
            self.generateRootHashes.append(value)
        elif key == 'renameFile':
            if value == 'yes':
                self.renameFile = True
        else:
            core.file.file.parseSetting(self, key, value)
Example #4
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'hostname':
            if self.hostname:
                parseError( "The hostname was already set: {0}".format( self.hostname ) )
            if containsSpace( value ):
                parseError( "A hostname must not contain spaces" )
            self.hostname = value
        elif key == 'port':
            if self.port:
                parseError( "The port was already set: {0}".format( self.port ) )
            if not isPositiveInt( value, True ):
                parseError( "The port must be a positive, non-zero integer" )
            self.port = value
        elif key == 'user':
            if self.user:
                parseError( "The user was already set: {0}".format( self.user ) )
            self.user = value
        else:
            host.parseSetting(self, key, value)            
Example #5
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'testTime':
            if self.testTime is not None:
                parseError( "Test time already set to {0}".format( self.testTime ) )
            if not isPositiveInt( value, True ):
                parseError( "The number of seconds to wait must be a non-zero positive integer" )
            self.testTime = value
        else:
            client.parseSetting(self, key, value)
Example #6
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'useSSL':
            self.useSSL = (value != "no")
        elif key == 'port':
            if self.port:
                parseError( "Port already set: {0}".format( self.port ) )
            if not isPositiveInt( value, True ) or int(value) > 65535:
                parseError( "Port should be a non-zero integer < 65536" )
            self.port = int(value)
        else:
            client.parseSetting(self, key, value)
Example #7
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'port':
            if self.port:
                parseError( "Port already set: {0}".format( self.port ) )
            if not isPositiveInt( value ) or int(value) < 1024 or int(value) > 65535:
                parseError( "Port must be a positive integer greater than 1023 and smaller than 65536, not {0}".format( value ) )
            self.port = int(value)
        elif key == 'changeTracker' or key == 'changetracker':
            if not isValidName( value ):
                parseError( "{0} is not a valid name for a file object.".format( value ) )
            self.changeTrackers.append( value )
        elif key == 'changeClientTracker':
            if not isValidName( value ):
                parseError( "{0} is not a valid name for a client object.".format( value ) )
            self.changeClientTrackers.append( value )
        else:
            client.parseSetting(self, key, value)
Example #8
0
def checkSpeedValue( value, speedName ):
    origValue = value
    intValue = value
    if value[-4:] == 'mbit':
        intValue = value[:-4]
    elif value[-4:] == 'kbit':
        intValue = value[:-4]
    else:
        value = value + 'mbit'
    if not isPositiveInt( intValue ):
        parseError( '{1} should be a positive integer, possibly postfixed by kbit or mbit (default: mbit), found "{0}"'.format( origValue, speedName ) )
    return value
Example #9
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'size':
            Campaign.logger.log( "WARNING! The size parameter to file:fakedata is deprecated. Please use ksize instead.")
            if not isPositiveInt( value, True ):
                parseError( "The size must be a positive, non-zero integer" )
            if self.size:
                parseError( "Size already set: {0}".format(self.size) )
            self.size = int(value)/1024
        elif key == 'ksize':
            if not isPositiveInt( value, True ):
                parseError( "The ksize must be a positive, non-zero integer" )
            if self.size:
                parseError( "Size already set: {0}".format(self.size) )
            if int(value) % 4 != 0:
                parseError( "The ksize parameter should be a multiple of 4")
            self.size = int(value)
        elif key == 'binary':
            if self.binary:
                parseError( "The path to the fakedata binary has already been set: {0}".format( self.binary ) )
            self.binary = value
        elif key == 'filename' or key == 'fileName':
            if key == 'fileName':
                Campaign.logger.log( "Warning: the parameter fileName to file:fakedata has been deprecated. Use filename instead." )
            if self.filename:
                parseError( "The filename has already been set: {0}".format( self.filename ) )
            self.filename = value
        elif key == 'multiple':
            if self.multiple:
                parseError( "multiple may be specified only once" )
            if not isPositiveInt( value, True ):
                parseError( "multiple must be a positive, non-zero integer" )
            self.multiple = int(value)
        elif key == 'generateRootHash':
            fallback = False
            if value[-1:] == 'L':
                if not isPositiveInt(value[:-1], True):
                    fallback = True
            else:
                if not isPositiveInt(value, True):
                    fallback = True
                else:
                    value = int(value)
            if fallback:
                Campaign.logger.log( "Warning! Chunksize {0} was detected as the value of a generateRootHash parameter to a file:fakedata. This is not a valid chunksize (which would be a positive non-zero integer possible postfixed by L) and is replaced by 1 for backwards compatibility. This behavior will disappear in 2.5.0.".format( value ) )
                value = 1
            if value in self.generateRootHashes:
                parseError( "Generation of root hashes for chunksize {0} was already requested.".format( value ) )
            self.generateRootHashes.append(value)
        elif key == 'generateTorrent':
            self.generateTorrent = (value != '')
        elif key == 'torrentCache':
            if self.torrentCacheDir:
                parseError( "A torrent cache directory has already been set: {0}".format( self.torrentCacheDir ) )
            if not os.path.isdir( value ):
                parseError( "{0} is not a directory".format( value ) )
            self.torrentCacheDir = value
        elif key == 'rootHashCache':
            if self.rootHashCacheFile:
                parseError( "A root hash cache file has already been set: {0}".format( self.rootHashCacheFile ) )
            if os.path.exists( value ) and not os.path.isfile( value ):
                parseError( "{0} is not a file".format( value ) )
            if os.path.dirname( value ) == '' or not os.path.isdir( os.path.dirname( value ) ):
                parseError( "{0} does not point to a new file in an existing directory".format( value ) )
            self.rootHashCacheFile = value
        else:
            core.file.file.parseSetting(self, key, value)
Example #10
0
        viewerObject = viewerClass(scenarioObject)
        if not viewerObject.canReview():
            raise Exception("Viewer {0} can't be used to review (canReview() returns False).".format(viewer.name))
        for arg in viewer.args:
            parameterName = getParameterName(arg)
            parameterValue = getParameterValue(arg)
            viewerObject.parseSettings(parameterName, parameterValue)
        viewerObject.checkSettings()
        viewerObjects.append(viewerObject)

    executionNumbers = []
    extraExecutionNumbers = []
    if not (leechers and seeders):
        for f in os.listdir(processedDir):
            if f[:9] == "isSeeder_":
                if not isPositiveInt(f[9:]):
                    print "Warning! '{0}' is not a valid execution number in the seeder data of directory {1}.".format(
                        f[9:], dirName
                    )
                    executionNumbers = []
                    break
                fObj = open(os.path.join(processedDir, f), "r")
                if not fObj:
                    print "Warning! Can't open {0}.".format(os.path.join(processedDir, f))
                    executionNumbers = []
                    break
                data = fObj.read()
                fObj.close()
                if data != "NO" and data != "YES":
                    print "Warning! Expected 'YES' or 'NO' in {0}, but found '{1}'.".format(
                        os.path.join(processedDir, f), data
Example #11
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'name':
            if self.name != '':
                parseError( 'Name already set: {0}'.format( self.name ) )
            if not isValidName( value ):
                parseError( '"{0}" is not a valid name'.format( value ) )
            if value in self.scenario.getObjectsDict('host'):
                parseError( 'Host object called {0} already exists'.format( value ) )
            self.name = value
        elif key == 'preparation':
            parseError( 'The preparation parameter was badly supported under version 1 and has been deprecated. If you need this parameter, please contact the developers of the framework to discuss support.' )
        elif key == 'cleanup':
            parseError( 'The cleanup parameter was badly supported under version 1 and has been deprecated. If you need this parameter, please contact the developers of the framework to discuss support.' )
        elif key == 'remoteFolder' or key == 'remoteDirectory':
            if self.remoteDirectory:
                parseError( 'Remote directory already set' )
            if value != '':
                self.remoteDirectory = value
        elif key == 'tc_iface' or key == 'tcInterface':
            if self.tcInterface:
                parseError( 'Only one interface for TC allowed' )
            if value == '':
                parseError( 'Empty interface for TC found, but an interface is required' )
            self.tcInterface = value
            self.tcParamsSet = True
        elif key == 'tc_down' or key == 'tcMaxDownSpeed':
            if self.tcDown != 0:
                parseError( 'Maximum download speed for TC already set' )
            self.tcDown = checkSpeedValue( value, 'Maximum download speed' )
            self.tcParamsSet = True
        elif key == 'tc_down_burst' or key == 'tcMaxDownBurst':
            if self.tcDownBurst != 0:
                parseError( 'Maximum download burst for TC already set' )
            self.tcDownBurst = checkSpeedValue( value, 'Maximum download burst' )
            self.tcParamsSet = True
        elif key == 'tc_up' or key == 'tcMaxUpSpeed':
            if self.tcUp != 0:
                parseError( 'Maximum upload speed for TC already set' )
            self.tcUp = checkSpeedValue( value, 'Maximum upload speed' )
            self.tcParamsSet = True
        elif key == 'tc_up_burst' or key == 'tcMaxUpBurst':
            if self.tcUpBurst != 0:
                parseError( 'Maximum upload burst for TC already set' )
            self.tcUpBurst = checkSpeedValue( value, 'Maximum upload burst' )
            self.tcParamsSet = True
        elif key == 'tc':
            if self.tc != '':
                parseError( 'TC module already set' )
            if value == '':
                return
            if not isValidName( value ):
                parseError( 'Name given as name of TC module is not a valid name: {0}'.format( value ) )
            __import__( 'modules.tc.'+value, globals(), locals(), value )    # Just checks availability
            self.tc = value
        elif key == 'tc_loss' or key == 'tcLossChance':
            if self.tcLoss != 0:
                parseError( 'Loss chance for TC already set' )
            if (not isPositiveFloat( value )) or float(value) > 100:
                parseError( 'Loss chance for TC should be a floating point number >= 0.0 and <= 100.0, unlike {0}'.format( value ) )
            self.tcLoss = float(value)
        elif key == 'tc_corruption' or key == 'tcCorruptionChance':
            if self.tcCorruption != 0:
                parseError( 'Corruption chance for TC already set' )
            if (not isPositiveFloat( value )) or float(value) > 100:
                parseError( 'Corruption chance for TC should be a floating point number >= 0.0 and <= 100.0, unlike {0}'.format( value ) )
            self.tcCorruption = float(value)
        elif key == 'tc_duplication' or key == 'tcDuplicationChance':
            if self.tcDuplication != 0:
                parseError( 'Duplication chance for TC already set' )
            if (not isPositiveFloat( value )) or float(value) > 100:
                parseError( 'Duplication chance for TC should be a floating point number >= 0.0 and <= 100.0, unlike {0}'.format( value ) )
            self.tcDuplication = float(value)
        elif key == 'tc_delay' or key == 'tcDelay':
            if self.tcDelay != 0:
                parseError( 'Delay for TC already set' )
            if not isPositiveInt( value ):
                parseError( 'Delay for TC should be a positive integer denoting the delay in ms, unlike {0}'.format( value ) )
            self.tcDelay = int(value)
        elif key == 'tc_jitter' or key == 'tcJitter':
            if self.tcJitter != 0:
                parseError( 'Jitter in the delay for TC already set' )
            if not isPositiveInt( value ):
                parseError( 'Jitter in the delay for TC should be a positive integer denoting the maximum deviation in the delay for TC in ms, unlike {0}'.format( value ) )
            self.tcJitter = int(value)
        else:
            parseError( 'Unknown parameter name: {0}'.format( key ) )
Example #12
0
    def parseSetting(self, key, value):
        """
        Parse a single setting for this object.

        Settings are written in text files in a key=value fashion.
        For each such setting that belongs to this object this method will be called.

        After all settings have been given, the method checkSettings will be called.

        If a setting does not parse correctly, this method raises an Exception with a descriptive message.

        Subclassers should first parse their own settings and then call this implementation to have the
        generic settings parsed and to have any unknown settings raise an Exception.
        
        @param  key     The name of the parameter, i.e. the key from the key=value pair.
        @param  value   The value of the parameter, i.e. the value from the key=value pair.
        """
        if key == 'host':
            if self.hostName:
                parseError( "A host was already given: {0}".format( self.hostName ) )
            if not isValidName( value ):
                if not isValidName( value[:value.find('@')]):
                    parseError( "{0} is not a valid host object name".format( value ) )
            self.hostName = value
        elif key == 'client':
            if self.clientName:
                parseError( "A client was already given: {0}".format( self.clientName ) )
            if not isValidName( value ):
                if not isValidName( value[:value.find('@')]):
                    parseError( "{0} is not a valid client object name".format( value ) )
            self.clientName = value
        elif key == 'file':
            if not isValidName( value ):
                if not isValidName( value[:value.find('@')]):
                    parseError( "{0} is not a valid file object name".format( value ) )
            if not self.fileNames:
                self.fileNames = [value]
            elif value not in self.fileNames:
                self.fileNames.append(value)
            else:
                Campaign.logger.log( "Warning for execution object on line {0}: file object {1} already added".format( Campaign.currentLineNumber, value ) )
        elif key == 'parser':
            if not isValidName( value ):
                parseError( "{0} is not a valif parser object name".format( value ) )
            if not self.parserNames:
                self.parserNames = []
            self.parserNames.append( value )
        elif key == 'seeder':
            if value != '':
                self.seeder = True
        elif key == 'timeout':
            if self.timeout != None:
                parseError( "The timeout was already set: {0}".format( self.timeout ) )
            if not isPositiveFloat( value ):
                parseError( "The timeout must be a non-negative floating point number." )
            self.timeout = float(value)
        elif key == 'keepSeeding':
            if value != '':
                self.keepSeeding = True
        elif key == 'multiply':
            if self.multiply is not None:
                parseError( "Multiply already set: {0}".format( self.multiply ) )
            if not isPositiveInt(value, True):
                parseError( "The multiply parameter must be a non-zero positive integer." )
            self.multiply = int(value)
        else:
            parseError( 'Unknown parameter name: {0}'.format( key ) )