6 from xml.etree import ElementTree as ET
8 from openvswitch.flow_tools import FlowAdderThread, FlowRemoverThread, MapNames, \
10 from openvswitch.mininet_tools import MininetTools
13 # Delay time value is important for slow machines
14 # value mean nr. of seconds for waiting for controller
16 # value mean nr. of seconds for waiting for mininet
17 MININET_START_DELAY = 15
20 class MultiTest(unittest.TestCase):
22 log = logging.getLogger('MultiTest')
28 MultiTest.log.info('setUp')
29 self.threads_count = 50
30 self.thread_pool = list()
33 self.__setup_threads()
37 MultiTest.log.info('tearDown')
41 def inc_error(value=1):
42 MultiTest.total_errors += value
45 def inc_flow(value=1):
46 MultiTest.total_flows += 1
49 def add_flow_id(flow_id=None):
51 MultiTest.ids.append(flow_id)
54 self.net = MininetTools.create_network(self.host, self.mn_port)
56 MultiTest.log.info('mininet stared')
57 MultiTest.log.info('waiting {0} seconds...'.format(WAIT_TIME))
61 # add dummy flows to test removal when there are already some flows in operational
62 self.__set_active_map(MapNames.DUMMY)
63 self.adder = FlowAdderThread(self, 0, self.host, self.port, self.net, MultiTest.flows + 1, MultiTest.flows + 11)
66 self.__set_active_map(MapNames.TEST)
67 self.adder = FlowAdderThread(self, 1, self.host, self.port, self.net, 1, MultiTest.flows + 1)
70 # if we didn't manage to get any flows on controller there is no point doing test
71 assert len(MultiTest.active_map) > 0, ('Stored flows should be greater than 0, actual is {0}'.format(len(MultiTest.active_map)))
73 # check numer of flows before deletion
74 MultiTest.log.debug('{0} flows are stored by results from threads, {1} errors'.format(len(MultiTest.active_map), MultiTest.total_errors))
75 MultiTest.log.debug('{0} flows are stored in controller config'.format(self.check_config_flows(self.host, self.port, self.active_map)))
76 MultiTest.log.info('{0} flows are stored in controller operational'.format(self.check_oper_flows_loop(self.host, self.port, self.active_map)))
78 self.remover = FlowRemoverThread(self, 0, self.host, self.port, self.net, list(MultiTest.active_map.items()))
81 MultiTest.log.info('\n\n---------- preparation finished, running test ----------')
83 # check and test after deletion
84 flows_oper_after = self.check_oper_flows_loop(self.host, self.port, self.active_map)
85 MultiTest.log.debug('{0} flows are stored in controller config'.format(self.check_config_flows(self.host, self.port, self.active_map)))
86 MultiTest.log.info('{0} flows are stored in controller operational'.format(flows_oper_after))
88 # check if we have managed to delete all test
89 if len(MultiTest.active_map) <> 0:
90 MultiTest.log.warning('Not all flows added during test have been deleted, ids of remaining flows are: {0}'.format(sorted(MultiTest.active_map)))
92 # if we didn't manage to get any flows on controller there is no point doing test
93 assert flows_oper_after == len(MultiTest.active_map), 'Number of flows added during test stored in operational should be {0}, is {1}'.format(len(MultiTest.active_map), flows_oper_after)
95 def __setup_threads(self):
96 if in_args.threads is not None:
97 self.threads_count = int(in_args.threads)
99 for i in range(0, self.threads_count):
100 #thread will have predetermined flows id to avoid using shared resource
101 t = FlowAdderThread(i, self.host, self.port, self.net, flows_ids_from=i*MultiTest.flows + 1, flows_ids_to=(i+1)*MultiTest.flows + 1)
103 self.thread_pool.append(t)
105 def __run_threads(self):
107 for t in self.thread_pool:
110 # wait for them to finish
111 for t in self.thread_pool:
115 #for t in self.thread_pool:
116 # MultiTest.inc_flow(t.flows)
117 # MultiTest.inc_error(t.errors)
119 if __name__ == '__main__':
120 logging.basicConfig(level=logging.INFO)
122 # parse cmdline arguments
123 parser = argparse.ArgumentParser(description='Test for flow addition to'
124 ' switch after the switch has been restarted')
125 parser.add_argument('--odlhost', default='127.0.0.1', help='host where '
126 'odl controller is running (default is 127.0.0.1)')
127 parser.add_argument('--odlport', type=int, default=8080, help='port on '
128 'which odl\'s RESTCONF is listening (default is 8080)')
129 parser.add_argument('--mnport', type=int, default=6653, help='port on '
130 'which odl\'s controller is listening (default is 6653)')
131 parser.add_argument('--xmls', default=None, help='generete tests only '
132 'from some xmls (i.e. 1,3,34) (default is None - use internal template)')
133 parser.add_argument('--threads', default=5, help='how many threads '
134 'should be used (default is 5)')
135 parser.add_argument('--flows', default=2, help='how many flows will add'
136 ' one thread (default is 10)')
137 in_args = parser.parse_args()
139 # set host and port of ODL controller for test cases
140 MultiTest.port = in_args.odlport
141 MultiTest.host = in_args.odlhost
142 MultiTest.mn_port = in_args.mnport
143 MultiTest.flows = int(in_args.flows)
147 suite = unittest.TestSuite()
148 test = MultiTest('test')
152 unittest.TextTestRunner(verbosity=2).run(suite)