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 ) )
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)
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)
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)
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)
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)
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)
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
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)
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
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 ) )
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 ) )