def stopAviwestBwTest(self): status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText( 'red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) serialOutputUntilTimeout = self.writeToSerial( 'abus-send sst-tx.BandwidthTestStop', ['bitrate='], 30) myRe = re.search('bitrate=[0-9]+', serialOutputUntilTimeout) # estimatedBitrate in kbps estimatedBitrate = int(re.sub('bitrate=', '', myRe.group())) estimatedBitrate = estimatedBitrate / 1000 if globals.verbose: utils.displayText('yellow', 'estimatedBitrate : %s' % estimatedBitrate, 0) self.writeToSerial( 'while ! abus-send sst-tx.get CommandReady | grep CommandReady=true; do sleep 1; done', ['CommandReady=true'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText( 'red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) return estimatedBitrate
def deserializeObject(): utils.displayText("blue", "deserializing full object from %s" % globals.jsonFileName, 0) if os.path.isfile(globals.jsonFileName): with open(globals.jsonFileName, "r") as f: myJson = json.load(f) else: utils.displayText("red", "file %s does not exist, run combineParameters.py first" % globals.jsonFileName, 0) utils.terminateTest(1) # deserialize scenParameters only possible if globals.scenarioId has been set if globals.scenarioId != -1: scenParameters = myJson["%06d" % globals.scenarioId] globals.scenarioComment = scenParameters["scenarioComment"] globals.scenarioEvolution = scenParameters["scenarioEvolution"] globals.scenarioDuration = int(scenParameters["scenarioDuration"]) globals.actionMode = scenParameters["actionMode"] globals.overEncodedBitrate = int(scenParameters["overEncodedBitrate"]) globals.audioBitrate = int(scenParameters["audioBitrate"]) globals.videoBitrateMode = scenParameters["videoBitrateMode"] globals.videoBitrate = int(scenParameters["videoBitrate"]) globals.frameRate = int(scenParameters["frameRate"]) globals.gopDuration = int(scenParameters["gopDuration"]) globals.iFramesVsPandBFramesRatio = int(scenParameters["iFramesVsPandBFramesRatio"]) globals.timeWindow = int(scenParameters["timeWindow"]) globals.gatewayBandWidth = int(scenParameters["gateway"]["bandWidth"]) globals.gatewayFixedLatency = int(scenParameters["gateway"]["fixedLatency"]) globals.gatewayInstantJitter = int(scenParameters["gateway"]["jitter"]) globals.gatewayQueueLength = int(scenParameters["gateway"]["queueLength"]) globals.gatewayPacketsLoss = int(scenParameters["gateway"]["packetsLoss"]) globals.nbOfEthAdapters = int(scenParameters["nbOfEthAdapters"]) for i in range(globals.nbOfEthAdapters): globals.ethAdaptersFixedLatenciesList.append(scenParameters["ethAdapters"][i]["fixedLatency"]) globals.ethAdaptersJittersList.append(scenParameters["ethAdapters"][i]["jitter"]) globals.ethAdaptersBandWidthsList.append(scenParameters["ethAdapters"][i]["bandWidth"]) globals.ethAdaptersPacketLossList.append(scenParameters["ethAdapters"][i]["packetsLoss"]) globals.ethAdaptersQueueLengthList.append(scenParameters["ethAdapters"][i]["queueLength"]) globals.nbOfUsbEthAdapters = int(scenParameters["nbOfUsbEthAdapters"]) for i in range(globals.nbOfUsbEthAdapters): globals.usbEthAdaptersFixedLatenciesList.append(scenParameters["usbEthAdapters"][i]["fixedLatency"]) globals.usbEthAdaptersJittersList.append(scenParameters["usbEthAdapters"][i]["jitter"]) globals.usbEthAdaptersBandWidthsList.append(scenParameters["usbEthAdapters"][i]["bandWidth"]) globals.usbEthAdaptersPacketLossList.append(scenParameters["usbEthAdapters"][i]["packetsLoss"]) globals.usbEthAdaptersQueueLengthList.append(scenParameters["usbEthAdapters"][i]["queueLength"]) globals.nbOfWifiAdapters = int(scenParameters["nbOfWifiAdapters"]) for i in range(globals.nbOfWifiAdapters): globals.wifiAdaptersFixedLatenciesList.append(scenParameters["wifiAdapters"][i]["fixedLatency"]) globals.wifiAdaptersJittersList.append(scenParameters["wifiAdapters"][i]["jitter"]) globals.wifiAdaptersBandWidthsList.append(scenParameters["wifiAdapters"][i]["bandWidth"]) globals.wifiAdaptersPacketLossList.append(scenParameters["wifiAdapters"][i]["packetsLoss"]) globals.wifiAdaptersQueueLengthList.append(scenParameters["wifiAdapters"][i]["queueLength"]) globals.lastScenarioId = myJson["lastScenarioId"]
def getNetworkInterfaceLinkStatus(networkInterface): utils.displayText( 'red', 'TODO : testing an IP alias with ethtool always report : \'Link detected: yes\'. It cannot be used here.', 0) utils.terminateTest(1) command = ['/usr/bin/sudo', '/sbin/ethtool', networkInterface] commandStdout, commandStderr = utils.executeCommand(command) # get "Link detected:" myRe = re.search('Link detected: yes|no', commandStdout) linkDetected = re.sub('Link detected: ', '', myRe.group()) if linkDetected == 'yes': networkInterfaceStatus = 'up' elif linkDetected == 'no': networkInterfaceStatus = 'down' else: utils.displayText( 'red', '[KO] linkDetected (%s) is neither \'yes\', nor \'no\'' % linkDetected, 0) utils.terminateTest(1) return networkInterfaceStatus
def setNetworkInterfaceState(self, interfaceName, requestedState): # check requestedState values if (requestedState != 'up') and (requestedState != 'down'): utils.displayText('red', '[KO] requestedState (%s) is neither \'up\', nor \'down\'' % requestedState, 0) utils.terminateTest(1) self.writeToSerial('ifconfig %s %s' % (interfaceName, requestedState), [], 10)
def setAllNetworkInterfacesState(self, requestedState): # check requestedState values if (requestedState != 'up') and (requestedState != 'down'): utils.displayText('red', '[KO] requestedState (%s) is neither \'up\', nor \'down\'' % requestedState, 0) utils.terminateTest(1) # do not modify controlNetworkInterface here... (when connected to the device through ssh, we do not want to disable this link) utils.displayText('cyan', 'setting up ethAdaptersInterfacesList in state %s' % requestedState, 0) for i in range(len(self.ethAdaptersInterfacesList)): interfaceName = self.ethAdaptersInterfacesList[i][0] self.setNetworkInterfaceState(interfaceName, requestedState) if (requestedState == 'up'): defaultGateway = self.ethAdaptersInterfacesList[i][5] self.setNetworkInterfaceDefaultGw(interfaceName, defaultGateway) utils.displayText('cyan', 'setting up usbEthAdaptersInterfacesList in state %s' % requestedState, 0) for i in range(len(self.usbEthAdaptersInterfacesList)): interfaceName = self.usbEthAdaptersInterfacesList[i][0] self.setNetworkInterfaceState(interfaceName, requestedState) if (requestedState == 'up'): defaultGateway = self.usbEthAdaptersInterfacesList[i][5] self.setNetworkInterfaceDefaultGw(interfaceName, defaultGateway) utils.displayText('cyan', 'setting up wifiAdaptersInterfacesList in state %s' % requestedState, 0) for i in range(len(self.wifiAdaptersInterfacesList)): interfaceName = self.wifiAdaptersInterfacesList[i][0] self.setNetworkInterfaceState(interfaceName, requestedState) if (requestedState == 'up'): defaultGateway = self.wifiAdaptersInterfacesList[i][5] self.setNetworkInterfaceDefaultGw(interfaceName, defaultGateway)
def startAviwestStreaming(self, timeWindow): self.writeToSerial( 'abus-send sst-tx.StreamConnect timewindow=%s' % timeWindow, [ 'New timewindow %d ms' % timeWindow, 'Aggreg WAIT_RESP->CONNECTED' ], 30) self.writeToSerial( 'while ! abus-send sst-tx.get CommandReady | grep CommandReady=true; do sleep 1; done', ['CommandReady=true'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText( 'red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) self.writeToSerial('abus-send sst-tx.StreamStart', ['tx_aggreg_do_cmd: CONNECTED\(StreamStart\)'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText( 'red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1)
def stopAviwestStreaming(self): #serialOutputUntilTimeout = self.writeToSerial('abus-send sst-tx.ConnectionStop', ['Aggreg STREAMING->DISCONNECTED'], 30) serialOutputUntilTimeout = self.writeToSerial('abus-send sst-tx.StreamStop', ['Aggreg STREAMING->DISCONNECTED'], 30) # set minVideoBitrate, maxVideoBitrate and avgVideoBitrate from serialOutputUntilTimeout regularExpression = 'Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg [0-9]+ kbps' myRe = re.search(regularExpression, serialOutputUntilTimeout) if myRe == None: utils.displayText('red', 'regular expression \"%s\" not found in serialOutputUntilTimeout' % regularExpression, 0) utils.displayText('red', 'serialOutputUntilTimeout :\n%s' % serialOutputUntilTimeout, 0) utils.terminateTest(1) minVideoBitrate = re.sub('Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min', '', myRe.group()) minVideoBitrate = re.sub('kbps, max [0-9]+ kbps, avg [0-9]+ kbps', '', minVideoBitrate) minVideoBitrate = int(minVideoBitrate) maxVideoBitrate = re.sub('Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max ', '', myRe.group()) maxVideoBitrate = re.sub('kbps, avg [0-9]+ kbps', '', maxVideoBitrate) maxVideoBitrate = int(maxVideoBitrate) avgVideoBitrate = re.sub('Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg ', '', myRe.group()) avgVideoBitrate = re.sub(' kbps', '', avgVideoBitrate) avgVideoBitrate = int(avgVideoBitrate) # set minAudioBitrate, maxAudioBitrate and avgAudioBitrate from serialOutputUntilTimeout regularExpression = 'Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg [0-9]+ kbps' myRe = re.search(regularExpression, serialOutputUntilTimeout) if myRe == None: utils.displayText('red', 'regular expression \"%s\" not found in serialOutputUntilTimeout' % regularExpression, 0) utils.displayText('red', 'serialOutputUntilTimeout :\n%s' % serialOutputUntilTimeout, 0) utils.terminateTest(1) minAudioBitrate = re.sub('Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min', '', myRe.group()) minAudioBitrate = re.sub('kbps, max [0-9]+ kbps, avg [0-9]+ kbps', '', minAudioBitrate) minAudioBitrate = int(minAudioBitrate) maxAudioBitrate = re.sub('Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max ', '', myRe.group()) maxAudioBitrate = re.sub('kbps, avg [0-9]+ kbps', '', maxAudioBitrate) maxAudioBitrate = int(maxAudioBitrate) avgAudioBitrate = re.sub('Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg ', '', myRe.group()) avgAudioBitrate = re.sub(' kbps', '', avgAudioBitrate) avgAudioBitrate = int(avgAudioBitrate) if globals.verbose: utils.displayText('yellow', 'minVideoBitrate : %d' % minVideoBitrate, 0) utils.displayText('yellow', 'maxVideoBitrate : %d' % maxVideoBitrate, 0) utils.displayText('yellow', 'avgVideoBitrate : %d' % avgVideoBitrate, 0) utils.displayText('yellow', 'minAudioBitrate : %d' % minAudioBitrate, 0) utils.displayText('yellow', 'maxAudioBitrate : %d' % maxAudioBitrate, 0) utils.displayText('yellow', 'avgAudioBitrate : %d' % avgAudioBitrate, 0) self.writeToSerial('abus-send sst-tx.terminate', ['res=0'], 30) return minVideoBitrate, maxVideoBitrate, avgVideoBitrate, minAudioBitrate, maxAudioBitrate, avgAudioBitrate
def setNetworkInterfaceState(self, interfaceName, requestedState): # check requestedState values if (requestedState != 'up') and (requestedState != 'down'): utils.displayText( 'red', '[KO] requestedState (%s) is neither \'up\', nor \'down\'' % requestedState, 0) utils.terminateTest(1) self.writeToSerial('ifconfig %s %s' % (interfaceName, requestedState), [], 10)
def startAviwestBwTest(self): self.writeToSerial('abus-send sst-tx.BandwidthTestConnect', ['Aggreg WAIT_RESP->CONNECTED'], 30) self.writeToSerial('while ! abus-send sst-tx.get CommandReady | grep CommandReady=true; do sleep 1; done', ['CommandReady=true'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText('red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) self.writeToSerial('abus-send sst-tx.BandwidthTestStart', ['Aggreg CONNECTED->BW_TEST'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText('red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1)
def startAviwestStreaming(self, timeWindow): self.writeToSerial('abus-send sst-tx.StreamConnect timewindow=%s' % timeWindow, ['New timewindow %d ms' % timeWindow, 'Aggreg WAIT_RESP->CONNECTED'], 30) self.writeToSerial('while ! abus-send sst-tx.get CommandReady | grep CommandReady=true; do sleep 1; done', ['CommandReady=true'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText('red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) self.writeToSerial('abus-send sst-tx.StreamStart', ['tx_aggreg_do_cmd: CONNECTED\(StreamStart\)'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText('red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1)
def getAviwestConnectionStatus(self): self.writeToSerial('abus-send sst-tx.get ConnectionStatus', ['ConnectionStatus=true'], 30) serialOutputUntilTimeout = self.writeToSerial('abus-send sst-tx.get ConnectionResult', ['ConnectionResult=0'], 30) myRe = re.search('Connection failed', serialOutputUntilTimeout) if myRe != None: utils.displayText('red', 'returnCode : %s (ConnectionResult is not the the expected one)' % returnCode, 0) utils.displayText('red', 'Connection failed (0:OK, 1:AUTH, 2:BUSY, 3:INVALID, 4:PROTOVERS, 5:KICKED, 6:TIMEOUT, 7:CONNECTION_LOST)', 0) utils.displayText('red', 'serialOutputUntilTimeout :\n%s' % serialOutputUntilTimeout, 0) utils.terminateTest(1) status = 'TODO' return status
def setState(networkInterface, requestedState): # check requestedState values if (requestedState != 'up') and (requestedState != 'down'): utils.displayText('red', '[KO] requestedState (%s) is neither \'up\', nor \'down\'' % requestedState, 0) utils.terminateTest(1) if requestedState == 'down': command = ['/usr/bin/sudo', '/sbin/ifdown', networkInterface] if requestedState == 'up': command = ['/usr/bin/sudo', '/sbin/ifup', networkInterface] commandStdout, commandStderr = utils.executeCommand(command) '''
def setState(networkInterface, requestedState): # check requestedState values if (requestedState != 'up') and (requestedState != 'down'): utils.displayText( 'red', '[KO] requestedState (%s) is neither \'up\', nor \'down\'' % requestedState, 0) utils.terminateTest(1) if requestedState == 'down': command = ['/usr/bin/sudo', '/sbin/ifdown', networkInterface] if requestedState == 'up': command = ['/usr/bin/sudo', '/sbin/ifup', networkInterface] commandStdout, commandStderr = utils.executeCommand(command) '''
def buildStudioSstTx(): '''buildStudioSstTx executable will be launched on dmng ''' if not os.path.isfile(globals.sourcesDirectory + '/' + '.svn/entries'): utils.displayText('red', 'globals.sourcesDirectory is not a svn working copy, call getNewAppliSvnWc first', 0) utils.terminateTest(1) commandsList = [] commandsList.append(['CROSS_COMPILE=arm-linux-', 'PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', 'init', '--directory', globals.sourcesDirectory]) commandsList.append(['CROSS_COMPILE=arm-linux-', 'PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', '--directory', globals.sourcesDirectory]) commandsList.append(['test', '-x', globals.sstTxBinary]) for command in commandsList: commandStdout, commandStderr = utils.executeCommand(command)
def start(self): '''run command on self.host_name in background (through ssh on port self.port) @param command : command to launch @return process ID ''' commandsList = [] commandsList.append([ '/usr/bin/ssh', '-T', '-p', '%d' % self.port, '%s' % self.host_name, 'test -x %s' % globals.gatewaySstRxBinary ]) commandsList.append(['test', '-x', globals.sstRxBinary]) for command in commandsList: commandStdout, commandStderr = utils.executeCommand(command) command = [ '/usr/bin/ssh', '-T', '-p', '%d' % self.port, '%s' % self.host_name, '%s -v -T -L %s -l %s:%s' % (globals.gatewaySstRxBinary, globals.gatewaySstRxLogFile, globals.gatewaySstRxLogin, globals.gatewaySstRxPassword) ] commandString = ' '.join(command) if not globals.quiet: utils.displayText('normal', 'executing command : %s' % commandString, 0) self.ssh = subprocess.Popen(command, bufsize=-1, shell=False, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={'LANG': 'en_GB.utf-8'}) if self.ssh == None: utils.displayText( 'red', '[KO] the following command failed : %s' % ' '.join(command), 0) utils.terminateTest(1)
def setAllNetworkInterfacesState(self, requestedState): # check requestedState values if (requestedState != 'up') and (requestedState != 'down'): utils.displayText( 'red', '[KO] requestedState (%s) is neither \'up\', nor \'down\'' % requestedState, 0) utils.terminateTest(1) # do not modify controlNetworkInterface here... (when connected to the device through ssh, we do not want to disable this link) utils.displayText( 'cyan', 'setting up ethAdaptersInterfacesList in state %s' % requestedState, 0) for i in range(len(self.ethAdaptersInterfacesList)): interfaceName = self.ethAdaptersInterfacesList[i][0] self.setNetworkInterfaceState(interfaceName, requestedState) if (requestedState == 'up'): defaultGateway = self.ethAdaptersInterfacesList[i][5] self.setNetworkInterfaceDefaultGw(interfaceName, defaultGateway) utils.displayText( 'cyan', 'setting up usbEthAdaptersInterfacesList in state %s' % requestedState, 0) for i in range(len(self.usbEthAdaptersInterfacesList)): interfaceName = self.usbEthAdaptersInterfacesList[i][0] self.setNetworkInterfaceState(interfaceName, requestedState) if (requestedState == 'up'): defaultGateway = self.usbEthAdaptersInterfacesList[i][5] self.setNetworkInterfaceDefaultGw(interfaceName, defaultGateway) utils.displayText( 'cyan', 'setting up wifiAdaptersInterfacesList in state %s' % requestedState, 0) for i in range(len(self.wifiAdaptersInterfacesList)): interfaceName = self.wifiAdaptersInterfacesList[i][0] self.setNetworkInterfaceState(interfaceName, requestedState) if (requestedState == 'up'): defaultGateway = self.wifiAdaptersInterfacesList[i][5] self.setNetworkInterfaceDefaultGw(interfaceName, defaultGateway)
def getNetworkInterfaceLinkStatus(networkInterface): utils.displayText('red', 'TODO : testing an IP alias with ethtool always report : \'Link detected: yes\'. It cannot be used here.', 0) utils.terminateTest(1) command = ['/usr/bin/sudo', '/sbin/ethtool', networkInterface] commandStdout, commandStderr = utils.executeCommand(command) # get "Link detected:" myRe = re.search('Link detected: yes|no', commandStdout) linkDetected = re.sub('Link detected: ', '', myRe.group()) if linkDetected == 'yes': networkInterfaceStatus = 'up' elif linkDetected == 'no': networkInterfaceStatus = 'down' else: utils.displayText('red', '[KO] linkDetected (%s) is neither \'yes\', nor \'no\'' % linkDetected, 0) utils.terminateTest(1) return networkInterfaceStatus
def stopAviwestBwTest(self): status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText('red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) serialOutputUntilTimeout = self.writeToSerial('abus-send sst-tx.BandwidthTestStop', ['bitrate='], 30) myRe = re.search('bitrate=[0-9]+', serialOutputUntilTimeout) # estimatedBitrate in kbps estimatedBitrate = int(re.sub('bitrate=', '', myRe.group())) estimatedBitrate = estimatedBitrate / 1000 if globals.verbose: utils.displayText('yellow', 'estimatedBitrate : %s' % estimatedBitrate, 0) self.writeToSerial('while ! abus-send sst-tx.get CommandReady | grep CommandReady=true; do sleep 1; done', ['CommandReady=true'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText('red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) return estimatedBitrate
def expectStringsOnSerial(self, expectedStringsList, timeout): # initializations serialOutputUntilTimeout = '' partialSerialOutputUntilTimeout = '' if globals.verbose: utils.displayText('normal', 'expecting strings list (%s) on serial %s (timeout : %d seconds)' % (expectedStringsList, self.ser.portstr, timeout), 0) # Set the signal handler and a timeout second alarm signal.alarm(timeout) try: stringsFoundList = [] while len(expectedStringsList) != 0: data = self.ser.read(self.ser.inWaiting()) # store data in serialOutputUntilTimeout if data != b'': data = bytes.decode(data) serialOutputUntilTimeout += data partialSerialOutputUntilTimeout += data for expectedString in expectedStringsList: if re.search(expectedString, partialSerialOutputUntilTimeout) != None: if not globals.quiet: utils.displayText('green', '[OK] expected string (%s) found' % expectedString, 0) stringsFoundList.append(expectedString) # use partialSerialOutputUntilTimeout to remove found strings as soon as they are found : usefull when expecting the same string several times in serialOutputUntilTimeout partialSerialOutputUntilTimeout = re.sub(expectedString, '', partialSerialOutputUntilTimeout) # update expectedStringsList for the next pass for string in stringsFoundList: if expectedStringsList.count(string) != 0: expectedStringsList.remove(string) except TimeoutException: utils.displayText('red', '[KO] expectedString (%s) not found' % expectedString, 0) utils.displayText('red', '----- serialOutputUntilTimeout -----', 0) utils.displayText('normal', serialOutputUntilTimeout, 0) utils.displayText('red', '------------------------------------', 0) returnCode = utils.terminateTest(1) return returnCode finally: # cancel alaram signal.alarm(0) if globals.verbose: utils.displayText('normal', '----- serialOutputUntilTimeout -----', 0) utils.displayText('normal', serialOutputUntilTimeout, 0) utils.displayText('normal', '------------------------------------', 0) globals.dmngLogFileHandle.write(serialOutputUntilTimeout) return serialOutputUntilTimeout
def startAviwestBwTest(self): self.writeToSerial('abus-send sst-tx.BandwidthTestConnect', ['Aggreg WAIT_RESP->CONNECTED'], 30) self.writeToSerial( 'while ! abus-send sst-tx.get CommandReady | grep CommandReady=true; do sleep 1; done', ['CommandReady=true'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText( 'red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1) self.writeToSerial('abus-send sst-tx.BandwidthTestStart', ['Aggreg CONNECTED->BW_TEST'], 30) status = self.getAviwestConnectionStatus() if status != 'connected': utils.displayText( 'red', 'status is not the expected one (current status is : %s; expected status was : connected)' % status, 0) utils.terminateTest(1)
def getAviwestConnectionStatus(self): self.writeToSerial('abus-send sst-tx.get ConnectionStatus', ['ConnectionStatus=true'], 30) serialOutputUntilTimeout = self.writeToSerial( 'abus-send sst-tx.get ConnectionResult', ['ConnectionResult=0'], 30) myRe = re.search('Connection failed', serialOutputUntilTimeout) if myRe != None: utils.displayText( 'red', 'returnCode : %s (ConnectionResult is not the the expected one)' % returnCode, 0) utils.displayText( 'red', 'Connection failed (0:OK, 1:AUTH, 2:BUSY, 3:INVALID, 4:PROTOVERS, 5:KICKED, 6:TIMEOUT, 7:CONNECTION_LOST)', 0) utils.displayText( 'red', 'serialOutputUntilTimeout :\n%s' % serialOutputUntilTimeout, 0) utils.terminateTest(1) status = 'TODO' return status
def buildStudioSstRx(): '''buildStudioSstRx executable will be launched on studio-sst-rx (x86) ''' if not os.path.isfile(globals.sourcesDirectory + '/' + '.svn/entries'): utils.displayText('red', 'globals.sourcesDirectory is not a svn working copy, call getNewAppliSvnWc first', 0) utils.terminateTest(1) if os.path.isdir(globals.sstRxBuildDirectory): shutil.rmtree(globals.sstRxBuildDirectory) os.makedirs(globals.sstRxBuildDirectory) # make init mandatory here (to generated the configure file) os.chdir(globals.sourcesDirectory) commandsList = [] commandsList.append(['CROSS_COMPILE=arm-linux-', 'PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', 'init', '--directory', globals.sourcesDirectory]) #commandsList.append(['PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', 'init', '--directory', globals.sourcesDirectory]) for command in commandsList: commandStdout, commandStderr = utils.executeCommand(command) os.chdir(globals.sstRxBuildDirectory) commandsList = [] #commandsList.append(['PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', 'init', '--directory', globals.sourcesDirectory]) commandsList.append(['PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), '%s/aggreg-sst/aggreg-sst/configure --enable-maintainer-mode --enable-sst-rx-only --prefix=$(pwd)/inst' % globals.sourcesDirectory]) commandsList.append(['PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', '--directory', globals.sstRxBuildDirectory]) commandsList.append(['test', '-x', '%s/Build/_install/bin/sst-tx' % globals.sourcesDirectory]) commandsList.append(['PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', '--directory', '%s/aggreg-common' % globals.sstRxBuildDirectory]) commandsList.append(['PATH=%s/ccache:%s:$PATH' % (armCompilerDirectory, armCompilerDirectory), 'make', '--directory', '%s/aggreg-studio' % globals.sstRxBuildDirectory]) commandsList.append(['test -x %s' % globals.sstRxBinary]) for command in commandsList: commandStdout, commandStderr = utils.executeCommand(command)
def start(self): '''run command on self.host_name in background (through ssh on port self.port) @param command : command to launch @return process ID ''' commandsList = [] commandsList.append(['/usr/bin/ssh', '-T', '-p', '%d' % self.port, '%s' % self.host_name, 'test -x %s' % globals.gatewaySstRxBinary]) commandsList.append(['test', '-x', globals.sstRxBinary]) for command in commandsList: commandStdout, commandStderr = utils.executeCommand(command) command = ['/usr/bin/ssh', '-T', '-p', '%d' % self.port, '%s' % self.host_name, '%s -v -T -L %s -l %s:%s' % (globals.gatewaySstRxBinary, globals.gatewaySstRxLogFile, globals.gatewaySstRxLogin, globals.gatewaySstRxPassword)] commandString = ' '.join(command) if not globals.quiet: utils.displayText('normal', 'executing command : %s' % commandString, 0) self.ssh = subprocess.Popen(command, bufsize=-1, shell = False, stdin = None, stdout = subprocess.PIPE, stderr = subprocess.PIPE, env={'LANG':'en_GB.utf-8'}) if self.ssh == None: utils.displayText('red', '[KO] the following command failed : %s' % ' '.join(command), 0) utils.terminateTest(1)
def waitForAviwestConnectionStatus(self): utils.displayText('red', 'TODO', 0) utils.terminateTest(1) self.getAviwestConnectionStatus()
def expectStringsOnSerial(self, expectedStringsList, timeout): # initializations serialOutputUntilTimeout = '' partialSerialOutputUntilTimeout = '' if globals.verbose: utils.displayText( 'normal', 'expecting strings list (%s) on serial %s (timeout : %d seconds)' % (expectedStringsList, self.ser.portstr, timeout), 0) # Set the signal handler and a timeout second alarm signal.alarm(timeout) try: stringsFoundList = [] while len(expectedStringsList) != 0: data = self.ser.read(self.ser.inWaiting()) # store data in serialOutputUntilTimeout if data != b'': data = bytes.decode(data) serialOutputUntilTimeout += data partialSerialOutputUntilTimeout += data for expectedString in expectedStringsList: if re.search(expectedString, partialSerialOutputUntilTimeout) != None: if not globals.quiet: utils.displayText( 'green', '[OK] expected string (%s) found' % expectedString, 0) stringsFoundList.append(expectedString) # use partialSerialOutputUntilTimeout to remove found strings as soon as they are found : usefull when expecting the same string several times in serialOutputUntilTimeout partialSerialOutputUntilTimeout = re.sub( expectedString, '', partialSerialOutputUntilTimeout) # update expectedStringsList for the next pass for string in stringsFoundList: if expectedStringsList.count(string) != 0: expectedStringsList.remove(string) except TimeoutException: utils.displayText( 'red', '[KO] expectedString (%s) not found' % expectedString, 0) utils.displayText('red', '----- serialOutputUntilTimeout -----', 0) utils.displayText('normal', serialOutputUntilTimeout, 0) utils.displayText('red', '------------------------------------', 0) returnCode = utils.terminateTest(1) return returnCode finally: # cancel alaram signal.alarm(0) if globals.verbose: utils.displayText('normal', '----- serialOutputUntilTimeout -----', 0) utils.displayText('normal', serialOutputUntilTimeout, 0) utils.displayText('normal', '------------------------------------', 0) globals.dmngLogFileHandle.write(serialOutputUntilTimeout) return serialOutputUntilTimeout
def stopAviwestStreaming(self): #serialOutputUntilTimeout = self.writeToSerial('abus-send sst-tx.ConnectionStop', ['Aggreg STREAMING->DISCONNECTED'], 30) serialOutputUntilTimeout = self.writeToSerial( 'abus-send sst-tx.StreamStop', ['Aggreg STREAMING->DISCONNECTED'], 30) # set minVideoBitrate, maxVideoBitrate and avgVideoBitrate from serialOutputUntilTimeout regularExpression = 'Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg [0-9]+ kbps' myRe = re.search(regularExpression, serialOutputUntilTimeout) if myRe == None: utils.displayText( 'red', 'regular expression \"%s\" not found in serialOutputUntilTimeout' % regularExpression, 0) utils.displayText( 'red', 'serialOutputUntilTimeout :\n%s' % serialOutputUntilTimeout, 0) utils.terminateTest(1) minVideoBitrate = re.sub( 'Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min', '', myRe.group()) minVideoBitrate = re.sub('kbps, max [0-9]+ kbps, avg [0-9]+ kbps', '', minVideoBitrate) minVideoBitrate = int(minVideoBitrate) maxVideoBitrate = re.sub( 'Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max ', '', myRe.group()) maxVideoBitrate = re.sub('kbps, avg [0-9]+ kbps', '', maxVideoBitrate) maxVideoBitrate = int(maxVideoBitrate) avgVideoBitrate = re.sub( 'Stream\(Video\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg ', '', myRe.group()) avgVideoBitrate = re.sub(' kbps', '', avgVideoBitrate) avgVideoBitrate = int(avgVideoBitrate) # set minAudioBitrate, maxAudioBitrate and avgAudioBitrate from serialOutputUntilTimeout regularExpression = 'Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg [0-9]+ kbps' myRe = re.search(regularExpression, serialOutputUntilTimeout) if myRe == None: utils.displayText( 'red', 'regular expression \"%s\" not found in serialOutputUntilTimeout' % regularExpression, 0) utils.displayText( 'red', 'serialOutputUntilTimeout :\n%s' % serialOutputUntilTimeout, 0) utils.terminateTest(1) minAudioBitrate = re.sub( 'Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min', '', myRe.group()) minAudioBitrate = re.sub('kbps, max [0-9]+ kbps, avg [0-9]+ kbps', '', minAudioBitrate) minAudioBitrate = int(minAudioBitrate) maxAudioBitrate = re.sub( 'Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max ', '', myRe.group()) maxAudioBitrate = re.sub('kbps, avg [0-9]+ kbps', '', maxAudioBitrate) maxAudioBitrate = int(maxAudioBitrate) avgAudioBitrate = re.sub( 'Stream\(Audio\) [0-9a-f]+ rtp_gen_stats: ordered_bitrate min [0-9]+ kbps, max [0-9]+ kbps, avg ', '', myRe.group()) avgAudioBitrate = re.sub(' kbps', '', avgAudioBitrate) avgAudioBitrate = int(avgAudioBitrate) if globals.verbose: utils.displayText('yellow', 'minVideoBitrate : %d' % minVideoBitrate, 0) utils.displayText('yellow', 'maxVideoBitrate : %d' % maxVideoBitrate, 0) utils.displayText('yellow', 'avgVideoBitrate : %d' % avgVideoBitrate, 0) utils.displayText('yellow', 'minAudioBitrate : %d' % minAudioBitrate, 0) utils.displayText('yellow', 'maxAudioBitrate : %d' % maxAudioBitrate, 0) utils.displayText('yellow', 'avgAudioBitrate : %d' % avgAudioBitrate, 0) self.writeToSerial('abus-send sst-tx.terminate', ['res=0'], 30) return minVideoBitrate, maxVideoBitrate, avgVideoBitrate, minAudioBitrate, maxAudioBitrate, avgAudioBitrate
def startEncoder(self): # kohala -video_source 0 : generator (GENERATOR=0, ANALOG=1, SDI=2, HDMI=3) self.writeToSerial('kohala -video_source 0', [], 10) # kohala -video_generator 64 2 # PAL COLOR_CIRCLES # standard # VIDEO_STANDARD_NTSC_BT656_4 = 0, = 0x0 # VIDEO_STANDARD_PAL = 64, = 0x40 # VIDEO_STANDARD_720p59_94 = 152, = 0x98 # VIDEO_STANDARD_720p50 = 146, = 0x92 # VIDEO_STANDARD_1080i59_94 = 200, = 0xC8 # VIDEO_STANDARD_1080i50 = 193, = 0xC1 # VIDEO_STANDARD_1080p30 = 208, = 0xD0 # VIDEO_STANDARD_1080p25 = 209, = 0xD1 self.writeToSerial('kohala -video_generator 64 2', [], 10) ##self.writeToSerial('kohala -video_generator 193 2', [], 10) self.writeToSerial('kohala -video_rate 0', [], 10) ##self.writeToSerial('kohala -video_rate 2', [], 10) # RATE_27_MHZ = 0x0, # RATE_74_175_MHZ = 0x1, # RATE_74_25_MHZ = 0x2 self.writeToSerial('kohala -video_release', [], 10) #------ Audio encoder static parameters ------------------- # GENERATOR=0, ANALOG=1, SDI=2, HDMI=3 self.writeToSerial('enconfig -encoder 0 -audio_source 0', [], 10) # MONO=0, STEREO=1, DUAL_MONO=2 self.writeToSerial('enconfig -encoder 0 -audio_channel_mode 1', [], 10) # AACLC=0, AACHE=1, AACHEV2=2, MPEG1L2=3 self.writeToSerial('enconfig -encoder 0 -audio_enc_mode 3', [], 10) # kHz self.writeToSerial('enconfig -encoder 0 -audio_sample_rate 48000', [], 10) # Kb self.writeToSerial( 'enconfig -encoder 0 -audio_bitrate %d' % globals.audioBitrate, [], 10) # CBR=0, VBR=1, CAPPED_VBR=2 self.writeToSerial('enconfig -encoder 0 -audio_bitrate_mode 0', [], 10) # ms self.writeToSerial('enconfig -encoder 0 -audio_pts_offset 0', [], 10) #------ Video encoder static parameters ------------------- # GENERATOR=0, ANALOG=1, SDI=2, HDMI=3 self.writeToSerial('enconfig -encoder 0 -video_source 0', [], 10) # pixels self.writeToSerial('enconfig -encoder 0 -video_resolution_width 720', [], 10) ##self.writeToSerial('enconfig -encoder 0 -video_resolution_width 1920', [], 10) # pixels self.writeToSerial('enconfig -encoder 0 -video_resolution_height 576', [], 10) ##self.writeToSerial('enconfig -encoder 0 -video_resolution_height 1080', [], 10) # frame_rate * 100 (2500, 2997) self.writeToSerial( 'enconfig -encoder 0 -video_frame_rate %d' % (globals.frameRate * 100), [], 10) # PROGRESSIVE_VIDEO=0, INTERLACED_VIDEO=1, DOUBLING_FIELD_VIDEO=2, ONE_FIELD_VIDEO=3 self.writeToSerial('enconfig -encoder 0 -video_scan_mode 1', [], 10) self.writeToSerial('enconfig -encoder 0 -video_latency 0', [], 10) # Kb self.writeToSerial( 'enconfig -encoder 0 -video_bitrate %d' % globals.videoBitrate, [], 10) # CBR=0, VBR=1, CAPPED_VBR=2 if globals.videoBitrateMode == 'CBR': self.writeToSerial('enconfig -encoder 0 -video_bitrate_mode 0', [], 10) elif globals.videoBitrateMode == 'VBR': self.writeToSerial('enconfig -encoder 0 -video_bitrate_mode 1', [], 10) else: utils.displayText( 'red', 'globals.videoBitrateMode (%s) is neither CBR nor VBR', 0) utils.terminateTest(1) # kb self.writeToSerial('enconfig -encoder 0 -video_capped_bitrate 10000', [], 10) #------ Video encoder static advanced parameters ---------- # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_dyn_res_en 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_dyn_fps_en 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_gop_n 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_gop_m 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_open_gop_en 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_aspect_ratio_en 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_deinterlace_en 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_median_filter 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_dcrowl_filter 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_alq_mode 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_roi_en 0', [], 10) #------ Encoder commands ---------------------------------- self.writeToSerial('enconfig -encoder 0 -start', [], 10)
scenarioId = directorySplitList[len(directorySplitList) -2] buildScenarioHtmlPage(root, dirs, appliVersion, scenarioId) ''' if re.search(globals.baseScenariiDirectoryForResults + '/' + '[0-9]+' + '/' + '[0-9.]+~svn~[0-9]+' + '/' + 'OK$|KO$|inconclusive$', root) != None: utils.displayText('blue', 'root : %s' % root, 0) utils.displayText('red', 'dirs : %s' % dirs, 0) utils.displayText('red', 'files : %s' % files, 0) directorySplitList = root.split('/') appliVersion = directorySplitList[len(directorySplitList) -3] scenarioId = directorySplitList[len(directorySplitList) -2] scenarioResult = directorySplitList[len(directorySplitList) -1] utils.displayText('black', 'appliVersion : %s' % appliVersion, 0) utils.displayText('black', 'scenarioId : %s' % scenarioId, 0) utils.displayText('black', 'scenarioResult : %s' % scenarioResult, 0) sys.exit(1) sys.exit(1) #buildHtmlPage(root, dirs, 'scenarioId') buildRunsHtmlPage(root, dirs, appliVersion, scenarioId, scenarioResult) ''' if __name__ == '__main__': globals.scriptStartTime = time.time() buildTestReport() utils.terminateTest(0)
def startEncoder(self): # kohala -video_source 0 : generator (GENERATOR=0, ANALOG=1, SDI=2, HDMI=3) self.writeToSerial('kohala -video_source 0', [], 10) # kohala -video_generator 64 2 # PAL COLOR_CIRCLES # standard # VIDEO_STANDARD_NTSC_BT656_4 = 0, = 0x0 # VIDEO_STANDARD_PAL = 64, = 0x40 # VIDEO_STANDARD_720p59_94 = 152, = 0x98 # VIDEO_STANDARD_720p50 = 146, = 0x92 # VIDEO_STANDARD_1080i59_94 = 200, = 0xC8 # VIDEO_STANDARD_1080i50 = 193, = 0xC1 # VIDEO_STANDARD_1080p30 = 208, = 0xD0 # VIDEO_STANDARD_1080p25 = 209, = 0xD1 self.writeToSerial('kohala -video_generator 64 2', [], 10) ##self.writeToSerial('kohala -video_generator 193 2', [], 10) self.writeToSerial('kohala -video_rate 0', [], 10) ##self.writeToSerial('kohala -video_rate 2', [], 10) # RATE_27_MHZ = 0x0, # RATE_74_175_MHZ = 0x1, # RATE_74_25_MHZ = 0x2 self.writeToSerial('kohala -video_release', [], 10) #------ Audio encoder static parameters ------------------- # GENERATOR=0, ANALOG=1, SDI=2, HDMI=3 self.writeToSerial('enconfig -encoder 0 -audio_source 0', [], 10) # MONO=0, STEREO=1, DUAL_MONO=2 self.writeToSerial('enconfig -encoder 0 -audio_channel_mode 1', [], 10) # AACLC=0, AACHE=1, AACHEV2=2, MPEG1L2=3 self.writeToSerial('enconfig -encoder 0 -audio_enc_mode 3', [], 10) # kHz self.writeToSerial('enconfig -encoder 0 -audio_sample_rate 48000', [], 10) # Kb self.writeToSerial('enconfig -encoder 0 -audio_bitrate %d' % globals.audioBitrate, [], 10) # CBR=0, VBR=1, CAPPED_VBR=2 self.writeToSerial('enconfig -encoder 0 -audio_bitrate_mode 0', [], 10) # ms self.writeToSerial('enconfig -encoder 0 -audio_pts_offset 0', [], 10) #------ Video encoder static parameters ------------------- # GENERATOR=0, ANALOG=1, SDI=2, HDMI=3 self.writeToSerial('enconfig -encoder 0 -video_source 0', [], 10) # pixels self.writeToSerial('enconfig -encoder 0 -video_resolution_width 720', [], 10) ##self.writeToSerial('enconfig -encoder 0 -video_resolution_width 1920', [], 10) # pixels self.writeToSerial('enconfig -encoder 0 -video_resolution_height 576', [], 10) ##self.writeToSerial('enconfig -encoder 0 -video_resolution_height 1080', [], 10) # frame_rate * 100 (2500, 2997) self.writeToSerial('enconfig -encoder 0 -video_frame_rate %d' % (globals.frameRate * 100), [], 10) # PROGRESSIVE_VIDEO=0, INTERLACED_VIDEO=1, DOUBLING_FIELD_VIDEO=2, ONE_FIELD_VIDEO=3 self.writeToSerial('enconfig -encoder 0 -video_scan_mode 1', [], 10) self.writeToSerial('enconfig -encoder 0 -video_latency 0', [], 10) # Kb self.writeToSerial('enconfig -encoder 0 -video_bitrate %d' % globals.videoBitrate, [], 10) # CBR=0, VBR=1, CAPPED_VBR=2 if globals.videoBitrateMode == 'CBR': self.writeToSerial('enconfig -encoder 0 -video_bitrate_mode 0', [], 10) elif globals.videoBitrateMode == 'VBR': self.writeToSerial('enconfig -encoder 0 -video_bitrate_mode 1', [], 10) else: utils.displayText('red', 'globals.videoBitrateMode (%s) is neither CBR nor VBR', 0) utils.terminateTest(1) # kb self.writeToSerial('enconfig -encoder 0 -video_capped_bitrate 10000', [], 10) #------ Video encoder static advanced parameters ---------- # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_dyn_res_en 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_dyn_fps_en 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_gop_n 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_gop_m 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_open_gop_en 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_aspect_ratio_en 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_deinterlace_en 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_median_filter 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_dcrowl_filter 0', [], 10) self.writeToSerial('enconfig -encoder 0 -video_alq_mode 0', [], 10) # DISABLE=0, ENABLE=1 self.writeToSerial('enconfig -encoder 0 -video_roi_en 0', [], 10) #------ Encoder commands ---------------------------------- self.writeToSerial('enconfig -encoder 0 -start', [], 10)
def buildCommandsList(networkInterface, action, networkDeviceDriver, bandWidth, fixedLatency, instantJitter, packetsLoss, queueLength): # check action values if (action != 'add') and (action != 'change'): utils.displayText('red', '[KO] action (%s) is neither \'add\', nor \'change\'' % action, 0) utils.terminateTest(1) limitValueInBytes=100000 # packetSizeInBytes : a packet is supposed to weigh 1024 Bytes max packetSizeInBytes=1024 # TBF parameters # http://lartc.org/manpages/tc-tbf.html # limit / latency : The limit parameter is the number of bytes to queue before packets are tail dropped. LIMIT IS THE NUMBER OF BYTES THAT CAN BE QUEUED WAITING FOR TOKENS TO BECOME AVAILABLE. The limit parameter tells us how big the queue of packets waiting to be sent can be. You can also specify this the other way around by setting the latency parameter, which specifies the maximum amount of time a packet can sit in the TBF. The latter calculation takes into account the size of the bucket, the rate and possibly the peakrate (if set). These two parameters are mutually exclusive.In Linux 2.6.1 and later if you attach a qdisc to your tbf class, the limit is ignored in favor of your attached qdisc. # burst / buffer / maxburst : Size of the bucket, in bytes. This is the maximum amount of bytes that tokens can be available for instantaneously. In general, larger shaping rates require a larger buffer. For 10mbit/s on Intel, you need at least 10kbyte buffer if you want to reach your configured rate! The minimum buffer size can be calculated by dividing the rate by HZ (ARSO : equivalent to CONFIG_HZ in kernel?) On 2012_08_01, CONFIG_HZ in dmng is supposed to be set to 250 HZ. ARSO : the result is too small for tbf to behave as we expect it to do. configHz = 250 # mpu : A zero-sized packet does not use zero bandwidth. For ethernet, no packet uses less than 64 bytes. The Minimum Packet Unit determines the minimal token usage (specified in bytes) for a packet. Defaults to zero. # rate : The speed knob. See remarks above about limits! See tc(8) for units. The rate tells us how fast tokens enter the buffer. PLEASE NOTE THAT IN THE ACTUAL IMPLEMENTATION, TOKENS CORRESPOND TO BYTES, NOT PACKETS. # peakrate : Maximum depletion rate of the bucket. Limited to 1mbit/s on Intel, 10mbit/s on Alpha. THE PEAKRATE DOES NOT NEED TO BE SET, IT IS ONLY NECESSARY IF PERFECT MILLISECOND TIMESCALE SHAPING IS REQUIRED. The normal bucket is used to limit the average rate data is sent but allow bursts of traffic to go through. THE PEAKRATE BUCKET IS USED TO LIMIT THE SPEED THOSE BURSTS ARE SENT. To calculate the maximum possible peakrate, multiply the configured mtu by configHz : 1500 x 250 = 375000 bps = 375 kbps : it is not usable for our bitrates (10kbps-10Mbps). # mtu / minburst : Specifies the size of the peakrate bucket. For perfect accuracy, should be set to the MTU of the interface. If a peakrate is needed, but some burstiness is acceptable, this size can be raised. A 3000 byte minburst allows around 3mbit/s of peakrate, given 1000 byte packets. queueLengthInBytes=queueLength * packetSizeInBytes # maxburstValueInBytes in Bytes # values found by using iperf (in TCP/UDP) and making experiences if networkDeviceDriver == 'asix': # asix : usb ethernet #maxburstValueInBytes = bandWidth / configHz maxburstValueInBytes = bandWidth * 25 elif networkDeviceDriver == 'smsc75xx': # smsc75xx : gigabit ethernet maxburstValueInBytes = bandWidth * 50 elif networkDeviceDriver == 'usb': # usb : wifi maxburstValueInBytes = bandWidth * 50 elif networkDeviceDriver == 'r8169': maxburstValueInBytes = bandWidth * 10 elif networkDeviceDriver == 'virtualBox': maxburstValueInBytes = bandWidth * 10 else: utils.displayText('red', 'networkDeviceDriver (%s) unknown' % networkDeviceDriver, 0) utils.terminateTest(1) commandsList = [] # queueLength' unit is in number of packets # bufferSize'unit is in bytes #bufferSize = 1024 * queueLength #bufferSize = 1024 * 2000 # units : # kbit : kilobits or kilobits per second # kb : kilobytes # b : bytes # ----- # pfifo / bfifo : does not allow traffic shaping # http://blog.edseek.com/~jasonb/articles/traffic_shaping/qdiscs.html # ----- #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:', 'bfifo', 'limit', '%dkbit' % bandWidth]) # control incoming traffic on validation platform if networkInterface is in usbEthAdaptersInterfacesListForDmngEthAdapter or usbEthAdaptersInterfacesListForDmngUsbEthAdapter if globals.platformType == 'validation' and re.search('eth', networkInterface) != None: # we will use ifb110 for eth110, ifb111 for eth111... The file /etc/modules has to contain something like this : "ifb numifbs=256" ifbDevice = re.sub('eth', 'ifb', networkInterface) commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'ingress']) commandsList.append(['/sbin/tc', 'filter', action, 'dev', networkInterface, 'parent', 'ffff:', 'protocol', 'ip', 'u32', 'match', 'u32', '0', '0', 'flowid', '1:1', 'action', 'mirred', 'egress', 'redirect', 'dev', ifbDevice]) networkInterface = ifbDevice # ----- # tbf # ----- commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'root', 'handle', '1:', 'tbf', 'rate', '%dkbit' % bandWidth, 'maxburst', '%db' % maxburstValueInBytes, 'limit', '%db' % (maxburstValueInBytes + queueLengthInBytes)]) # ----- # try with htb... # ----- #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:', 'htb', 'default', '99', 'r2q', '5']) #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'parent', 'handle', '1:', 'htb', 'rate', '%dkbit' % bandWidth, 'ceil', '%dkbit' % bandWidth]) ###commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:', 'htb']) ###commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:', 'classid', '1:1', 'htb', 'rate', '%dmbit' % 100, 'ceil', '%dmbit' % 100]) ##commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'parent', '1:1', 'classid', '1:10', 'htb', 'rate', '%dkbit' % bandWidth, 'ceil', '%dkbit' % bandWidth]) #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'protocol', 'ip', '1:1', 'parent', '1:0', 'prio', '1', 'handle', '2', 'fw', 'classid', '1:10']) ##commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'parent', '1:10', 'handle', '10:', 'sfq', 'quantum', '1500b', 'perturb', '10']) #default 30 #$TC class add dev $IF parent 1: classid 1:1 htb rate $DNLD # ----- # try with cbq... # CBQ is the most complex qdisc available, the most hyped, the least understood, and probably the trickiest one to get right. This is not because the authors are evil or incompetent, far from it, it's just that the CBQ algorithm isn't all that precise and doesn't really match the way Linux works. # ----- #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:0', 'cbq', 'bandwidth', '1mbit', 'avpkt', '1000']) #commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:', 'classid', '1:1', 'cbq', 'rate', '700kbit', 'allot', '1500', 'prio' , '5', 'bounded', 'isolated']) #commandsList.append(['/sbin/tc', 'filter', 'add', 'dev', networkInterface, 'parent', '1:', 'protocol', 'ip', 'prio', '16', 'u32', 'match', 'ip', 'dst', '172.16.110.1', 'flowid', '1:1']) # ----- # try with hfsc... (not available on dmng) # ----- ##commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:0', 'hfsc', 'default', '1']) #commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:0', 'classid', '1:1', 'hfsc', 'rt', 'm2', '1mbit']) ##commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:0', 'classid', '1:1', 'hfsc', 'sc', 'rate', '1000kbit', 'ul', 'rate', '1000kbit']) #tc qdisc add dev eth0 root handle 1: hfsc #tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 1000kbit ul rate 1000kbit #tc class add dev eth0 parent 1:1 classid 1:10 hfsc sc rate 500kbit ul rate 1000kbit #tc class add dev eth0 parent 1:1 classid 1:20 hfsc sc rate 500kbit ul rate 1000kbit #tc class add dev eth0 parent 1:10 classid 1:11 hfsc sc umax 1500b dmax 53ms rate 400kbit ul rate 1000kbit #tc class add dev eth0 parent 1:10 classid 1:12 hfsc sc umax 1500b dmax 30ms rate 100kbit ul rate 1000kbit # ----- # loss, delay... # ----- #commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '1:1', 'handle', '2:', 'pfifo', 'limit', '%db' % queueLengthInBytes]) # this is the netem loss command that causes "1 datagrams received out-of-order" error message when testing with iperf. It simply indicates that packets are reordered. # when there is latency, iperf says there is loss, whereas there is no loss using ping!!! commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '1:1', 'handle', '2:', 'netem', 'loss', '%d%%' % packetsLoss, 'limit', '%db' % limitValueInBytes]) if fixedLatency == 0 or instantJitter == 0: commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '2:1', 'handle', '3:', 'netem', 'delay', '%dms' % fixedLatency, 'limit', '%db' % limitValueInBytes]) else: commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '2:1', 'handle', '3:', 'netem', 'delay', '%dms' % fixedLatency, '%dms' % instantJitter, 'distribution', 'normal', 'limit', '%db' % limitValueInBytes]) commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '3:1', 'handle', '4:', 'pfifo', 'limit', '%db' % limitValueInBytes]) return commandsList
if entryExist: utils.displayText('yellow', '[WARNING] scenario already present in file %s' % globals.jsonFileName, 0) else: newScenarii['%06d' % nbOfNewScenarii] = fullEntry nbOfNewScenarii += 1 # main globals.scriptStartTime = time.time() # initializations newScenarii = {} nbOfNewScenarii = 0 if not os.path.isfile(globals.jsonFileName): utils.displayText('red', 'file %s does not exist, create an empty one first' % globals.jsonFileName, 0) utils.terminateTest(1) utils.displayText('blue', 'deserializing full object from %s' % globals.jsonFileName, 0) if os.path.isfile(globals.jsonFileName): with open(globals.jsonFileName, 'r') as f: myJson = json.load(f) else: utils.displayText('red', 'file %s does not exist, run combineParameters.py first' % globals.jsonFileName, 0) utils.terminateTest(1) lastScenarioId = myJson['lastScenarioId'] main() if nbOfNewScenarii > 0:
def deserializeObject(): utils.displayText( 'blue', 'deserializing full object from %s' % globals.jsonFileName, 0) if os.path.isfile(globals.jsonFileName): with open(globals.jsonFileName, 'r') as f: myJson = json.load(f) else: utils.displayText( 'red', 'file %s does not exist, run combineParameters.py first' % globals.jsonFileName, 0) utils.terminateTest(1) # deserialize scenParameters only possible if globals.scenarioId has been set if globals.scenarioId != -1: scenParameters = myJson['%06d' % globals.scenarioId] globals.scenarioComment = scenParameters['scenarioComment'] globals.scenarioEvolution = scenParameters['scenarioEvolution'] globals.scenarioDuration = int(scenParameters['scenarioDuration']) globals.actionMode = scenParameters['actionMode'] globals.overEncodedBitrate = int(scenParameters['overEncodedBitrate']) globals.audioBitrate = int(scenParameters['audioBitrate']) globals.videoBitrateMode = scenParameters['videoBitrateMode'] globals.videoBitrate = int(scenParameters['videoBitrate']) globals.frameRate = int(scenParameters['frameRate']) globals.gopDuration = int(scenParameters['gopDuration']) globals.iFramesVsPandBFramesRatio = int( scenParameters['iFramesVsPandBFramesRatio']) globals.timeWindow = int(scenParameters['timeWindow']) globals.gatewayBandWidth = int(scenParameters['gateway']['bandWidth']) globals.gatewayFixedLatency = int( scenParameters['gateway']['fixedLatency']) globals.gatewayInstantJitter = int(scenParameters['gateway']['jitter']) globals.gatewayQueueLength = int( scenParameters['gateway']['queueLength']) globals.gatewayPacketsLoss = int( scenParameters['gateway']['packetsLoss']) globals.nbOfEthAdapters = int(scenParameters['nbOfEthAdapters']) for i in range(globals.nbOfEthAdapters): globals.ethAdaptersFixedLatenciesList.append( scenParameters['ethAdapters'][i]['fixedLatency']) globals.ethAdaptersJittersList.append( scenParameters['ethAdapters'][i]['jitter']) globals.ethAdaptersBandWidthsList.append( scenParameters['ethAdapters'][i]['bandWidth']) globals.ethAdaptersPacketLossList.append( scenParameters['ethAdapters'][i]['packetsLoss']) globals.ethAdaptersQueueLengthList.append( scenParameters['ethAdapters'][i]['queueLength']) globals.nbOfUsbEthAdapters = int(scenParameters['nbOfUsbEthAdapters']) for i in range(globals.nbOfUsbEthAdapters): globals.usbEthAdaptersFixedLatenciesList.append( scenParameters['usbEthAdapters'][i]['fixedLatency']) globals.usbEthAdaptersJittersList.append( scenParameters['usbEthAdapters'][i]['jitter']) globals.usbEthAdaptersBandWidthsList.append( scenParameters['usbEthAdapters'][i]['bandWidth']) globals.usbEthAdaptersPacketLossList.append( scenParameters['usbEthAdapters'][i]['packetsLoss']) globals.usbEthAdaptersQueueLengthList.append( scenParameters['usbEthAdapters'][i]['queueLength']) globals.nbOfWifiAdapters = int(scenParameters['nbOfWifiAdapters']) for i in range(globals.nbOfWifiAdapters): globals.wifiAdaptersFixedLatenciesList.append( scenParameters['wifiAdapters'][i]['fixedLatency']) globals.wifiAdaptersJittersList.append( scenParameters['wifiAdapters'][i]['jitter']) globals.wifiAdaptersBandWidthsList.append( scenParameters['wifiAdapters'][i]['bandWidth']) globals.wifiAdaptersPacketLossList.append( scenParameters['wifiAdapters'][i]['packetsLoss']) globals.wifiAdaptersQueueLengthList.append( scenParameters['wifiAdapters'][i]['queueLength']) globals.lastScenarioId = myJson['lastScenarioId']
parser = argparse.ArgumentParser( description="launch a scenario on aggregation-platform") # add positional arguments parser.add_argument("platformType", action="store", help="platform type : development|validation") args = parser.parse_args() globals.platformType = args.platformType if globals.platformType != 'development' and globals.platformType != 'validation': utils.displayText( 'red', 'platformType (%s) is neither development nor validation' % globals.platformType, 0) utils.terminateTest(1) # new instance of Dmng myDmng = dmng.Dmng() initChains() setDefaultPolicy() setInputRules(myDmng) setOutputRules() setForwardRules() setNatPostroutingRules() setNatOutputRules() setNatPreroutingRules(myDmng) #setMangleOutputRules() #setManglePreroutingRules() displayRules()
def buildCommandsList(networkInterface, action, networkDeviceDriver, bandWidth, fixedLatency, instantJitter, packetsLoss, queueLength): # check action values if (action != 'add') and (action != 'change'): utils.displayText( 'red', '[KO] action (%s) is neither \'add\', nor \'change\'' % action, 0) utils.terminateTest(1) limitValueInBytes = 100000 # packetSizeInBytes : a packet is supposed to weigh 1024 Bytes max packetSizeInBytes = 1024 # TBF parameters # http://lartc.org/manpages/tc-tbf.html # limit / latency : The limit parameter is the number of bytes to queue before packets are tail dropped. LIMIT IS THE NUMBER OF BYTES THAT CAN BE QUEUED WAITING FOR TOKENS TO BECOME AVAILABLE. The limit parameter tells us how big the queue of packets waiting to be sent can be. You can also specify this the other way around by setting the latency parameter, which specifies the maximum amount of time a packet can sit in the TBF. The latter calculation takes into account the size of the bucket, the rate and possibly the peakrate (if set). These two parameters are mutually exclusive.In Linux 2.6.1 and later if you attach a qdisc to your tbf class, the limit is ignored in favor of your attached qdisc. # burst / buffer / maxburst : Size of the bucket, in bytes. This is the maximum amount of bytes that tokens can be available for instantaneously. In general, larger shaping rates require a larger buffer. For 10mbit/s on Intel, you need at least 10kbyte buffer if you want to reach your configured rate! The minimum buffer size can be calculated by dividing the rate by HZ (ARSO : equivalent to CONFIG_HZ in kernel?) On 2012_08_01, CONFIG_HZ in dmng is supposed to be set to 250 HZ. ARSO : the result is too small for tbf to behave as we expect it to do. configHz = 250 # mpu : A zero-sized packet does not use zero bandwidth. For ethernet, no packet uses less than 64 bytes. The Minimum Packet Unit determines the minimal token usage (specified in bytes) for a packet. Defaults to zero. # rate : The speed knob. See remarks above about limits! See tc(8) for units. The rate tells us how fast tokens enter the buffer. PLEASE NOTE THAT IN THE ACTUAL IMPLEMENTATION, TOKENS CORRESPOND TO BYTES, NOT PACKETS. # peakrate : Maximum depletion rate of the bucket. Limited to 1mbit/s on Intel, 10mbit/s on Alpha. THE PEAKRATE DOES NOT NEED TO BE SET, IT IS ONLY NECESSARY IF PERFECT MILLISECOND TIMESCALE SHAPING IS REQUIRED. The normal bucket is used to limit the average rate data is sent but allow bursts of traffic to go through. THE PEAKRATE BUCKET IS USED TO LIMIT THE SPEED THOSE BURSTS ARE SENT. To calculate the maximum possible peakrate, multiply the configured mtu by configHz : 1500 x 250 = 375000 bps = 375 kbps : it is not usable for our bitrates (10kbps-10Mbps). # mtu / minburst : Specifies the size of the peakrate bucket. For perfect accuracy, should be set to the MTU of the interface. If a peakrate is needed, but some burstiness is acceptable, this size can be raised. A 3000 byte minburst allows around 3mbit/s of peakrate, given 1000 byte packets. queueLengthInBytes = queueLength * packetSizeInBytes # maxburstValueInBytes in Bytes # values found by using iperf (in TCP/UDP) and making experiences if networkDeviceDriver == 'asix': # asix : usb ethernet #maxburstValueInBytes = bandWidth / configHz maxburstValueInBytes = bandWidth * 25 elif networkDeviceDriver == 'smsc75xx': # smsc75xx : gigabit ethernet maxburstValueInBytes = bandWidth * 50 elif networkDeviceDriver == 'usb': # usb : wifi maxburstValueInBytes = bandWidth * 50 elif networkDeviceDriver == 'r8169': maxburstValueInBytes = bandWidth * 10 elif networkDeviceDriver == 'virtualBox': maxburstValueInBytes = bandWidth * 10 else: utils.displayText( 'red', 'networkDeviceDriver (%s) unknown' % networkDeviceDriver, 0) utils.terminateTest(1) commandsList = [] # queueLength' unit is in number of packets # bufferSize'unit is in bytes #bufferSize = 1024 * queueLength #bufferSize = 1024 * 2000 # units : # kbit : kilobits or kilobits per second # kb : kilobytes # b : bytes # ----- # pfifo / bfifo : does not allow traffic shaping # http://blog.edseek.com/~jasonb/articles/traffic_shaping/qdiscs.html # ----- #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:', 'bfifo', 'limit', '%dkbit' % bandWidth]) # control incoming traffic on validation platform if networkInterface is in usbEthAdaptersInterfacesListForDmngEthAdapter or usbEthAdaptersInterfacesListForDmngUsbEthAdapter if globals.platformType == 'validation' and re.search( 'eth', networkInterface) != None: # we will use ifb110 for eth110, ifb111 for eth111... The file /etc/modules has to contain something like this : "ifb numifbs=256" ifbDevice = re.sub('eth', 'ifb', networkInterface) commandsList.append( ['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'ingress']) commandsList.append([ '/sbin/tc', 'filter', action, 'dev', networkInterface, 'parent', 'ffff:', 'protocol', 'ip', 'u32', 'match', 'u32', '0', '0', 'flowid', '1:1', 'action', 'mirred', 'egress', 'redirect', 'dev', ifbDevice ]) networkInterface = ifbDevice # ----- # tbf # ----- commandsList.append([ '/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'root', 'handle', '1:', 'tbf', 'rate', '%dkbit' % bandWidth, 'maxburst', '%db' % maxburstValueInBytes, 'limit', '%db' % (maxburstValueInBytes + queueLengthInBytes) ]) # ----- # try with htb... # ----- #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:', 'htb', 'default', '99', 'r2q', '5']) #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'parent', 'handle', '1:', 'htb', 'rate', '%dkbit' % bandWidth, 'ceil', '%dkbit' % bandWidth]) ###commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:', 'htb']) ###commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:', 'classid', '1:1', 'htb', 'rate', '%dmbit' % 100, 'ceil', '%dmbit' % 100]) ##commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'parent', '1:1', 'classid', '1:10', 'htb', 'rate', '%dkbit' % bandWidth, 'ceil', '%dkbit' % bandWidth]) #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'protocol', 'ip', '1:1', 'parent', '1:0', 'prio', '1', 'handle', '2', 'fw', 'classid', '1:10']) ##commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'parent', '1:10', 'handle', '10:', 'sfq', 'quantum', '1500b', 'perturb', '10']) #default 30 #$TC class add dev $IF parent 1: classid 1:1 htb rate $DNLD # ----- # try with cbq... # CBQ is the most complex qdisc available, the most hyped, the least understood, and probably the trickiest one to get right. This is not because the authors are evil or incompetent, far from it, it's just that the CBQ algorithm isn't all that precise and doesn't really match the way Linux works. # ----- #commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:0', 'cbq', 'bandwidth', '1mbit', 'avpkt', '1000']) #commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:', 'classid', '1:1', 'cbq', 'rate', '700kbit', 'allot', '1500', 'prio' , '5', 'bounded', 'isolated']) #commandsList.append(['/sbin/tc', 'filter', 'add', 'dev', networkInterface, 'parent', '1:', 'protocol', 'ip', 'prio', '16', 'u32', 'match', 'ip', 'dst', '172.16.110.1', 'flowid', '1:1']) # ----- # try with hfsc... (not available on dmng) # ----- ##commandsList.append(['/sbin/tc', 'qdisc', 'add', 'dev', networkInterface, 'root', 'handle', '1:0', 'hfsc', 'default', '1']) #commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:0', 'classid', '1:1', 'hfsc', 'rt', 'm2', '1mbit']) ##commandsList.append(['/sbin/tc', 'class', 'add', 'dev', networkInterface, 'parent', '1:0', 'classid', '1:1', 'hfsc', 'sc', 'rate', '1000kbit', 'ul', 'rate', '1000kbit']) #tc qdisc add dev eth0 root handle 1: hfsc #tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 1000kbit ul rate 1000kbit #tc class add dev eth0 parent 1:1 classid 1:10 hfsc sc rate 500kbit ul rate 1000kbit #tc class add dev eth0 parent 1:1 classid 1:20 hfsc sc rate 500kbit ul rate 1000kbit #tc class add dev eth0 parent 1:10 classid 1:11 hfsc sc umax 1500b dmax 53ms rate 400kbit ul rate 1000kbit #tc class add dev eth0 parent 1:10 classid 1:12 hfsc sc umax 1500b dmax 30ms rate 100kbit ul rate 1000kbit # ----- # loss, delay... # ----- #commandsList.append(['/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '1:1', 'handle', '2:', 'pfifo', 'limit', '%db' % queueLengthInBytes]) # this is the netem loss command that causes "1 datagrams received out-of-order" error message when testing with iperf. It simply indicates that packets are reordered. # when there is latency, iperf says there is loss, whereas there is no loss using ping!!! commandsList.append([ '/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '1:1', 'handle', '2:', 'netem', 'loss', '%d%%' % packetsLoss, 'limit', '%db' % limitValueInBytes ]) if fixedLatency == 0 or instantJitter == 0: commandsList.append([ '/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '2:1', 'handle', '3:', 'netem', 'delay', '%dms' % fixedLatency, 'limit', '%db' % limitValueInBytes ]) else: commandsList.append([ '/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '2:1', 'handle', '3:', 'netem', 'delay', '%dms' % fixedLatency, '%dms' % instantJitter, 'distribution', 'normal', 'limit', '%db' % limitValueInBytes ]) commandsList.append([ '/sbin/tc', 'qdisc', action, 'dev', networkInterface, 'parent', '3:1', 'handle', '4:', 'pfifo', 'limit', '%db' % limitValueInBytes ]) return commandsList