2015-05-20 18:37:50 +00:00
from mpTcptraceData import *
2015-05-26 23:28:19 +00:00
import numpy as np
2015-05-20 18:37:50 +00:00
2015-05-27 16:13:31 +00:00
# to get a REPL:
#import code
#code.interact(local=locals())
2015-05-20 18:37:50 +00:00
# A checker runs tests, and a test is made of multiple validations
# For a validation, the value to compare to is the target value from the yaml
# The validation takes place in the validate method, which takes
# as argument a value from which to extract the value to compare or the value itself
class Validation :
def __init__ ( self , yml ) :
2015-05-27 16:13:31 +00:00
if " target " in yml :
self . compared = yml [ " target " ]
else :
self . compared = None
2015-05-20 18:37:50 +00:00
def name ( self ) :
return self . __class__ . __name__
2015-05-20 19:29:48 +00:00
def validate ( self , value ) :
raise Exception ( " Method not implemented " )
2015-05-26 19:19:16 +00:00
def setup ( self ) :
raise Exception ( " Method not implemented " )
2015-05-20 18:37:50 +00:00
# checks a value passed is greater or equal (generic)
class MinValueValidation ( Validation ) :
def validate ( self , value ) :
2015-05-26 19:00:03 +00:00
self . value = value
2015-05-20 18:37:50 +00:00
return self . compared < = value
2015-05-26 16:43:53 +00:00
# checks a value passed is greater or equal (generic)
class MaxValueValidation ( Validation ) :
def validate ( self , value ) :
2015-05-26 19:00:03 +00:00
self . value = value
2015-05-26 16:43:53 +00:00
return self . compared > = value
# checks a value passed is greater or equal (generic)
class ExactValueValidation ( Validation ) :
def validate ( self , value ) :
2015-05-26 19:00:03 +00:00
self . value = value
2015-05-26 16:43:53 +00:00
return self . compared == value
2015-05-20 18:37:50 +00:00
2015-05-27 16:13:31 +00:00
# individual flow validations (used with FlowsTest)
###################################################
2015-05-20 18:37:50 +00:00
class MinDelayValidation ( Validation ) :
2015-05-27 16:13:31 +00:00
# receives flow_spec = (index, flows) where index is the index of the flow to validate, and flows is the array of flows
2015-05-20 18:37:50 +00:00
def validate ( self , flow_spec ) :
2015-05-26 19:00:03 +00:00
( yml , trace ) = flow_spec
index = yml [ " index " ]
2015-05-26 16:59:37 +00:00
val = trace . first_packet ( index ) - trace . first_packet ( 0 )
2015-05-26 19:00:03 +00:00
self . value = val
2015-05-20 18:37:50 +00:00
return self . compared < = val
2015-05-26 17:12:46 +00:00
class MinDelayBetweenValidation ( Validation ) :
2015-05-27 16:13:31 +00:00
# gets flow_spec = ( [ index0, index1] , flows) where:
# - index0 is the index of the flow taken as reference for timing
# - index1 is the flow for which we want to validate the timing
# - flows is the array of flows
2015-05-26 17:12:46 +00:00
def validate ( self , flow_spec ) :
2015-05-26 19:00:03 +00:00
( yml , trace ) = flow_spec
[ index0 , index1 ] = yml [ " index " ]
2015-05-26 17:12:46 +00:00
val = trace . first_packet ( index1 ) - trace . first_packet ( index0 )
2015-05-26 19:00:03 +00:00
self . value = val
2015-05-26 17:12:46 +00:00
return self . compared < = val
2015-05-26 19:19:16 +00:00
class AttributeValidation ( Validation ) :
def setup ( self , flow_spec ) :
2015-05-26 19:00:03 +00:00
( yml , trace ) = flow_spec
[ index0 , index1 ] = yml [ " index " ]
2015-05-26 19:19:16 +00:00
self . val0 = trace . get ( index0 , yml [ " attribute " ] )
self . val1 = trace . get ( index1 , yml [ " attribute " ] )
class AttributeMinimumDifferenceValidation ( AttributeValidation ) :
def validate ( self , flow_spec ) :
self . setup ( flow_spec )
self . value = self . val1 - self . val0
return self . compared < = self . value
class AttributeMaximumDifferenceValidation ( AttributeValidation ) :
def validate ( self , flow_spec ) :
self . setup ( flow_spec )
self . value = self . val1 - self . val0
return self . compared > = self . value
class AttributeMinimumRatioValidation ( AttributeValidation ) :
def validate ( self , flow_spec ) :
self . setup ( flow_spec )
self . value = float ( self . val1 ) / + float ( self . val1 )
return self . compared < = self . value
class AttributeMaximumRatioValidation ( AttributeValidation ) :
def validate ( self , flow_spec ) :
self . setup ( flow_spec )
self . value = float ( self . val1 ) / float ( self . val0 )
return self . compared > = self . value
2015-05-27 16:13:31 +00:00
# mptcptrace csv validations
############################
# validates all values passed have increasing values
# it is the Tester's get_tested_value method that does the work
# to extract the values list from the trace.
2015-05-26 23:28:19 +00:00
class IncreasingValueValidation ( AttributeValidation ) :
def validate ( self , values ) :
previous = 0
for i , v in enumerate ( values ) :
#print i, "{:10.6f}".format(previous), "{:10.6f}".format(v)
if v < previous :
2015-05-27 16:13:31 +00:00
self . value = " row " + str ( i ) # index of error row
2015-05-26 23:28:19 +00:00
return False
else :
previous = v
2015-05-27 16:13:31 +00:00
return True
2015-05-26 23:28:19 +00:00
2015-05-26 19:19:16 +00:00
2015-05-26 22:04:15 +00:00
class Tester :
2015-05-26 23:28:19 +00:00
def __init__ ( self , yml , trace ) :
self . yml = yml [ " validations " ]
self . trace = trace
2015-05-20 18:37:50 +00:00
# performs a validation found in the yml file.
def validate ( self ) :
is_ok = True
self . logs = " "
for val in self . yml :
tested_value = self . get_tested_value ( val )
klass_name = val [ " name " ] . title ( ) . replace ( " _ " , " " ) + " Validation "
tester_klass = globals ( ) [ klass_name ]
tester = tester_klass ( val )
2015-05-27 16:13:31 +00:00
if " target " in val :
target = val [ " target " ]
else :
target = None
2015-05-26 17:44:34 +00:00
try :
if tester . validate ( tested_value ) :
2015-05-27 16:13:31 +00:00
self . logs = self . logs + " " + " OK : " + val [ " desc " ] + " - " + tester . name ( ) + " value : " + str ( tester . value ) + ( " " if target == None else " vs target " + str ( val [ " target " ] ) ) + " \n "
2015-05-26 17:44:34 +00:00
else :
2015-05-27 16:13:31 +00:00
self . logs = self . logs + " " + " FAIL: " + val [ " desc " ] + " - " + tester . name ( ) + " value : " + str ( tester . value ) + ( " " if target == None else " vs target " + str ( val [ " target " ] ) ) + " \n "
2015-05-26 17:44:34 +00:00
is_ok = False
except Exception as e :
2015-05-26 19:00:03 +00:00
self . logs = self . logs + ( " " if self . logs == " " else " \n " ) + " EXCP: " + val [ " desc " ] + " - " + tester . name ( ) + " " + str ( e ) + " \n "
2015-05-20 18:37:50 +00:00
return is_ok
def name ( self ) :
return self . __class__ . __name__
2015-05-20 19:29:48 +00:00
def get_tested_value ( self , yml ) :
raise Exception ( " Method not implemented " )
2015-05-20 18:37:50 +00:00
2015-05-26 22:04:15 +00:00
# Base class testing tcptrace results
# the inheriting class should implement get_tested_value(self, yml)
# the get_tested_value should return the value that all validations of this test will use
# the validations get this value as argument of their validate method
# The validate method iterates one the validations mentioned for the test in the yml file.
2015-05-26 23:28:19 +00:00
class TcptraceTest ( Tester ) :
pass
2015-05-26 22:04:15 +00:00
2015-05-20 18:37:50 +00:00
# get_tested_value returns the number of flows
class NumberOfFlowsTest ( TcptraceTest ) :
def get_tested_value ( self , yml ) :
return self . trace . number_of_flows
# get_tested_value returns index of the flow to validate, and the list of flows
2015-05-26 17:12:46 +00:00
# index can be a compound value, as in the case of min_delay_between where it is an array of indexes
2015-05-20 18:37:50 +00:00
class FlowsTest ( TcptraceTest ) :
def get_tested_value ( self , yml ) :
2015-05-26 19:00:03 +00:00
return ( yml , self . trace )
2015-05-20 18:37:50 +00:00
2015-05-26 23:28:19 +00:00
class MptcptraceTest ( Tester ) :
pass
# get_tested_value returns the number of flows
class ColumnValuesTest ( TcptraceTest ) :
def get_tested_value ( self , yml ) :
a = self . trace . get ( yml [ " csv " ] )
return a [ : , yml [ " column " ] ]
2015-05-26 22:04:15 +00:00
class Checker :
2015-05-20 18:37:50 +00:00
def check ( self ) :
is_ok = True
self . logs = self . test_id + " \n "
for test in self . yml :
name = test [ " test " ] . title ( ) . replace ( " _ " , " " ) + " Test "
klass = globals ( ) [ name ]
r = klass ( test , self . trace )
if r . validate ( ) :
2015-05-26 19:00:03 +00:00
self . logs = self . logs + " * " + self . test_id + " " + r . name ( ) + " SUCCESS \n "
2015-05-20 18:37:50 +00:00
self . logs = self . logs + r . logs
else :
self . logs = self . logs + " * " + self . test_id + " " + r . name ( ) + " FAIL \n "
self . logs = self . logs + r . logs
2015-05-26 22:04:15 +00:00
# Runs tests based on tcptrace
# It (in the method inherited from its parent class) instanciates the ...Test class passing it the TcptraceData instance
class TcptraceChecker ( Checker ) :
def __init__ ( self , yml , test_id , destDir ) :
self . yml = yml [ " tcptrace " ]
self . trace = TcptraceData ( destDir + " /client.pcap " )
self . test_id = test_id
2015-05-26 23:28:19 +00:00
from mpMptcptraceData import *
2015-05-26 22:04:15 +00:00
# Runs tests based on mptcptrace
# It (in the method inherited from its parent class) instanciates the ...Test class passing it the MptcptraceData instance
class MptcptraceChecker ( Checker ) :
def __init__ ( self , yml , test_id , destDir ) :
self . yml = yml [ " mptcptrace " ]
self . trace = MptcptraceData ( destDir + " /client.pcap " )
self . test_id = test_id
2015-05-20 18:37:50 +00:00