d28437125261947a95d85c13b857eb9fc2cfc4fb
[openflowplugin.git] / test-scripts / oper_data_test.py
1 import unittest
2 import os
3 import re
4 import sys
5 import logging
6 import time
7 import argparse
8 import requests
9
10 import xml.dom.minidom as md
11 from xml.etree import ElementTree as ET
12
13 from openvswitch.mininet_tools import MininetTools
14 from openvswitch.flow_tools import  FlowAdderThread, FlowRemoverThread, MapNames, loglevels, TO_GET, WAIT_TIME, OPERATIONAL_DELAY, FLOWS_PER_SECOND
15 from openvswitch.testclass_templates import TestClassAdd, TestClassRemove
16 from openvswitch.testclass_components import CheckConfigFlowsComponent, CheckOperFlowsComponent
17
18 class MultiTest(unittest.TestCase, TestClassAdd, TestClassRemove, CheckConfigFlowsComponent, CheckOperFlowsComponent):
19
20     log = logging.getLogger('MultiTest')
21     total_errors = 0
22
23     id_maps = dict()
24     active_map = dict()
25
26     def setUp(self):
27         MultiTest.log.info('test setup...')
28         self.__start_MN()
29
30         MultiTest.id_maps[MapNames.TEST] = dict()
31         MultiTest.id_maps[MapNames.DUMMY] = dict()
32
33         MultiTest.active_map = MultiTest.id_maps[MapNames.TEST]
34
35
36     def tearDown(self):
37         MultiTest.log.info('test cleanup...')
38         self.__set_active_map(MapNames.DUMMY)
39         self.remover = FlowRemoverThread(self, 1, self.host, self.port, self.net, list(MultiTest.active_map.items()))
40         self.remover.run()
41
42         for k, v in MultiTest.id_maps.items():
43             if len(v) > 0:
44                 MultiTest.log.warning('not all flows were deleted, remaining test flows: {0}, from map: {1}'.format(len(v),k))
45
46     def __set_active_map(self, key):
47         try:    
48             MultiTest.active_map = MultiTest.id_maps[key]
49         except KeyError as e:
50             MultiTest.log.warning('Error switching between map ids: {0}'.format(str(e)))
51
52
53     def inc_error(self, value=1):
54         MultiTest.total_errors += value
55
56     def inc_flow(self, flow_id= None, cookie_id=1):
57         if flow_id is not None and cookie_id is not None:
58             #we dont care about actual value, just need to store flow_id as unique identifier           
59             MultiTest.active_map[flow_id] = flow_id
60
61     def delete_flow_from_map(self, flow_id, cookie_id=None):
62         del MultiTest.active_map[flow_id]
63
64     def __start_MN(self):
65         self.net = MininetTools.create_network(self.host, self.mn_port)
66         self.net.start()
67         MultiTest.log.info('mininet stared')
68         MultiTest.log.info('waiting {0} seconds...'.format(WAIT_TIME))
69         time.sleep(WAIT_TIME)
70
71     def test(self):
72         # add dummy flows to test removal when there are already some flows in operational
73         self.__set_active_map(MapNames.DUMMY)
74         self.adder = FlowAdderThread(self, 0, self.host, self.port, self.net, MultiTest.flows + 1, MultiTest.flows + 11)
75         self.adder.run()
76
77         self.__set_active_map(MapNames.TEST)
78         self.adder = FlowAdderThread(self, 1, self.host, self.port, self.net, 1, MultiTest.flows + 1)
79         self.adder.run()
80
81         # if we didn't manage to get any flows on controller there is no point doing test
82         assert len(MultiTest.active_map) > 0, ('Stored flows should be greater than 0, actual is {0}'.format(len(MultiTest.active_map)))
83
84         # check numer of flows before deletion
85         MultiTest.log.debug('{0} flows are stored by results from threads, {1} errors'.format(len(MultiTest.active_map), MultiTest.total_errors))
86         MultiTest.log.debug('{0} flows are stored in controller config'.format(self.check_config_flows(self.host, self.port, self.active_map)))
87         MultiTest.log.info('{0} flows are stored in controller operational'.format(self.check_oper_flows_loop(self.host, self.port, self.active_map)))
88
89         self.remover = FlowRemoverThread(self, 0, self.host, self.port, self.net, list(MultiTest.active_map.items()))
90         self.remover.run()
91
92         MultiTest.log.info('\n\n---------- preparation finished, running test ----------')
93
94         # check and test after deletion
95         flows_oper_after = self.check_oper_flows_loop(self.host, self.port, self.active_map)
96         MultiTest.log.debug('{0} flows are stored in controller config'.format(self.check_config_flows(self.host, self.port, self.active_map)))
97         MultiTest.log.info('{0} flows are stored in controller operational'.format(flows_oper_after))
98
99         # check if we have managed to delete all test
100         if len(MultiTest.active_map) <> 0:
101             MultiTest.log.warning('Not all flows added during test have been deleted, ids of remaining flows are: {0}'.format(sorted(MultiTest.active_map)))
102
103         # if we didn't manage to get any flows on controller there is no point doing test
104         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)
105
106
107 if __name__ == '__main__':
108
109     requests_log = logging.getLogger("requests")
110     requests_log.setLevel(logging.WARNING)
111
112     # parse cmdline arguments
113     parser = argparse.ArgumentParser(description='End to end stress tests of flows '
114                         'addition from multiple connections')
115     parser.add_argument('--odlhost', default='127.0.0.1', help='host where '
116                         'odl controller is running  (default = 127.0.0.1) ')
117     parser.add_argument('--odlport', type=int, default=8080, help='port on '
118                         'which odl\'s RESTCONF is listening  (default = 8080) ')
119     parser.add_argument('--mnport', type=int, default=6653, help='port on '
120                         'which odl\'s controller is listening  (default = 6653)')
121     parser.add_argument('--flows', default=100, help='how many flows will be added'
122                         ' (default = 100)')
123     parser.add_argument('--log', default='info', help='log level, permitted values are'
124                         ' debug/info/warning/error  (default = info)')
125     args = parser.parse_args()
126
127     #logging.basicConfig(level=logging.DEBUG)
128     logging.basicConfig(level=loglevels.get(args.log, logging.INFO))
129
130     # set host and port of ODL controller for test cases
131     MultiTest.port = args.odlport
132     MultiTest.host = args.odlhost
133     MultiTest.mn_port = args.mnport
134     MultiTest.flows = int(args.flows)
135
136     del sys.argv[1:]
137
138     suite = unittest.TestSuite()
139     test = MultiTest('test')
140     suite.addTest(test)
141
142     try:
143         unittest.TextTestRunner(verbosity=2).run(suite)
144         #unittest.main()
145     finally:
146         test.net.stop()
147         print 'end'