--- /dev/null
+*.pyc
+/.pydevproject
id;id
cookie_mask;cookie_mask
dl_type;dl_type
+ip;ip
+installHw;installHw
import xmltodict
from xmlvalidator import XMLValidator
+# Delay time value is important for slow machines
+# value mean nr. of seconds for waiting for controller
+TEST_TIME_DELAY = 0
+
class TestOpenFlowXml_Base(unittest.TestCase):
+ """
+ Base TEST class extends unittest.TestCase and
+ it provides possibilty to add parameters for
+ all subclasses by call a static constructor:
+
+ TestOpenFlowXml_Base.load_file_name(sub_class_name, param)
+ """
def __init__(self, methodName='runTest', path_to_xml=None):
+ """
+ private defalut constructor
+ """
super(TestOpenFlowXml_Base, self).__init__(methodName)
self.path_to_xml = path_to_xml
@staticmethod
def load_file_name(clazz, path_to_xml=None):
+ """
+ static constructor for all subclasses with param
+ param -> path_to_xml (default None)
+ """
testloader = unittest.TestLoader()
testnames = testloader.getTestCaseNames(clazz)
suite = unittest.TestSuite()
class ConvertorTools():
-
+ """
+ Tool class contains static conversion method
+ for the value conversions
+ """
CONVERTORS = {
'cookie': hex,
+ 'metadata': hex
}
@staticmethod
def base_tag_values_conversion(key, value):
- convertor = ConvertorTools.CONVERTORS.get(key, None)
- return convertor(int(value)) if convertor > None else value
+ """
+ Check a need to conversion and convert if need
+ """
+ if value is None : return ''
+ else:
+ convertor = ConvertorTools.CONVERTORS.get(key, None)
+ if convertor is None : return value
+ else :
+ return convertor(int(value))
class ParseTools():
@staticmethod
def sort_ordered_dict_to_array(x_dict=None):
if (x_dict > None):
- out_put = None
+ out_put = []
for val in map(lambda val: x_dict.get(val), sorted(x_dict.keys())) :
- if (out_put > None) :
- out_put += ', %s' %val
- else :
- out_put = val
- return out_put
+ out_put.append(val)
+# if (out_put > None) :
+# out_put += ', %s' %val
+# else :
+# out_put = val
+ return ', '.join(out_put)
return
@staticmethod
ParseTools.__parse_tags_from_xml(child, flow_dict, key_dict, ikwd=ignore_key_dict)
return flow_dict
-
- @staticmethod
- def get_switchflow_dict(switch_dict, ignore_key_dict=None):
- x_dict={}
- for sw_key in switch_dict.keys() :
- if (ignore_key_dict.get(sw_key,None) is None):
- x_dict[sw_key] = switch_dict.get(sw_key)
-
- return x_dict
+
+ # TODO VD remove this method
+# @staticmethod
+# def get_switchflow_dict(switch_dict, ignore_key_dict=None):
+# x_dict={}
+# for sw_key in switch_dict.keys() :
+# if (ignore_key_dict.get(sw_key,None) is None):
+# x_dict[sw_key] = switch_dict.get(sw_key)
+#
+# return x_dict
@staticmethod
def all_nodes(xml_root):
class MininetTools():
-
+ """
+ Tool class provides static method for Open_vswitch
+ mininet out of box controls
+ """
@staticmethod
def create_network(controller_ip, controller_port):
"""Create topology and mininet network."""
return net
+# @staticmethod #TODO VD finish it
+# def __mininet_parse_response(resp_str='', x_dict={}, ikwd={}):
+# for elm in resp_str.split(',') :
+# if len(elm.split('=')) > 1 :
+# x_key = elm.split('=')[0]
+# x_val = elm.split
+# x_dict[elm] = MininetTools.__mininet_parse_response(elm.split('='), x_dict, ikwd)
+
+
@staticmethod
def get_flows(net, ikwd={}):
"""Get list of flows from network's first switch.
log.debug('switch flow table: {}'.format(output))
+ # dictionary for return
flows = {}
for line in output.splitlines()[1:] :
output = line;
- action = re.split('actions=',output,1)[1]
+ if (len(re.split('actions=', output, 1)) > 0) :
+ try :
+ action_str = re.split('actions=',output,1)[1]
+ flows['actions'] = ', '.join((action_str.split(','))) if (len(action_str.split(',')) > 0) else action_str.strip()
+ # TODO: VD look at actions with own param (xml24) __mininet_parse_resp
+ except Exception, e :
+ log.error(e)
+
+ else :
+ flows['actions'] = ''
+
output= re.split('actions=',output,1)[0]
- for elem in output.split(',') :
- elm_d = elem.split('=')
- a_key = (elm_d[0]).strip()
+ for e in output.split(',') :
+ elem = e.split('=')
+ a_key = (elem[0]).strip()
if (ikwd.get(a_key, None) is None) :
- a_value = elm_d[1] if (len(elm_d) > 1) else None
+ a_value = elem[1] if (len(elem) > 1) else None
flows[a_key] = a_value.strip() if isinstance(a_value,str) else (str(a_value)).strip()
-
- flows['actions'] = action.split(',')
-
+
return flows
-# for line in output.splitlines()[1:]:
-# flows.append(ParseTools.dump_string_to_dict(line))
-#
-# # sort by duration
-# return sorted(flows, key=lambda x: x['duration'].rstrip('s'))
class FileLoaderTools():
action_key_dict = action_keywords,
match_key_dict = match_keywords,
ignore_key_dict = ignore_keywords)
- print (switch_etalon)
ids = ParseTools.get_values(tree.documentElement, 'table_id', 'id')
log.debug('received content: {}'.format(rsp.text))
assert rsp.status_code == 204 or rsp.status_code == 200, 'Status' \
' code returned %d' % rsp.status_code
+ time.sleep(TEST_TIME_DELAY)
+
try:
# check request content against restconf's datastore
response = requests.get(url, auth=('admin', 'admin'),
assert switch_etalon == switch_flows, 'expected and stored switch settings are not the same \n'\
'expected: %s\nstored: %s' %(switch_etalon,switch_flows)
+ # TODO VD remove dead code
# compare requested object and flow table state
## TODO look at action parsing separatly from a flow
# switch_flow_dict = ParseTools.get_switchflow_dict(switch_flows[0], ignore_keywords)
# Comparator.compare_results(switch_flows[0], ParseTools.dump_string_to_dict(mn_string))
# else:
# log.error('cannot find test results - comparison skipped')
+ except Exception, e :
+ log.error(e)
+ print '\n'
+ raise e
+
finally:
response = requests.delete(url, auth=('admin', 'admin'),
headers={'Accept': 'application/xml'})
assert response.status_code == 200
print '\n\n\n'
+ time.sleep(TEST_TIME_DELAY)
def suite(path='xmls', test_class='TestOpenFlowXml_Base') :
suite = unittest.TestSuite()
if args.xmls is not None:
xmls = map(int, args.xmls.split(','))
+ else :
+ xmls = None
xmlfiles = None
if xmls is not None:
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.1.1/24</ipv4-destination>
+ <ipv4-destination>10.0.1.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<address>00:00:00:11:23:ae</address>
</ethernet-source>
</ethernet-match>
- <ipv4-source>17.1.2.3/8</ipv4-source>
- <ipv4-destination>172.168.5.6/16</ipv4-destination>
+ <ipv4-source>17.0.0.0/8</ipv4-source>
+ <ipv4-destination>172.168.0.0/16</ipv4-destination>
<ip-match>
<ip-protocol>132</ip-protocol>
<ip-dscp>0</ip-dscp>
<address>00:00:00:11:23:ae</address>
</ethernet-source>
</ethernet-match>
- <ipv4-source>17.1.2.3/8</ipv4-source>
- <ipv4-destination>172.168.5.6/16</ipv4-destination>
+ <ipv4-source>17.0.0.0/8</ipv4-source>
+ <ipv4-destination>172.168.0.0/16</ipv4-destination>
<ip-match>
<ip-protocol>1</ip-protocol>
<ip-dscp>27</ip-dscp>
<type>34525</type>
</ethernet-type>
</ethernet-match>
- <ipv6-source>1234:5678:9ABC:DEF0:FDCD:A987:6543:210F/76</ipv6-source>
- <ipv6-destination>fe80:2acf:e9ff:fe21::6431/94</ipv6-destination>
+ <ipv6-source>1234:5678:9ABC:DEF0:FDCD:A987:6543:0/76</ipv6-source>
+ <ipv6-destination>fe80:2acf:e9ff:fe21::0/94</ipv6-destination>
<ipv6-nd-target>fe80:3456:789A:fe21::6431</ipv6-nd-target>
<ipv6-nd-sll>12:34:56:78:9A:BC</ipv6-nd-sll>
<ipv6-nd-tll>FE:DC:BA:98:76:54</ipv6-nd-tll>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<type>2048</type>
</ethernet-type>
</ethernet-match>
- <ipv4-destination>10.0.0.1/24</ipv4-destination>
+ <ipv4-destination>10.0.0.0/24</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<address>00:00:00:00:23:ae</address>
</ethernet-source>
</ethernet-match>
- <ipv4-source>10.1.2.3/24</ipv4-source>
- <ipv4-destination>20.4.5.6/16</ipv4-destination>
+ <ipv4-source>10.1.2.0/24</ipv4-source>
+ <ipv4-destination>20.4.0.0/16</ipv4-destination>
<in-port>0</in-port>
</match>
<hard-timeout>12</hard-timeout>
<address>00:00:00:01:23:ae</address>
</ethernet-source>
</ethernet-match>
- <ipv4-source>10.1.2.3/24</ipv4-source>
- <ipv4-destination>40.4.5.6/16</ipv4-destination>
+ <ipv4-source>10.1.2.0/24</ipv4-source>
+ <ipv4-destination>40.4.0.0/16</ipv4-destination>
</match>
<hard-timeout>12</hard-timeout>
<flags>FlowModFlags [_cHECKOVERLAP=false, _rESETCOUNTS=false, _nOPKTCOUNTS=false, _nOBYTCOUNTS=false, _sENDFLOWREM=false]</flags>
<address>00:00:00:11:23:ae</address>
</ethernet-source>
</ethernet-match>
- <ipv4-source>10.1.2.3/24</ipv4-source>
- <ipv4-destination>20.4.5.6/16</ipv4-destination>
+ <ipv4-source>10.1.2.0/24</ipv4-source>
+ <ipv4-destination>20.4.0.0/16</ipv4-destination>
<ip-match>
<ip-protocol>56</ip-protocol>
<ip-dscp>15</ip-dscp>
<address>00:00:00:11:23:ae</address>
</ethernet-source>
</ethernet-match>
- <ipv4-source>17.1.2.3/8</ipv4-source>
- <ipv4-destination>172.168.5.6/16</ipv4-destination>
+ <ipv4-source>17.0.0.0/8</ipv4-source>
+ <ipv4-destination>172.168.0.0/16</ipv4-destination>
<ip-match>
<ip-protocol>6</ip-protocol>
<ip-dscp>2</ip-dscp>
<address>00:00:00:11:23:ae</address>
</ethernet-source>
</ethernet-match>
- <ipv4-source>19.1.2.3/10</ipv4-source>
- <ipv4-destination>172.168.5.6/18</ipv4-destination>
+ <ipv4-source>19.1.0.0/16</ipv4-source>
+ <ipv4-destination>172.168.5.0/24</ipv4-destination>
<ip-match>
<ip-protocol>17</ip-protocol>
<ip-dscp>8</ip-dscp>
raise StandardError
def ipv4_check(self, a):
+ IP_MASK_COMPARE_PATTERNS = {
+ '24' : '.0',
+ '16' : '.0.0',
+ '8' : '.0.0.0'
+ }
XMLValidator.log.debug('validating ipv4 address: {}'.format(a))
+ ip_arr = a.split('/')
+ if (len(ip_arr) > 1) :
+ m_patt = IP_MASK_COMPARE_PATTERNS.get(ip_arr[1], None)
+ if (m_patt is None) :
+ raise StandardError('{} is not valid ipv4 mask'.format(ip_arr[1]))
+ if (ip_arr[0].endswith(m_patt) != True) :
+ raise StandardError('ipv4 address mask has to *{}/{}'.format(m_patt, ip_arr[1]))
+
mask_pos = a.find('/')
if mask_pos > 0:
a = a[:mask_pos]