blob: f9ce3ff1c086c422de1e2f2a45c3809b88eb9c22 [file] [log] [blame]
Devin Lim58046fa2017-07-05 16:55:00 -07001import time
2import re
3import imp
4import json
5class Topology:
6
7 def __init__( self ):
8 self.default = ''
9 """
10 These functions can be used for topology comparisons
11 """
12 def getAllDevices( self, numNode, needRetry, kwargs={} ):
13 """
14 Return a list containing the devices output from each ONOS node
15 """
16 devices = []
17 threads = []
18 for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
19 t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].devices,
20 name="devices-" + str( i ),
21 args=[main.CLIs[ i ].devices, [ None ] ] if needRetry else [],
22 kwargs=kwargs )
23 threads.append( t )
24 t.start()
25
26 for t in threads:
27 t.join()
28 devices.append( t.result )
29 return devices
30
31 def getAllHosts( self, numNode, needRetry, kwargs={}, inJson=False ):
32 """
33 Return a list containing the hosts output from each ONOS node
34 """
35 hosts = []
36 ipResult = main.TRUE
37 threads = []
38 for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
39 t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].hosts,
40 name="hosts-" + str( i ),
41 args=[main.CLIs[ i ].hosts, [ None ] ] if needRetry else [],
42 kwargs=kwargs )
43 threads.append( t )
44 t.start()
45
46 for t in threads:
47 t.join()
48 if inJson:
49 try:
50 hosts.append( json.loads( t.result ) )
51 except ( ValueError, TypeError ):
52 main.log.exception( "Error parsing hosts results" )
53 main.log.error( repr( t.result ) )
54 hosts.append( None )
55 else:
56 hosts.append( t.result )
57 return hosts
58
59 def getAllPorts( self, numNode, needRetry, kwargs={} ):
60 """
61 Return a list containing the ports output from each ONOS node
62 """
63 ports = []
64 threads = []
65 for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
66 t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].ports,
67 name="ports-" + str( i ),
68 args=[ main.CLIs[ i ].ports, [ None ] ] if needRetry else [],
69 kwargs=kwargs )
70 threads.append( t )
71 t.start()
72
73 for t in threads:
74 t.join()
75 ports.append( t.result )
76 return ports
77
78 def getAllLinks( self, numNode, needRetry, kwargs={} ):
79 """
80 Return a list containing the links output from each ONOS node
81 """
82 links = []
83 threads = []
84 print numNode
85 for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
86 t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].links,
87 name="links-" + str( i ),
88 args=[main.CLIs[ i ].links, [ None ] ] if needRetry else [],
89 kwargs=kwargs )
90 threads.append( t )
91 t.start()
92
93 for t in threads:
94 t.join()
95 links.append( t.result )
96 print links
97 return links
98
99 def getAllClusters( self, numNode, needRetry, kwargs={} ):
100 """
101 Return a list containing the clusters output from each ONOS node
102 """
103 clusters = []
104 threads = []
105 for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
106 t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].clusters,
107 name="clusters-" + str( i ),
108 args=[main.CLIs[ i ].clusters, [ None ] ] if needRetry else [],
109 kwargs=kwargs )
110 threads.append( t )
111 t.start()
112
113 for t in threads:
114 t.join()
115 clusters.append( t.result )
116 return clusters
117
118 def compareDevicePort( self, Mininet, controller, mnSwitches, devices, ports ):
119 if devices[ controller ] and ports[ controller ] and \
120 "Error" not in devices[ controller ] and \
121 "Error" not in ports[ controller ]:
122 try:
123 currentDevicesResult = Mininet.compareSwitches(
124 mnSwitches,
125 json.loads( devices[ controller ] ),
126 json.loads( ports[ controller ] ) )
127 except(TypeError, ValueError):
128 main.log.error(
129 "Could not load json: {0} or {1}".format( str( devices[ controller ] )
130 , str( ports[ controller ] ) ) )
131 currentDevicesResult = main.FALSE
132 else:
133 currentDevicesResult = main.FALSE
134 return currentDevicesResult
135
136 def compareBase( self, compareElem, controller, compareF, compareArg ):
137 if compareElem[ controller ] and "Error" not in compareElem[ controller ]:
138 try:
139 if isinstance( compareArg, list ):
140 compareArg.append( json.loads( compareElem[ controller ] ) )
141 else:
142 compareArg = [compareArg, json.loads( compareElem[ controller ] ) ]
143
144 currentCompareResult = compareF( *compareArg )
145 except(TypeError, ValueError):
146 main.log.error(
147 "Could not load json: {0} or {1}".format( str( compareElem[ controller ] ) ) )
148 currentCompareResult = main.FALSE
149 else:
150 currentCompareResult = main.FALSE
151
152 return currentCompareResult
153
154 def compareTopos( self, Mininet, attempts=1 ):
155
156 main.case( "Compare ONOS Topology view to Mininet topology" )
157 main.caseExplanation = "Compare topology elements between Mininet" +\
158 " and ONOS"
159 main.log.info( "Gathering topology information from Mininet" )
160 devicesResults = main.FALSE # Overall Boolean for device correctness
161 linksResults = main.FALSE # Overall Boolean for link correctness
162 hostsResults = main.FALSE # Overall Boolean for host correctness
163 deviceFails = [] # Nodes where devices are incorrect
164 linkFails = [] # Nodes where links are incorrect
165 hostFails = [] # Nodes where hosts are incorrect
166
167 mnSwitches = Mininet.getSwitches()
168 mnLinks = Mininet.getLinks()
169 mnHosts = Mininet.getHosts()
170
171 main.step( "Comparing Mininet topology to ONOS topology" )
172
173 while ( attempts >= 0 ) and\
174 ( not devicesResults or not linksResults or not hostsResults ):
175 main.log.info( "Sleeping {} seconds".format( 2 ) )
176 time.sleep( 2 )
177 if not devicesResults:
178 devices = self.getAllDevices( main.numCtrls, False )
179 ports = self.getAllPorts( main.numCtrls, False )
180 devicesResults = main.TRUE
181 deviceFails = [] # Reset for each failed attempt
182 if not linksResults:
183 links = self.getAllLinks( main.numCtrls, False )
184 linksResults = main.TRUE
185 linkFails = [] # Reset for each failed attempt
186 if not hostsResults:
187 hosts = self.getAllHosts( main.numCtrls, False )
188 hostsResults = main.TRUE
189 hostFails = [] # Reset for each failed attempt
190
191 # Check for matching topology on each node
192 for controller in range( main.numCtrls ):
193 controllerStr = str( controller + 1 ) # ONOS node number
194 # Compare Devices
195 currentDevicesResult = self.compareDevicePort( Mininet, controller,
196 mnSwitches,
197 devices, ports )
198 if not currentDevicesResult:
199 deviceFails.append( controllerStr )
200 devicesResults = devicesResults and currentDevicesResult
201 # Compare Links
202 currentLinksResult = self.compareBase( links, controller,
203 Mininet.compareLinks,
204 [ mnSwitches, mnLinks ] )
205 if not currentLinksResult:
206 linkFails.append( controllerStr )
207 linksResults = linksResults and currentLinksResult
208 # Compare Hosts
209 currentHostsResult = self.compareBase( hosts, controller,
210 Mininet.compareHosts,
211 mnHosts )
212 if not currentHostsResult:
213 hostFails.append( controllerStr )
214 hostsResults = hostsResults and currentHostsResult
215 # Decrement Attempts Remaining
216 attempts -= 1
217
218 utilities.assert_equals( expect=[],
219 actual=deviceFails,
220 onpass="ONOS correctly discovered all devices",
221 onfail="ONOS incorrectly discovered devices on nodes: " +
222 str( deviceFails ) )
223 utilities.assert_equals( expect=[],
224 actual=linkFails,
225 onpass="ONOS correctly discovered all links",
226 onfail="ONOS incorrectly discovered links on nodes: " +
227 str( linkFails ) )
228 utilities.assert_equals( expect=[],
229 actual=hostFails,
230 onpass="ONOS correctly discovered all hosts",
231 onfail="ONOS incorrectly discovered hosts on nodes: " +
232 str( hostFails ) )
233 topoResults = hostsResults and linksResults and devicesResults
234 utilities.assert_equals( expect=main.TRUE,
235 actual=topoResults,
236 onpass="ONOS correctly discovered the topology",
237 onfail="ONOS incorrectly discovered the topology" )