blob: e3940f81fd0aea5b05cf0f6557db241a537774a0 [file] [log] [blame]
andrewonlab2a6c9342014-10-16 13:40:15 -04001#TopoPerfNext
2#
3#Topology Performance test for ONOS-next
4#
5#andrew@onlab.us
6
7import time
8import sys
9import os
10import re
11
12class TopoPerfNext:
13 def __init__(self):
14 self.default = ''
15
16 def CASE1(self, main):
17 '''
18 ONOS startup sequence
19 '''
andrewonlabe9fb6722014-10-24 12:20:35 -040020 import time
21
andrewonlab2a6c9342014-10-16 13:40:15 -040022 cell_name = main.params['ENV']['cellName']
23
24 git_pull = main.params['GIT']['autoPull']
25 checkout_branch = main.params['GIT']['checkout']
26
27 ONOS1_ip = main.params['CTRL']['ip1']
andrewonlabba44bcf2014-10-16 16:54:41 -040028 ONOS2_ip = main.params['CTRL']['ip2']
29 ONOS3_ip = main.params['CTRL']['ip3']
andrewonlab2a6c9342014-10-16 13:40:15 -040030 MN1_ip = main.params['MN']['ip1']
31 BENCH_ip = main.params['BENCH']['ip']
32
33 main.case("Setting up test environment")
34
35 main.step("Creating cell file")
36 cell_file_result = main.ONOSbench.create_cell_file(
andrewonlabe6745342014-10-17 14:29:13 -040037 BENCH_ip, cell_name, MN1_ip, "onos-core",
andrewonlabba44bcf2014-10-16 16:54:41 -040038 ONOS1_ip, ONOS2_ip, ONOS3_ip)
andrewonlab2a6c9342014-10-16 13:40:15 -040039
40 main.step("Applying cell file to environment")
41 cell_apply_result = main.ONOSbench.set_cell(cell_name)
42 verify_cell_result = main.ONOSbench.verify_cell()
43
44 main.step("Git checkout and pull "+checkout_branch)
45 if git_pull == 'on':
46 checkout_result = \
47 main.ONOSbench.git_checkout(checkout_branch)
48 pull_result = main.ONOSbench.git_pull()
49 else:
50 checkout_result = main.TRUE
51 pull_result = main.TRUE
52 main.log.info("Skipped git checkout and pull")
53
54 main.step("Using mvn clean & install")
andrewonlab8d29f122014-10-22 17:15:04 -040055 #mvn_result = main.ONOSbench.clean_install()
56 mvn_result = main.TRUE
andrewonlab2a6c9342014-10-16 13:40:15 -040057
58 main.step("Creating ONOS package")
59 package_result = main.ONOSbench.onos_package()
60
61 main.step("Installing ONOS package")
andrewonlabe9fb6722014-10-24 12:20:35 -040062 install1_result = main.ONOSbench.onos_install(node=ONOS1_ip)
63 install2_result = main.ONOSbench.onos_install(node=ONOS2_ip)
64 install3_result = main.ONOSbench.onos_install(node=ONOS3_ip)
andrewonlab2a6c9342014-10-16 13:40:15 -040065
andrewonlabe9fb6722014-10-24 12:20:35 -040066 #NOTE: This step may be unnecessary
67 #main.step("Starting ONOS service")
68 #start_result = main.ONOSbench.onos_start(ONOS1_ip)
andrewonlab2a6c9342014-10-16 13:40:15 -040069
andrewonlab867212a2014-10-22 20:13:38 -040070 main.step("Set cell for ONOS cli env")
71 main.ONOS1cli.set_cell(cell_name)
72 main.ONOS2cli.set_cell(cell_name)
73 main.ONOS3cli.set_cell(cell_name)
74
andrewonlabe9fb6722014-10-24 12:20:35 -040075 time.sleep(10)
76
andrewonlab867212a2014-10-22 20:13:38 -040077 main.step("Start onos cli")
andrewonlabe9fb6722014-10-24 12:20:35 -040078 cli1 = main.ONOS1cli.start_onos_cli(ONOS1_ip)
79 cli2 = main.ONOS2cli.start_onos_cli(ONOS2_ip)
80 cli3 = main.ONOS3cli.start_onos_cli(ONOS3_ip)
81
andrewonlab867212a2014-10-22 20:13:38 -040082 main.step("Enable metrics feature")
83 main.ONOS1cli.feature_install("onos-app-metrics-topology")
84 main.ONOS2cli.feature_install("onos-app-metrics-topology")
85 main.ONOS3cli.feature_install("onos-app-metrics-topology")
86
andrewonlab2a6c9342014-10-16 13:40:15 -040087 utilities.assert_equals(expect=main.TRUE,
88 actual= cell_file_result and cell_apply_result and\
89 verify_cell_result and checkout_result and\
90 pull_result and mvn_result and\
andrewonlabe9fb6722014-10-24 12:20:35 -040091 install1_result and install2_result and\
92 install3_result,
andrewonlab8d29f122014-10-22 17:15:04 -040093 onpass="ONOS started successfully",
94 onfail="Failed to start ONOS")
andrewonlab2a6c9342014-10-16 13:40:15 -040095
andrewonlabba44bcf2014-10-16 16:54:41 -040096 def CASE2(self, main):
97 '''
98 Assign s1 to ONOS1 and measure latency
andrewonlab3a7c3c72014-10-24 17:21:03 -040099
100 There are 4 levels of latency measurements to this test:
101 1) End-to-end measurement: Complete end-to-end measurement
102 from TCP (SYN/ACK) handshake to Graph change
103 2) OFP-to-graph measurement: 'ONOS processing' snippet of
104 measurement from OFP Vendor message to Graph change
105 3) OFP-to-device measurement: 'ONOS processing without
106 graph change' snippet of measurement from OFP vendor
107 message to Device change timestamp
108 4) T0-to-device measurement: Measurement that includes
109 the switch handshake to devices timestamp without
110 the graph view change. (TCP handshake -> Device
111 change)
andrewonlabba44bcf2014-10-16 16:54:41 -0400112 '''
113 import time
andrewonlabe6745342014-10-17 14:29:13 -0400114 import subprocess
115 import json
116 import requests
117 import os
andrewonlabba44bcf2014-10-16 16:54:41 -0400118
119 ONOS1_ip = main.params['CTRL']['ip1']
120 ONOS2_ip = main.params['CTRL']['ip2']
121 ONOS3_ip = main.params['CTRL']['ip3']
andrewonlabe6745342014-10-17 14:29:13 -0400122 ONOS_user = main.params['CTRL']['user']
123
andrewonlabba44bcf2014-10-16 16:54:41 -0400124 default_sw_port = main.params['CTRL']['port1']
125
126 #Number of iterations of case
127 num_iter = main.params['TEST']['numIter']
128
andrewonlab226024e2014-10-24 16:01:32 -0400129 #Timestamp 'keys' for json metrics output.
130 #These are subject to change, hence moved into params
131 deviceTimestamp = main.params['JSON']['deviceTimestamp']
132 graphTimestamp = main.params['JSON']['graphTimestamp']
133
134 #List of switch add latency collected from
135 #all iterations
136 latency_end_to_end_list = []
137 latency_ofp_to_graph_list = []
138 latency_ofp_to_device_list = []
139 latency_t0_to_device_list = []
140
andrewonlabba44bcf2014-10-16 16:54:41 -0400141 #Directory/file to store tshark results
142 tshark_of_output = "/tmp/tshark_of_topo.txt"
143 tshark_tcp_output = "/tmp/tshark_tcp_topo.txt"
144
145 #String to grep in tshark output
146 tshark_tcp_string = "TCP 74 "+default_sw_port
147 tshark_of_string = "OFP 86 Vendor"
andrewonlabe6745342014-10-17 14:29:13 -0400148
149 #Initialize assertion to TRUE
150 assertion = main.TRUE
151
andrewonlabba44bcf2014-10-16 16:54:41 -0400152 main.log.report("Latency of adding one switch")
153
154 for i in range(0, int(num_iter)):
155 main.log.info("Starting tshark capture")
156
157 #* TCP [ACK, SYN] is used as t0_a, the
158 # very first "exchange" between ONOS and
159 # the switch for end-to-end measurement
160 #* OFP [Stats Reply] is used for t0_b
161 # the very last OFP message between ONOS
162 # and the switch for ONOS measurement
163 main.ONOS1.tshark_grep(tshark_tcp_string,
164 tshark_tcp_output)
165 main.ONOS1.tshark_grep(tshark_of_string,
166 tshark_of_output)
167
168 #Wait and ensure tshark is started and
169 #capturing
170 time.sleep(10)
171
172 main.log.info("Assigning s1 to controller")
173
174 main.Mininet1.assign_sw_controller(sw="1",
175 ip1=ONOS1_ip, port1=default_sw_port)
176
177 #Wait and ensure switch is assigned
178 #before stopping tshark
andrewonlab867212a2014-10-22 20:13:38 -0400179 time.sleep(30)
andrewonlab226024e2014-10-24 16:01:32 -0400180
181 main.log.info("Stopping all Tshark processes")
andrewonlabba44bcf2014-10-16 16:54:41 -0400182 main.ONOS1.stop_tshark()
183
andrewonlabe6745342014-10-17 14:29:13 -0400184 #tshark output is saved in ONOS. Use subprocess
185 #to copy over files to TestON for parsing
186 main.log.info("Copying over tshark files")
187
188 #TCP CAPTURE ****
andrewonlab8d29f122014-10-22 17:15:04 -0400189 #Copy the tshark output from ONOS machine to
190 #TestON machine in tshark_tcp_output directory>file
191 os.system("scp "+ONOS_user+"@"+ONOS1_ip+":"+
192 tshark_tcp_output+" /tmp/")
193 tcp_file = open(tshark_tcp_output, 'r')
194 temp_text = tcp_file.readline()
andrewonlabe6745342014-10-17 14:29:13 -0400195 temp_text = temp_text.split(" ")
andrewonlabba44bcf2014-10-16 16:54:41 -0400196
andrewonlabe6745342014-10-17 14:29:13 -0400197 main.log.info("Object read in from TCP capture: "+
198 str(temp_text))
andrewonlab867212a2014-10-22 20:13:38 -0400199 if len(temp_text) > 1:
andrewonlab3a7c3c72014-10-24 17:21:03 -0400200 t0_tcp = float(temp_text[1])*1000.0
andrewonlabe6745342014-10-17 14:29:13 -0400201 else:
202 main.log.error("Tshark output file for TCP"+
203 " returned unexpected results")
204 t0_tcp = 0
205 assertion = main.FALSE
andrewonlab8d29f122014-10-22 17:15:04 -0400206
207 tcp_file.close()
andrewonlabe6745342014-10-17 14:29:13 -0400208 #****************
andrewonlabba44bcf2014-10-16 16:54:41 -0400209
andrewonlabe6745342014-10-17 14:29:13 -0400210 #OF CAPTURE ****
andrewonlab8d29f122014-10-22 17:15:04 -0400211 os.system("scp "+ONOS_user+"@"+ONOS1_ip+":"+
212 tshark_of_output+" /tmp/")
213 of_file = open(tshark_of_output, 'r')
214
215 line_ofp = ""
andrewonlab226024e2014-10-24 16:01:32 -0400216 #Read until last line of file
andrewonlabe6745342014-10-17 14:29:13 -0400217 while True:
andrewonlab8d29f122014-10-22 17:15:04 -0400218 temp_text = of_file.readline()
219 if temp_text !='':
andrewonlabe6745342014-10-17 14:29:13 -0400220 line_ofp = temp_text
221 else:
222 break
223 obj = line_ofp.split(" ")
224
225 main.log.info("Object read in from OFP capture: "+
226 str(line_ofp))
227
andrewonlab867212a2014-10-22 20:13:38 -0400228 if len(line_ofp) > 1:
andrewonlab3a7c3c72014-10-24 17:21:03 -0400229 t0_ofp = float(obj[1])*1000.0
andrewonlabe6745342014-10-17 14:29:13 -0400230 else:
231 main.log.error("Tshark output file for OFP"+
232 " returned unexpected results")
233 t0_ofp = 0
234 assertion = main.FALSE
andrewonlab8d29f122014-10-22 17:15:04 -0400235
236 of_file.close()
andrewonlabe6745342014-10-17 14:29:13 -0400237 #****************
238
andrewonlab867212a2014-10-22 20:13:38 -0400239 json_str_1 = main.ONOS1cli.topology_events_metrics()
240 json_str_2 = main.ONOS2cli.topology_events_metrics()
241 json_str_3 = main.ONOS3cli.topology_events_metrics()
andrewonlab867212a2014-10-22 20:13:38 -0400242
243 json_obj_1 = json.loads(json_str_1)
244 json_obj_2 = json.loads(json_str_2)
245 json_obj_3 = json.loads(json_str_3)
246
andrewonlab226024e2014-10-24 16:01:32 -0400247 #Obtain graph timestamp. This timestsamp captures
248 #the epoch time at which the topology graph was updated.
249 graph_timestamp_1 = \
250 json_obj_1[graphTimestamp]['value']
251 graph_timestamp_2 = \
252 json_obj_2[graphTimestamp]['value']
253 graph_timestamp_3 = \
254 json_obj_3[graphTimestamp]['value']
andrewonlab867212a2014-10-22 20:13:38 -0400255
andrewonlab226024e2014-10-24 16:01:32 -0400256 #Obtain device timestamp. This timestamp captures
257 #the epoch time at which the device event happened
258 device_timestamp_1 = \
259 json_obj_1[deviceTimestamp]['value']
260 device_timestamp_2 = \
261 json_obj_2[deviceTimestamp]['value']
262 device_timestamp_3 = \
263 json_obj_3[deviceTimestamp]['value']
andrewonlabe9fb6722014-10-24 12:20:35 -0400264
andrewonlab226024e2014-10-24 16:01:32 -0400265 #t0 to device processing latency
266 delta_device_1 = int(device_timestamp_1) - int(t0_tcp)
267 delta_device_2 = int(device_timestamp_2) - int(t0_tcp)
268 delta_device_3 = int(device_timestamp_3) - int(t0_tcp)
269
270 #Get average of delta from all instances
271 avg_delta_device = \
272 (int(delta_device_1)+\
273 int(delta_device_2)+\
274 int(delta_device_3)) / 3
andrewonlabba44bcf2014-10-16 16:54:41 -0400275
andrewonlab226024e2014-10-24 16:01:32 -0400276 #Ensure avg delta meets the threshold before appending
277 if avg_delta_device > 0.0 and avg_delta_device < 10000:
278 latency_t0_to_device_list.append(avg_delta_device)
andrewonlabee4efeb2014-10-24 16:44:51 -0400279 else:
andrewonlab09d973e2014-10-24 18:56:58 -0400280 main.log.info("Results for t0-to-device ignored"+\
281 "due to excess in threshold")
andrewonlabee4efeb2014-10-24 16:44:51 -0400282
andrewonlab226024e2014-10-24 16:01:32 -0400283 #t0 to graph processing latency (end-to-end)
284 delta_graph_1 = int(graph_timestamp_1) - int(t0_tcp)
285 delta_graph_2 = int(graph_timestamp_2) - int(t0_tcp)
286 delta_graph_3 = int(graph_timestamp_3) - int(t0_tcp)
287
288 #Get average of delta from all instances
289 avg_delta_graph = \
290 (int(delta_graph_1)+\
291 int(delta_graph_2)+\
292 int(delta_graph_3)) / 3
293
andrewonlab226024e2014-10-24 16:01:32 -0400294 #Ensure avg delta meets the threshold before appending
295 if avg_delta_graph > 0.0 and avg_delta_graph < 10000:
andrewonlab09d973e2014-10-24 18:56:58 -0400296 latency_end_to_end_list.append(avg_delta_graph)
andrewonlabee4efeb2014-10-24 16:44:51 -0400297 else:
andrewonlab09d973e2014-10-24 18:56:58 -0400298 main.log.info("Results for end-to-end ignored"+\
299 "due to excess in threshold")
andrewonlab226024e2014-10-24 16:01:32 -0400300
301 #ofp to graph processing latency (ONOS processing)
302 delta_ofp_graph_1 = int(graph_timestamp_1) - int(t0_ofp)
303 delta_ofp_graph_2 = int(graph_timestamp_2) - int(t0_ofp)
304 delta_ofp_graph_3 = int(graph_timestamp_3) - int(t0_ofp)
305
306 avg_delta_ofp_graph = \
307 (int(delta_ofp_graph_1)+\
308 int(delta_ofp_graph_2)+\
309 int(delta_ofp_graph_3)) / 3
310
311 if avg_delta_ofp_graph > 0.0 and avg_delta_ofp_graph < 10000:
312 latency_ofp_to_graph_list.append(avg_delta_ofp_graph)
andrewonlabee4efeb2014-10-24 16:44:51 -0400313 else:
andrewonlab09d973e2014-10-24 18:56:58 -0400314 main.log.info("Results for ofp-to-graph "+\
315 "ignored due to excess in threshold")
andrewonlabee4efeb2014-10-24 16:44:51 -0400316
andrewonlab226024e2014-10-24 16:01:32 -0400317 #ofp to device processing latency (ONOS processing)
andrewonlabee4efeb2014-10-24 16:44:51 -0400318 delta_ofp_device_1 = float(device_timestamp_1) - float(t0_ofp)
319 delta_ofp_device_2 = float(device_timestamp_2) - float(t0_ofp)
320 delta_ofp_device_3 = float(device_timestamp_3) - float(t0_ofp)
andrewonlab226024e2014-10-24 16:01:32 -0400321
322 avg_delta_ofp_device = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400323 (float(delta_ofp_device_1)+\
324 float(delta_ofp_device_2)+\
325 float(delta_ofp_device_3)) / 3.0
andrewonlab226024e2014-10-24 16:01:32 -0400326
andrewonlabf47993a2014-10-24 17:56:01 -0400327 #NOTE: ofp - delta measurements are occasionally negative
328 # due to system time misalignment.
329 #TODO: Implement ptp across all clusters
330 #Just add the calculation to list for now
331 latency_ofp_to_device_list.append(avg_delta_ofp_device)
andrewonlabba44bcf2014-10-16 16:54:41 -0400332
andrewonlabe6745342014-10-17 14:29:13 -0400333 #TODO:
334 #Fetch logs upon threshold excess
andrewonlabba44bcf2014-10-16 16:54:41 -0400335
andrewonlabf47993a2014-10-24 17:56:01 -0400336
andrewonlab226024e2014-10-24 16:01:32 -0400337 main.log.info("ONOS1 delta end-to-end: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400338 str(delta_graph_1) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400339 main.log.info("ONOS2 delta end-to-end: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400340 str(delta_graph_2) + " ms")
341 main.log.info("ONOS3 delta end-to-end: "+
342 str(delta_graph_3) + " ms")
andrewonlabba44bcf2014-10-16 16:54:41 -0400343
andrewonlab226024e2014-10-24 16:01:32 -0400344 main.log.info("ONOS1 delta OFP - graph: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400345 str(delta_ofp_graph_1) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400346 main.log.info("ONOS2 delta OFP - graph: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400347 str(delta_ofp_graph_2) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400348 main.log.info("ONOS3 delta OFP - graph: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400349 str(delta_ofp_graph_3) + " ms")
andrewonlabe6745342014-10-17 14:29:13 -0400350
andrewonlab226024e2014-10-24 16:01:32 -0400351 main.log.info("ONOS1 delta device - t0: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400352 str(delta_device_1) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400353 main.log.info("ONOS2 delta device - t0: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400354 str(delta_device_2) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400355 main.log.info("ONOS3 delta device - t0: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400356 str(delta_device_3) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400357
358 main.log.info("ONOS1 delta OFP - device: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400359 str(delta_ofp_device_1) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400360 main.log.info("ONOS2 delta OFP - device: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400361 str(delta_ofp_device_2) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400362 main.log.info("ONOS3 delta OFP - device: "+
andrewonlab09d973e2014-10-24 18:56:58 -0400363 str(delta_ofp_device_3) + " ms")
andrewonlab226024e2014-10-24 16:01:32 -0400364
andrewonlab8d29f122014-10-22 17:15:04 -0400365 main.step("Remove switch from controller")
366 main.Mininet1.delete_sw_controller("s1")
andrewonlabba44bcf2014-10-16 16:54:41 -0400367
andrewonlab8d29f122014-10-22 17:15:04 -0400368 time.sleep(5)
andrewonlabba44bcf2014-10-16 16:54:41 -0400369
andrewonlab09d973e2014-10-24 18:56:58 -0400370 #END of for loop iteration
andrewonlabf47993a2014-10-24 17:56:01 -0400371
andrewonlabee4efeb2014-10-24 16:44:51 -0400372 #If there is at least 1 element in each list,
andrewonlabc15c9582014-10-24 16:35:52 -0400373 #pass the test case
374 if len(latency_end_to_end_list) > 0 and\
375 len(latency_ofp_to_graph_list) > 0 and\
376 len(latency_ofp_to_device_list) > 0 and\
377 len(latency_t0_to_device_list) > 0:
378 assertion = main.TRUE
andrewonlabf47993a2014-10-24 17:56:01 -0400379 elif len(latency_end_to_end_list) == 0:
380 #The appending of 0 here is to prevent
381 #the min,max,sum functions from failing
382 #below
383 latency_end_to_end_list.append(0)
384 assertion = main.FALSE
385 elif len(latency_ofp_to_graph_list) == 0:
386 latency_ofp_to_graph_list.append(0)
387 assertion = main.FALSE
388 elif len(latency_ofp_to_device_list) == 0:
389 latency_ofp_to_device_list.append(0)
390 assertion = main.FALSE
391 elif len(latency_t0_to_device_list) == 0:
392 latency_t0_to_device_list.append(0)
393 assertion = main.FALSE
andrewonlabc15c9582014-10-24 16:35:52 -0400394
395 #Calculate min, max, avg of latency lists
396 latency_end_to_end_max = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400397 int(max(latency_end_to_end_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400398 latency_end_to_end_min = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400399 int(min(latency_end_to_end_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400400 latency_end_to_end_avg = \
andrewonlabc90667c2014-10-24 16:48:28 -0400401 (int(sum(latency_end_to_end_list)) / \
andrewonlabc15c9582014-10-24 16:35:52 -0400402 len(latency_end_to_end_list))
403
404 latency_ofp_to_graph_max = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400405 int(max(latency_ofp_to_graph_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400406 latency_ofp_to_graph_min = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400407 int(min(latency_ofp_to_graph_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400408 latency_ofp_to_graph_avg = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400409 (int(sum(latency_ofp_to_graph_list)) / \
andrewonlabc15c9582014-10-24 16:35:52 -0400410 len(latency_ofp_to_graph_list))
411
412 latency_ofp_to_device_max = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400413 int(max(latency_ofp_to_device_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400414 latency_ofp_to_device_min = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400415 int(min(latency_ofp_to_device_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400416 latency_ofp_to_device_avg = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400417 (int(sum(latency_ofp_to_device_list)) / \
andrewonlabc15c9582014-10-24 16:35:52 -0400418 len(latency_ofp_to_device_list))
419
420 latency_t0_to_device_max = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400421 float(max(latency_t0_to_device_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400422 latency_t0_to_device_min = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400423 float(min(latency_t0_to_device_list))
andrewonlabc15c9582014-10-24 16:35:52 -0400424 latency_t0_to_device_avg = \
andrewonlabee4efeb2014-10-24 16:44:51 -0400425 (float(sum(latency_t0_to_device_list)) / \
andrewonlabc15c9582014-10-24 16:35:52 -0400426 len(latency_ofp_to_device_list))
427
428 main.log.report("Switch add - End-to-end latency: \n"+\
429 "Min: "+str(latency_end_to_end_min)+"\n"+\
430 "Max: "+str(latency_end_to_end_max)+"\n"+\
431 "Avg: "+str(latency_end_to_end_avg))
432 main.log.report("Switch add - OFP-to-Graph latency: \n"+\
433 "Min: "+str(latency_ofp_to_graph_min)+"\n"+\
434 "Max: "+str(latency_ofp_to_graph_max)+"\n"+\
435 "Avg: "+str(latency_ofp_to_graph_avg))
436 main.log.report("Switch add - OFP-to-Device latency: \n"+\
437 "Min: "+str(latency_ofp_to_device_min)+"\n"+\
438 "Max: "+str(latency_ofp_to_device_max)+"\n"+\
439 "Avg: "+str(latency_ofp_to_device_avg))
440 main.log.report("Switch add - t0-to-Device latency: \n"+\
441 "Min: "+str(latency_t0_to_device_min)+"\n"+\
442 "Max: "+str(latency_t0_to_device_max)+"\n"+\
443 "Avg: "+str(latency_t0_to_device_avg))
andrewonlab226024e2014-10-24 16:01:32 -0400444
andrewonlab8d29f122014-10-22 17:15:04 -0400445 utilities.assert_equals(expect=main.TRUE, actual=assertion,
446 onpass="Switch latency test successful",
447 onfail="Switch latency test failed")
andrewonlabba44bcf2014-10-16 16:54:41 -0400448
andrewonlab8d29f122014-10-22 17:15:04 -0400449 def CASE3(self, main):
450 '''
451 Bring port up / down and measure latency.
452 Port enable / disable is simulated by ifconfig up / down
andrewonlab393531a2014-10-27 18:36:26 -0400453
454 In ONOS-next, we must ensure that the port we are
455 manipulating is connected to another switch with a valid
456 connection. Otherwise, graph view will not be updated.
andrewonlab8d29f122014-10-22 17:15:04 -0400457 '''
458 import time
459 import subprocess
460 import os
461 import requests
462 import json
andrewonlab2a6c9342014-10-16 13:40:15 -0400463
andrewonlab8d29f122014-10-22 17:15:04 -0400464 ONOS1_ip = main.params['CTRL']['ip1']
andrewonlab393531a2014-10-27 18:36:26 -0400465 ONOS2_ip = main.params['CTRL']['ip2']
466 ONOS3_ip = main.params['CTRL']['ip3']
andrewonlab8d29f122014-10-22 17:15:04 -0400467 ONOS_user = main.params['CTRL']['user']
andrewonlab8d29f122014-10-22 17:15:04 -0400468
andrewonlab393531a2014-10-27 18:36:26 -0400469 default_sw_port = main.params['CTRL']['port1']
470
471 #Number of iterations of case
472 num_iter = main.params['TEST']['numIter']
473
474 #Timestamp 'keys' for json metrics output.
475 #These are subject to change, hence moved into params
476 deviceTimestamp = main.params['JSON']['deviceTimestamp']
477 graphTimestamp = main.params['JSON']['graphTimestamp']
478
479 #NOTE: Some hardcoded variables you may need to configure
480 # besides the params
481
andrewonlab8d29f122014-10-22 17:15:04 -0400482 tshark_port_status = "OFP 130 Port Status"
483
484 tshark_port_up = "/tmp/tshark_port_up.txt"
485 tshark_port_down = "/tmp/tshark_port_down.txt"
andrewonlab393531a2014-10-27 18:36:26 -0400486 interface_config = "s1-eth1"
andrewonlab8d29f122014-10-22 17:15:04 -0400487
488 main.log.report("Port enable / disable latency")
489
andrewonlab393531a2014-10-27 18:36:26 -0400490 main.step("Assign switches s1 and s2 to controller 1")
andrewonlab8d29f122014-10-22 17:15:04 -0400491 main.Mininet1.assign_sw_controller(sw="1",ip1=ONOS1_ip,
492 port1=default_sw_port)
andrewonlab393531a2014-10-27 18:36:26 -0400493 main.Mininet1.assign_sw_controller(sw="2",ip1=ONOS1_ip,
494 port1=default_sw_port)
andrewonlab8d29f122014-10-22 17:15:04 -0400495
496 main.step("Verify switch is assigned correctly")
497 result_s1 = main.Mininet1.get_sw_controller(sw="s1")
andrewonlab393531a2014-10-27 18:36:26 -0400498 result_s2 = main.Mininet1.get_sw_controller(sw="s2")
499 if result_s1 == main.FALSE or result_s2 == main.FALSE:
andrewonlab8d29f122014-10-22 17:15:04 -0400500 main.log.info("Switch s1 was not assigned correctly")
501 assertion = main.FALSE
502 else:
503 main.log.info("Switch s1 was assigned correctly")
504
andrewonlab393531a2014-10-27 18:36:26 -0400505 port_up_device_to_ofp_list = []
506 port_up_graph_to_ofp_list = []
507 port_down_device_to_ofp_list = []
508 port_down_graph_to_ofp_list = []
509
andrewonlab8d29f122014-10-22 17:15:04 -0400510 for i in range(0, int(num_iter)):
511 main.step("Starting wireshark capture for port status down")
512 main.ONOS1.tshark_grep(tshark_port_status,
513 tshark_port_down)
514
515 time.sleep(10)
516
andrewonlab393531a2014-10-27 18:36:26 -0400517 #Disable interface that is connected to switch 2
518 main.step("Disable port: "+interface_config)
519 main.Mininet2.handle.sendline("sudo ifconfig "+
520 interface_config+" down")
andrewonlab8d29f122014-10-22 17:15:04 -0400521 main.Mininet2.handle.expect("\$")
522 time.sleep(20)
523
524 main.ONOS1.tshark_stop()
525 time.sleep(5)
526
527 #Copy tshark output file from ONOS to TestON instance
528 #/tmp directory
529 os.system("scp "+ONOS_user+"@"+ONOS1_ip+":"+
530 tshark_port_down+" /tmp/")
531
532 f_port_down = open(tshark_port_down, 'r')
andrewonlab393531a2014-10-27 18:36:26 -0400533 #Get first line of port down event from tshark
andrewonlab8d29f122014-10-22 17:15:04 -0400534 f_line = f_port_down.readline()
535 obj_down = f_line.split(" ")
536 if len(f_line) > 0:
andrewonlab393531a2014-10-27 18:36:26 -0400537 timestamp_begin_pt_down = int(float(obj_down[1]))*1000
538 main.log.info("Port down begin timestamp: "+
539 str(timestamp_begin_pt_down))
andrewonlab8d29f122014-10-22 17:15:04 -0400540 else:
541 main.log.info("Tshark output file returned unexpected"+
andrewonlab393531a2014-10-27 18:36:26 -0400542 " results: "+str(obj_down))
andrewonlab8d29f122014-10-22 17:15:04 -0400543 timestamp_begin_pt_down = 0
andrewonlab393531a2014-10-27 18:36:26 -0400544
545 f_port_down.close()
andrewonlab8d29f122014-10-22 17:15:04 -0400546
547 main.step("Obtain t1 by REST call")
andrewonlab393531a2014-10-27 18:36:26 -0400548 json_str_1 = main.ONOS1cli.topology_events_metrics()
549 json_str_2 = main.ONOS2cli.topology_events_metrics()
550 json_str_3 = main.ONOS3cli.topology_events_metrics()
andrewonlab8d29f122014-10-22 17:15:04 -0400551
andrewonlab393531a2014-10-27 18:36:26 -0400552 json_obj_1 = json.loads(json_str_1)
553 json_obj_2 = json.loads(json_str_2)
554 json_obj_3 = json.loads(json_str_3)
andrewonlab8d29f122014-10-22 17:15:04 -0400555
andrewonlab393531a2014-10-27 18:36:26 -0400556 time.sleep(5)
557
558 #Obtain graph timestamp. This timestsamp captures
559 #the epoch time at which the topology graph was updated.
560 graph_timestamp_1 = \
561 json_obj_1[graphTimestamp]['value']
562 graph_timestamp_2 = \
563 json_obj_2[graphTimestamp]['value']
564 graph_timestamp_3 = \
565 json_obj_3[graphTimestamp]['value']
566
567 #TODO: Test purposes, remove later
568 main.log.info("json_timestamp graph: "+str(graph_timestamp_1))
569 main.log.info("json_timestamp graph: "+str(graph_timestamp_2))
570 main.log.info("json_timestamp graph: "+str(graph_timestamp_3))
571
572 #Obtain device timestamp. This timestamp captures
573 #the epoch time at which the device event happened
574 device_timestamp_1 = \
575 json_obj_1[deviceTimestamp]['value']
576 device_timestamp_2 = \
577 json_obj_2[deviceTimestamp]['value']
578 device_timestamp_3 = \
579 json_obj_3[deviceTimestamp]['value']
580
581 #TODO: Test purposes, remove later
582 main.log.info("json_timestamp device: "+str(device_timestamp_1))
583 main.log.info("json_timestamp device: "+str(device_timestamp_2))
584 main.log.info("json_timestamp device: "+str(device_timestamp_3))
585
586 #Get delta between graph event and OFP
587 pt_down_graph_to_ofp_1 = int(graph_timestamp_1) -\
588 int(timestamp_begin_pt_down)
589 pt_down_graph_to_ofp_2 = int(graph_timestamp_2) -\
590 int(timestamp_begin_pt_down)
591 pt_down_graph_to_ofp_3 = int(graph_timestamp_3) -\
592 int(timestamp_begin_pt_down)
593
594 #Get delta between device event and OFP
595 pt_down_device_to_ofp_1 = int(device_timestamp_1) -\
596 int(timestamp_begin_pt_down)
597 pt_down_device_to_ofp_2 = int(device_timestamp_2) -\
598 int(timestamp_begin_pt_down)
599 pt_down_device_to_ofp_3 = int(device_timestamp_3) -\
600 int(timestamp_begin_pt_down)
601
602 #Caluclate average across clusters
603 pt_down_graph_to_ofp_avg =\
604 (int(pt_down_graph_to_ofp_1) +
605 int(pt_down_graph_to_ofp_2) +
606 int(pt_down_graph_to_ofp_3)) / 3
607 pt_down_device_to_ofp_avg = \
608 (int(pt_down_device_to_ofp_1) +
609 int(pt_down_device_to_ofp_2) +
610 int(pt_down_device_to_ofp_3)) / 3
611
612 if pt_down_graph_to_ofp_avg > 0 and \
613 pt_down_graph_to_ofp_avg < 1000:
614 port_down_graph_to_ofp_list.append(
615 pt_down_graph_to_ofp_avg)
616 else:
617 main.log.info("Average port down graph-to-ofp result" +
618 " exceeded the threshold: "+
619 str(pt_down_graph_to_ofp_avg))
620
andrewonlab3622beb2014-10-28 16:07:56 -0400621 if pt_down_device_to_ofp_avg > 0 and \
622 pt_down_device_to_ofp_avg < 1000:
623 port_down_device_to_ofp_list.append(
624 pt_down_device_to_ofp_avg)
625 else:
626 main.log.info("Average port down device-to-ofp result" +
627 " exceeded the threshold: "+
628 str(pt_down_device_to_ofp_avg))
629
andrewonlab8d29f122014-10-22 17:15:04 -0400630 #TODO: Remove these logs. For test purposes only
andrewonlab393531a2014-10-27 18:36:26 -0400631 main.log.info("Delta1 down graph: "+str(pt_down_graph_to_ofp_1))
632 main.log.info("Delta2 down graph: "+str(pt_down_graph_to_ofp_2))
633 main.log.info("Delta3 down graph: "+str(pt_down_graph_to_ofp_3))
634
635 main.log.info("Delta1 down device: "+
636 str(pt_down_device_to_ofp_1))
637 main.log.info("Delta2 down device: "+
638 str(pt_down_device_to_ofp_2))
639 main.log.info("Delta3 down device: "+
640 str(pt_down_device_to_ofp_3))
andrewonlab8d29f122014-10-22 17:15:04 -0400641
642 #Port up events
643 main.step("Enable port and obtain timestamp")
644 main.step("Starting wireshark capture for port status up")
645 main.ONOS1.tshark_grep("OFP 130 Port Status", tshark_port_up)
646 time.sleep(10)
647
andrewonlab393531a2014-10-27 18:36:26 -0400648 main.Mininet2.handle.sendline("sudo ifconfig "+
649 interface_config+" up")
andrewonlab8d29f122014-10-22 17:15:04 -0400650 main.Mininet2.handle.expect("\$")
651 time.sleep(20)
652
653 os.system("scp "+ONOS_user+"@"+ONOS1_ip+":"+
654 tshark_port_up+" /tmp/")
655
656 f_port_up = open(tshark_port_up, 'r')
andrewonlab393531a2014-10-27 18:36:26 -0400657 f_line = f_port_up.readline()
andrewonlab8d29f122014-10-22 17:15:04 -0400658 obj_up = f_line.split(" ")
659 if len(f_line) > 0:
andrewonlab393531a2014-10-27 18:36:26 -0400660 timestamp_begin_pt_up = int(float(obj_up[1]))*1000
661 main.log.info("Port up begin timestamp: "+
662 str(timestamp_begin_pt_up))
andrewonlab8d29f122014-10-22 17:15:04 -0400663 else:
664 main.log.info("Tshark output file returned unexpected"+
665 " results.")
666 timestamp_begin_pt_up = 0
667
andrewonlab393531a2014-10-27 18:36:26 -0400668 f_port_up.close()
669
andrewonlab8d29f122014-10-22 17:15:04 -0400670 main.step("Obtain t1 by REST call")
671 #TODO: Implement json object parsing here
andrewonlab393531a2014-10-27 18:36:26 -0400672 json_str_1 = main.ONOS1cli.topology_events_metrics()
673 json_str_2 = main.ONOS2cli.topology_events_metrics()
674 json_str_3 = main.ONOS3cli.topology_events_metrics()
andrewonlab8d29f122014-10-22 17:15:04 -0400675
andrewonlab393531a2014-10-27 18:36:26 -0400676 json_obj_1 = json.loads(json_str_1)
677 json_obj_2 = json.loads(json_str_2)
678 json_obj_3 = json.loads(json_str_3)
andrewonlab8d29f122014-10-22 17:15:04 -0400679
andrewonlab393531a2014-10-27 18:36:26 -0400680 #Obtain graph timestamp. This timestsamp captures
681 #the epoch time at which the topology graph was updated.
682 graph_timestamp_1 = \
683 json_obj_1[graphTimestamp]['value']
684 graph_timestamp_2 = \
685 json_obj_2[graphTimestamp]['value']
686 graph_timestamp_3 = \
687 json_obj_3[graphTimestamp]['value']
688
689 #Obtain device timestamp. This timestamp captures
690 #the epoch time at which the device event happened
691 device_timestamp_1 = \
692 json_obj_1[deviceTimestamp]['value']
693 device_timestamp_2 = \
694 json_obj_2[deviceTimestamp]['value']
695 device_timestamp_3 = \
696 json_obj_3[deviceTimestamp]['value']
697
698 #Get delta between graph event and OFP
699 pt_up_graph_to_ofp_1 = int(graph_timestamp_1) -\
andrewonlab8d29f122014-10-22 17:15:04 -0400700 int(timestamp_begin_pt_up)
andrewonlab393531a2014-10-27 18:36:26 -0400701 pt_up_graph_to_ofp_2 = int(graph_timestamp_2) -\
andrewonlab8d29f122014-10-22 17:15:04 -0400702 int(timestamp_begin_pt_up)
andrewonlab393531a2014-10-27 18:36:26 -0400703 pt_up_graph_to_ofp_3 = int(graph_timestamp_3) -\
704 int(timestamp_begin_pt_up)
705
706 #Get delta between device event and OFP
707 pt_up_device_to_ofp_1 = int(device_timestamp_1) -\
708 int(timestamp_begin_pt_up)
709 pt_up_device_to_ofp_2 = int(device_timestamp_2) -\
710 int(timestamp_begin_pt_up)
711 pt_up_device_to_ofp_3 = int(device_timestamp_3) -\
andrewonlab8d29f122014-10-22 17:15:04 -0400712 int(timestamp_begin_pt_up)
andrewonlab3622beb2014-10-28 16:07:56 -0400713
714 pt_up_graph_to_ofp_avg = \
715 (float(pt_up_graph_to_ofp_1) +
716 float(pt_up_graph_to_ofp_2) +
717 float(pt_up_graph_to_ofp_3)) / 3
718
719 pt_up_device_to_ofp_avg = \
720 (float(pt_up_device_to_ofp_1) +
721 float(pt_up_device_to_ofp_2) +
722 float(pt_up_device_to_ofp_3)) / 3
723
724 if pt_up_graph_to_ofp_avg > 0 and \
725 pt_up_graph_to_ofp_avg < 1000:
726 port_up_graph_to_ofp_list.append(
727 pt_up_graph_to_ofp_avg)
728 else:
729 main.log.info("Average port up graph-to-ofp result"+
730 " exceeded the threshold: "+
731 str(pt_up_graph_to_ofp_avg))
732
733 if pt_up_device_to_ofp_avg > 0 and \
734 pt_up_device_to_ofp_avg < 1000:
735 port_up_device_to_ofp_list.append(
736 pt_up_device_to_ofp_avg)
737 else:
738 main.log.info("Average port up graph-to-ofp result"+
739 " exceeded the threshold: "+
740 str(pt_up_device_to_ofp_avg))
741
andrewonlab8d29f122014-10-22 17:15:04 -0400742 #TODO: Remove these logs. For test purposes only
andrewonlab393531a2014-10-27 18:36:26 -0400743 main.log.info("Delta1 up graph: "+str(pt_up_graph_to_ofp_1))
744 main.log.info("Delta2 up graph: "+str(pt_up_graph_to_ofp_2))
745 main.log.info("Delta3 up graph: "+str(pt_up_graph_to_ofp_3))
andrewonlab8d29f122014-10-22 17:15:04 -0400746
andrewonlab393531a2014-10-27 18:36:26 -0400747 main.log.info("Delta1 down device: "+
748 str(pt_up_device_to_ofp_1))
749 main.log.info("Delta2 down device: "+
750 str(pt_up_device_to_ofp_2))
751 main.log.info("Delta3 down device: "+
752 str(pt_up_device_to_ofp_3))
andrewonlab8d29f122014-10-22 17:15:04 -0400753
andrewonlab3622beb2014-10-28 16:07:56 -0400754 #END ITERATION FOR LOOP
755
756 port_down_graph_to_ofp_min = min(port_down_graph_to_ofp_list)
757 port_down_graph_to_ofp_max = max(port_down_graph_to_ofp_list)
758 port_down_graph_to_ofp_avg = \
759 (sum(port_down_graph_to_ofp_list) /
760 len(port_down_graph_to_ofp_list))
761
762 main.log.report("Port up graph-to-ofp Min: ")
763 main.log.report("Port up graph-to-ofp Max: ")
764 main.log.report("Port up graph-to-ofp Avg: ")
andrewonlab8d29f122014-10-22 17:15:04 -0400765
andrewonlab3622beb2014-10-28 16:07:56 -0400766 def CASE4(self, main):
767 '''
768 Link down event using loss rate 100%
769 '''
770 import time
771 import subprocess
772 import os
773 import requests
774 import json
775
776 ONOS1_ip = main.params['CTRL']['ip1']
777 ONOS2_ip = main.params['CTRL']['ip2']
778 ONOS3_ip = main.params['CTRL']['ip3']
779 ONOS_user = main.params['CTRL']['user']
780
781 default_sw_port = main.params['CTRL']['port1']
782
783 #Number of iterations of case
784 num_iter = main.params['TEST']['numIter']
785
786 #Timestamp 'keys' for json metrics output.
787 #These are subject to change, hence moved into params
788 deviceTimestamp = main.params['JSON']['deviceTimestamp']
789 linkTimestamp = main.params['JSON']['linkTimestamp']
790
791 assertion = main.TRUE
792 #Link event timestamp to system time list
793 link_down_link_to_system_list = []
794 link_up_link_to_system_list = []
795 #Graph event timestamp to system time list
796 link_down_graph_to_system_list = []
797 link_up_graph_to_system_list = []
798
799 main.log.report("Add / remove link latency between "+
800 "two switches")
801
802 main.step("Assign all switches")
803 main.Mininet1.assign_sw_controller(sw="1",
804 ip1=ONOS1_ip, port1=default_sw_port)
805 main.Mininet1.assign_sw_controller(sw="2",
806 ip1=ONOS1_ip, port1=default_sw_port)
807
808 main.step("Verifying switch assignment")
809 result_s1 = main.Mininet1.get_sw_controller(sw="s1")
810 result_s2 = main.Mininet1.get_sw_controller(sw="s2")
811
812 if result_s1 == main.TRUE and result_s2 == main.TRUE:
813 main.log.report("Switches s1, s2 assigned successfully")
814 else:
815 main.log.error("Error assigning switches s1 and s2")
816 assertion = main.FALSE
817
818 #Allow time for events to finish before taking measurements
819 time.sleep(10)
820
821 #Start iteration of link event test
822 for i in range(0, int(num_iter)):
823 main.step("Getting initial system time as t0")
andrewonlab8d29f122014-10-22 17:15:04 -0400824
andrewonlab3622beb2014-10-28 16:07:56 -0400825 timestamp_link_down_t0 = time.time() * 1000
826 #Link down is simulated by 100% loss rate using traffic
827 #control command
828 main.Mininet1.handle.sendline(
829 "sh tc qdisc add dev s1-eth1 root netem loss 100%")
830
831 #TODO: Iterate through topology count to detect
832 # link down discovery. Take timestamp and
833 # gather list for num_iter
834
andrewonlab8d29f122014-10-22 17:15:04 -0400835
836
837