Merge "Fixed a bug where measured rate was not reported properly Added comments into...
[integration/test.git] / test / tools / odl-mdsal-clustering-tests / clustering-performance-test / flow_config_blaster_fle.py
1 #!/usr/bin/python
2 __author__ = "Jan Medved"
3 __copyright__ = "Copyright(c) 2014, Cisco Systems, Inc."
4 __license__ = "New-style BSD"
5 __email__ = "jmedved@cisco.com"
6
7 from flow_config_blaster import FlowConfigBlaster
8 import argparse
9 import netaddr
10 import time
11 import json
12
13 class FlowConfigBlasterFLE(FlowConfigBlaster):
14     """
15     FlowConfigBlaster, Floodlight Edition; Uses the Floodlight Static Flow Entry Pusher REST API to inject flows.
16     """
17     flow = {
18         'switch': "00:00:00:00:00:00:00:01",
19         "name": "flow-mod",
20         "cookie": "0",
21         "priority": "32768",
22         "ether-type": "2048",
23         "dst-ip": "10.0.0.1/32",
24         "active": "true",
25         "actions": "output=flood"
26     }
27
28     def __init__(self, host, port, ncycles, nthreads, nnodes, nflows, startflow):
29         FlowConfigBlaster.__init__(self, host, port, ncycles, nthreads, nnodes, nflows, startflow, False, '')
30
31         # Create the service URL
32         self.url = 'http://' + self.host + ":" + self.port + '/wm/staticflowentrypusher/json'
33
34
35     def get_num_nodes(self, session):
36         """
37         Determines the number of nodes in the network. Overrides the get_num_nodes method in FlowConfigBlaster.
38         :param session:
39         :return:
40         """
41         url = 'http://' + self.host + ":" + self.port + '/wm/core/controller/switches/json'
42         nodes = self.nnodes
43
44         r = session.get(url, headers=self.getheaders, stream=False)
45
46         if r.status_code == 200:
47             try:
48                 nodes = len(json.loads(r.content))
49             except KeyError:
50                 pass
51
52         return nodes
53
54
55     def add_flow(self, session, node, flow_id, ipaddr):
56         """
57         Adds a flow. Overrides the add_flow method in FlowConfigBlaster.
58         :param session:
59         :param node:
60         :param flow_id:
61         :param ipaddr:
62         :return:
63         """
64         self.flow['switch'] = "00:00:00:00:00:00:00:%s" % '{0:02x}'.format(node)
65         self.flow['name'] = 'TestFlow-%d' % flow_id
66         self.flow['cookie'] = str(flow_id)
67         self.flow['dst-ip'] = "%s/32" % str(netaddr.IPAddress(ipaddr))
68
69         flow_data = json.dumps(self.flow)
70         # print flow_data
71         # print flow_url
72
73         r = session.post(self.url, data=flow_data, headers=self.putheaders, stream=False)
74         return r.status_code
75
76
77     def delete_flow(self, session, node, flow_id):
78         """
79         Deletes a flow. Overrides the delete_flow method in FlowConfigBlaster.
80         :param session:
81         :param node:
82         :param flow_id:
83         :return:
84         """
85         f = {'name': 'TestFlow-%d' % flow_id}
86         flow_data = json.dumps(f)
87
88         r = session.delete(self.url, data=flow_data, headers=self.getheaders)
89         return r.status_code
90
91
92 if __name__ == "__main__":
93
94     parser = argparse.ArgumentParser(description='Flow programming performance test for Floodlight: First adds and '
95                                                  'then deletes flows using the Static Flow Entry Pusher REST API.')
96
97     parser.add_argument('--host', default='127.0.0.1',
98                         help='Host where the controller is running (default is 127.0.0.1)')
99     parser.add_argument('--port', default='8080',
100                         help='Port on which the controller\'s RESTCONF is listening (default is 8080)')
101     parser.add_argument('--cycles', type=int, default=1,
102                         help='Number of flow add/delete cycles; default 1. Both Flow Adds and Flow Deletes are '
103                              'performed in cycles. <THREADS> worker threads are started in each cycle and the cycle '
104                              'ends when all threads finish. Another cycle is started when the previous cycle finished.')
105     parser.add_argument('--threads', type=int, default=1,
106                         help='Number of request worker threads to start in each cycle; default=1. '
107                              'Each thread will add/delete <FLOWS> flows.')
108     parser.add_argument('--flows', type=int, default=10,
109                         help='Number of flows that will be added/deleted by each worker thread in each cycle; '
110                              'default 10')
111     parser.add_argument('--nodes', type=int, default=16,
112                         help='Number of nodes if mininet is not connected; default=16. If mininet is connected, '
113                              'flows will be evenly distributed (programmed) into connected nodes.')
114     parser.add_argument('--delay', type=int, default=0,
115                         help='Time (in seconds) to wait between the add and delete cycles; default=0')
116     parser.add_argument('--no-delete', dest='delete', action='store_false',
117                         help='Do not perform the delete cycle.')
118     parser.add_argument('--startflow', type=int, default=0,
119                         help='The starting Flow ID; default=0')
120
121     in_args = parser.parse_args()
122
123
124     fct = FlowConfigBlasterFLE(in_args.host, in_args.port, in_args.cycles, in_args.threads, in_args.nodes,
125                                in_args.flows, in_args.startflow)
126
127     # Run through <cycles>, where <threads> are started in each cycle and <flows> are added from each thread
128     fct.add_blaster()
129
130     print '\n*** Total flows added: %s' % fct.get_total_flows()
131     print '    HTTP[OK] results:  %d\n' % fct.get_ok_flows()
132
133     if in_args.delay > 0:
134         print '*** Waiting for %d seconds before the delete cycle ***\n' % in_args.delay
135         time.sleep(in_args.delay)
136
137     # Run through <cycles>, where <threads> are started in each cycle and <flows> previously added in an add cycle are
138     # deleted in each thread
139     if in_args.delete:
140         fct.delete_blaster()