moved to a CsvTester doing all tests

This commit is contained in:
Raphael Bauduin 2015-05-27 10:59:35 -07:00
parent cdb954756f
commit 793f51be69
4 changed files with 80 additions and 172 deletions

View File

@ -38,7 +38,7 @@ class MptcptraceData:
# gets cell corresponding to flow with header column
# flow 0 = first one, from 1=subflows
def get(self, name):
def get_csv(self, name):
if hasattr(self,name):
return getattr(self,name)
else:

View File

@ -6,6 +6,7 @@ import csv
from io import StringIO
import re
import numpy as np
@ -15,43 +16,12 @@ class TcptraceData:
self.pcap_file=pcap_file
csv_content = check_output(["tcptrace", "-l", "--csv", pcap_file])
tcptrace_reader = csv.reader(filter(lambda l: len(l)>0 and l[0]!="#",csv_content.splitlines()))
cells=list(tcptrace_reader)
cells=np.array(list(tcptrace_reader))
#drop header row
cells= cells[1:]
self.cells = cells
self.headers=cells[0]
self.flows=cells[1:]
self.number_of_flows=len(self.flows)
# gets cell corresponding to flow with header column
# flow 0 = first one, from 1=subflows
def get(self, flow, column):
if flow>self.number_of_flows-1:
raise Exception("Bad flow index")
value = self.flows[flow][self.headers.index(column)]
if re.search("[a-zA-Z]", value):
return value
elif re.search("\.", value):
return float(value)
elif re.search("^[0-9]+$", value):
return int(value)
else:
return value
# returns first packet time of flow
def first_packet(self, flow):
return float(self.flows[flow][self.header_index("first_packet")])-float(self.flows[0][self.header_index("first_packet")])
# util: get column index based on header name
def header_index(self, column):
return self.headers.index(column)
#t = TcptraceData("client.pcap")
#print t.number_of_flows
#print t.first_packet(1)
def get_csv(self, name):
return self.cells

View File

@ -47,72 +47,42 @@ class ExactValueValidation(Validation):
self.value = value
return self.compared==value
# individual flow validations (used with FlowsTest)
###################################################
class MinDelayValidation(Validation):
# receives flow_spec = (index, flows) where index is the index of the flow to validate, and flows is the array of flows
def validate(self, flow_spec):
(yml,trace) = flow_spec
index=yml["index"]
val = trace.first_packet(index)-trace.first_packet(0)
self.value = val
return self.compared<=val
class MinDelayBetweenValidation(Validation):
# 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
def validate(self, flow_spec):
(yml ,trace) = flow_spec
[index0, index1] = yml["index"]
val = trace.first_packet(index1)-trace.first_packet(index0)
self.value = val
return self.compared<=val
class AttributeValidation(Validation):
def setup(self, flow_spec):
(yml ,trace) = flow_spec
[index0, index1] = yml["index"]
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
# the method get_tested_value of the tester returns the value passed to validate.
# the CsvTester returns an array of values
class MinDifferenceValidation(Validation):
def validate(self, value):
v = value.flatten()
if len(v)>2:
raise Exception("MinDifferenceValidation requires 2 values maximum, not "+ str(len(v)))
self.value = float(v[1])-float(v[0])
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)
class MinRowsValidation(Validation):
def validate(self, value):
self.value = len(value)
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)
class MaxRowsValidation(Validation):
def validate(self, value):
self.value = len(value)
return self.compared>=self.value
class ExactRowsValidation(Validation):
def validate(self, value):
self.value = len(value)
return self.compared==self.value
class MaxRatioValidation(Validation):
def validate(self, value):
v = value.flatten()
if len(v)>2:
raise Exception("MinDifferenceValidation requires 2 values maximum, not "+ str(len(v)))
self.value = float(v[1])/(float(v[0])+float(v[1]))
return self.compared>=self.value
# 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.
class IncreasingValueValidation(AttributeValidation):
class IncreasingValuesValidation(Validation):
def validate(self, values):
previous = 0
for i,v in enumerate(values):
for i,v in enumerate(values.flatten()):
#print i, "{:10.6f}".format(previous), "{:10.6f}".format(v)
if v<previous:
self.value= "row " + str(i) # index of error row
@ -122,15 +92,16 @@ class IncreasingValueValidation(AttributeValidation):
return True
class Tester:
def __init__(self, yml, trace):
self.yml = yml["validations"]
self.yml = yml
self.trace = trace
# performs a validation found in the yml file.
def validate(self):
is_ok = True
self.logs = ""
for val in self.yml:
for val in self.yml["validations"]:
tested_value = self.get_tested_value(val)
klass_name=val["name"].title().replace("_","")+"Validation"
tester_klass=globals()[klass_name]
@ -156,36 +127,15 @@ class Tester:
# 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.
class TcptraceTest(Tester):
pass
class CsvTest(Tester):
def get_tested_value(self, validation):
a = self.trace.get_csv(self.yml["csv"])
if "rows" in self.yml:
a = a[self.yml["rows"]]
if "columns" in self.yml:
a = a[:,self.yml["columns"]]
return a
# 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
# index can be a compound value, as in the case of min_delay_between where it is an array of indexes
class FlowsTest(TcptraceTest):
def get_tested_value(self, yml):
return (yml,self.trace)
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"]]
class Checker:
def check(self):

View File

@ -1,56 +1,44 @@
mptcptrace:
- test: "column_values"
- test: "csv"
csv: "c2s_seq_1"
columns: 2
validations:
- name: "increasing_value"
csv: "c2s_seq_1"
column: 2
- name: "increasing_values"
desc: "dummy: check sequence numbers grow"
tcptrace:
- test: "number_of_flows"
- test: "csv"
csv: "tcptrace"
rows: [0,1]
columns: [5]
validations:
- name: "min_value"
- name: "min_difference"
target: 2
desc: "Open minimum 2 flows"
- name: "max_value"
target: 4
desc: "Open maximum 4 flows"
- name: "exact_value"
target: 4
desc: "Open exactly 4 flows"
# This tests the flows opened by the connection. See class FlowsTest
- test: "flows"
desc: "minimum difference of opening time"
- test: "csv"
csv: "tcptrace"
validations:
# validates time between first packets of the first stream and the stream for which the index is passed.
- name: "min_delay"
index: 1
- name: "min_rows"
target: 2
desc: "Minimum 2 seconds delay between opening of first and second flow"
# validates time between first packets of streams for which the index is passed.
# index is now a compound value, handled by the validate method of the class MinDelayBetweenValidation
# first index value is the base flow we compare to
# second index is the flow we want to validate
- name: "min_delay_between"
index:
- 1
- 2
target: 1
desc: "Minimum 1 second delay between opening of second and third flow"
- name: "attribute_minimum_difference"
attribute: "first_packet"
# first index value is the base flow we compare to
# second index is the flow we want to validate
index:
- 0
- 1
desc: "minimum number of flows"
- name: "max_rows"
target: 5
desc: "minimum number of flows"
- name: "exact_rows"
target: 4
desc: "minimum number of flows"
- test: "csv"
csv: "tcptrace"
rows: [1,2]
columns: [5]
validations:
- name: "min_difference"
target: 2
desc: "first packet delay 2nd flow"
- name: "attribute_maximum_ratio"
attribute: "total_packets_a2b"
# first index value is the base flow we compare to
# second index is the flow we want to validate
index:
- 0
- 1
# flows[1].packets_a2b/flows[2].packets_a2b < 5%
desc: "minimum difference of opening time between flow 2 and 3"
- test: "csv"
csv: "tcptrace"
rows: [0,1]
columns: [7]
validations:
- name: "max_ratio"
target: 0.05
desc: "a->b packet ration flow 2 compard to flow1"
desc: "max ration of packet a->b on flow 1 compared to flow 0."