blob: 04e6246aeea9348f5d82b2adb0869d2cf3734591 [file] [log] [blame]
Devin Lim142b5342017-07-20 15:22:39 -07001"""
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002Copyright 2016 Open Networking Foundation ( ONF )
Devin Lim142b5342017-07-20 15:22:39 -07003
4Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
5the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
6or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070011 ( at your option ) any later version.
Devin Lim142b5342017-07-20 15:22:39 -070012
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20"""
Devin Lim58046fa2017-07-05 16:55:00 -070021import time
22import re
23import imp
24import json
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070025
26
Devin Lim58046fa2017-07-05 16:55:00 -070027class Topology:
28
29 def __init__( self ):
30 self.default = ''
Devin Lim142b5342017-07-20 15:22:39 -070031
Devin Lim58046fa2017-07-05 16:55:00 -070032 """
33 These functions can be used for topology comparisons
34 """
Devin Lim142b5342017-07-20 15:22:39 -070035 def getAll( self, function, needRetry=False, kwargs={}, inJson=False ):
Devin Lim58046fa2017-07-05 16:55:00 -070036 """
Devin Lim142b5342017-07-20 15:22:39 -070037 Description:
38 get all devices/links/hosts/ports of the onosCli
39 Required:
40 * function - name of the function
41 * needRetry - it will retry if this is true.
42 * kwargs - kwargs of the function
43 * inJson - True if want it in Json form
44 Returns:
45 Returns the list of the result.
Devin Lim58046fa2017-07-05 16:55:00 -070046 """
Devin Lim142b5342017-07-20 15:22:39 -070047 returnList = []
Devin Lim58046fa2017-07-05 16:55:00 -070048 threads = []
Jon Hallca319892017-06-15 15:25:22 -070049 for ctrl in main.Cluster.active():
Devin Lim142b5342017-07-20 15:22:39 -070050 func = getattr( ctrl.CLI, function )
51 t = main.Thread( target=utilities.retry if needRetry else func,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070052 name=function + "-" + str( ctrl ),
Devin Lim142b5342017-07-20 15:22:39 -070053 args=[ func, [ None ] ] if needRetry else [],
Devin Lim58046fa2017-07-05 16:55:00 -070054 kwargs=kwargs )
55 threads.append( t )
56 t.start()
57
58 for t in threads:
59 t.join()
60 if inJson:
61 try:
Devin Lim142b5342017-07-20 15:22:39 -070062 returnList.append( json.loads( t.result ) )
Devin Lim58046fa2017-07-05 16:55:00 -070063 except ( ValueError, TypeError ):
64 main.log.exception( "Error parsing hosts results" )
65 main.log.error( repr( t.result ) )
Devin Lim142b5342017-07-20 15:22:39 -070066 returnList.append( None )
Devin Lim58046fa2017-07-05 16:55:00 -070067 else:
Devin Lim142b5342017-07-20 15:22:39 -070068 returnList.append( t.result )
69 return returnList
Devin Lim58046fa2017-07-05 16:55:00 -070070
71 def compareDevicePort( self, Mininet, controller, mnSwitches, devices, ports ):
Devin Lim142b5342017-07-20 15:22:39 -070072 """
73 Description:
74 compares the devices and port of the onos to the mininet.
75 Required:
76 * Mininet - mininet driver to use
77 * controller - controller position of the devices
78 * mnSwitches - switches of mininet
79 * devices - devices of the onos
80 * ports - ports of the onos
81 Returns:
82 Returns main.TRUE if the results are matching else
83 Returns main.FALSE
84 """
Devin Lim58046fa2017-07-05 16:55:00 -070085 if devices[ controller ] and ports[ controller ] and \
86 "Error" not in devices[ controller ] and \
87 "Error" not in ports[ controller ]:
88 try:
89 currentDevicesResult = Mininet.compareSwitches(
90 mnSwitches,
91 json.loads( devices[ controller ] ),
92 json.loads( ports[ controller ] ) )
Jon Hallca319892017-06-15 15:25:22 -070093 except ( TypeError, ValueError ):
Devin Lim58046fa2017-07-05 16:55:00 -070094 main.log.error(
Jon Hallca319892017-06-15 15:25:22 -070095 "Could not load json: {0} or {1}".format( str( devices[ controller ] ),
96 str( ports[ controller ] ) ) )
Devin Lim58046fa2017-07-05 16:55:00 -070097 currentDevicesResult = main.FALSE
98 else:
99 currentDevicesResult = main.FALSE
100 return currentDevicesResult
101
102 def compareBase( self, compareElem, controller, compareF, compareArg ):
Devin Lim142b5342017-07-20 15:22:39 -0700103 """
104 Description:
105 compares the links/hosts of the onos to the mininet.
106 Required:
107 * compareElem - list of links/hosts of the onos
108 * controller - controller position of the devices
109 * compareF - function of the mininet that will compare the
110 results
111 * compareArg - arg of the compareF.
112 Returns:
113 Returns main.TRUE if the results are matching else
114 Returns main.FALSE
115 """
Devin Lim58046fa2017-07-05 16:55:00 -0700116 if compareElem[ controller ] and "Error" not in compareElem[ controller ]:
117 try:
118 if isinstance( compareArg, list ):
119 compareArg.append( json.loads( compareElem[ controller ] ) )
120 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700121 compareArg = [ compareArg, json.loads( compareElem[ controller ] ) ]
Devin Lim58046fa2017-07-05 16:55:00 -0700122
123 currentCompareResult = compareF( *compareArg )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700124 except( TypeError, ValueError ):
Devin Lim58046fa2017-07-05 16:55:00 -0700125 main.log.error(
126 "Could not load json: {0} or {1}".format( str( compareElem[ controller ] ) ) )
127 currentCompareResult = main.FALSE
128 else:
129 currentCompareResult = main.FALSE
130
131 return currentCompareResult
132
Devin Lim0c972b72018-02-08 14:53:59 -0800133 def compareTopos( self, Mininet, attempts=1, includeCaseDesc=True ):
Devin Lim142b5342017-07-20 15:22:39 -0700134 """
135 Description:
136 compares the links and hosts and switches of the onos to the mininet.
137 Required:
138 * Mininet - Mininet driver to use.
139 * attempts - number of attempts to compare in case
140 the result is different after a certain time.
141 Returns:
142 Returns main.TRUE if the results are matching else
143 Returns main.FALSE
144 """
Devin Lim0c972b72018-02-08 14:53:59 -0800145 if includeCaseDesc:
146 main.case( "Compare ONOS Topology view to Mininet topology" )
147 main.caseExplanation = "Compare topology elements between Mininet" +\
148 " and ONOS"
Devin Lim58046fa2017-07-05 16:55:00 -0700149 main.log.info( "Gathering topology information from Mininet" )
150 devicesResults = main.FALSE # Overall Boolean for device correctness
151 linksResults = main.FALSE # Overall Boolean for link correctness
152 hostsResults = main.FALSE # Overall Boolean for host correctness
153 deviceFails = [] # Nodes where devices are incorrect
154 linkFails = [] # Nodes where links are incorrect
155 hostFails = [] # Nodes where hosts are incorrect
156
157 mnSwitches = Mininet.getSwitches()
158 mnLinks = Mininet.getLinks()
159 mnHosts = Mininet.getHosts()
160
161 main.step( "Comparing Mininet topology to ONOS topology" )
162
163 while ( attempts >= 0 ) and\
164 ( not devicesResults or not linksResults or not hostsResults ):
165 main.log.info( "Sleeping {} seconds".format( 2 ) )
166 time.sleep( 2 )
167 if not devicesResults:
Devin Lim142b5342017-07-20 15:22:39 -0700168 devices = self.getAll( "devices", False )
169 ports = self.getAll( "ports", False )
Devin Lim58046fa2017-07-05 16:55:00 -0700170 devicesResults = main.TRUE
171 deviceFails = [] # Reset for each failed attempt
172 if not linksResults:
Devin Lim142b5342017-07-20 15:22:39 -0700173 links = self.getAll( "links", False )
Devin Lim58046fa2017-07-05 16:55:00 -0700174 linksResults = main.TRUE
175 linkFails = [] # Reset for each failed attempt
176 if not hostsResults:
Devin Lim142b5342017-07-20 15:22:39 -0700177 hosts = self.getAll( "hosts", False )
Devin Lim58046fa2017-07-05 16:55:00 -0700178 hostsResults = main.TRUE
179 hostFails = [] # Reset for each failed attempt
180
181 # Check for matching topology on each node
Devin Lim142b5342017-07-20 15:22:39 -0700182 for controller in main.Cluster.getRunningPos():
Devin Lim58046fa2017-07-05 16:55:00 -0700183 controllerStr = str( controller + 1 ) # ONOS node number
184 # Compare Devices
185 currentDevicesResult = self.compareDevicePort( Mininet, controller,
Jon Hallca319892017-06-15 15:25:22 -0700186 mnSwitches,
187 devices, ports )
Devin Lim58046fa2017-07-05 16:55:00 -0700188 if not currentDevicesResult:
189 deviceFails.append( controllerStr )
190 devicesResults = devicesResults and currentDevicesResult
191 # Compare Links
192 currentLinksResult = self.compareBase( links, controller,
Jon Hallca319892017-06-15 15:25:22 -0700193 Mininet.compareLinks,
194 [ mnSwitches, mnLinks ] )
Devin Lim58046fa2017-07-05 16:55:00 -0700195 if not currentLinksResult:
196 linkFails.append( controllerStr )
197 linksResults = linksResults and currentLinksResult
198 # Compare Hosts
199 currentHostsResult = self.compareBase( hosts, controller,
200 Mininet.compareHosts,
201 mnHosts )
202 if not currentHostsResult:
203 hostFails.append( controllerStr )
204 hostsResults = hostsResults and currentHostsResult
205 # Decrement Attempts Remaining
206 attempts -= 1
207
208 utilities.assert_equals( expect=[],
209 actual=deviceFails,
210 onpass="ONOS correctly discovered all devices",
211 onfail="ONOS incorrectly discovered devices on nodes: " +
212 str( deviceFails ) )
213 utilities.assert_equals( expect=[],
214 actual=linkFails,
215 onpass="ONOS correctly discovered all links",
216 onfail="ONOS incorrectly discovered links on nodes: " +
217 str( linkFails ) )
218 utilities.assert_equals( expect=[],
219 actual=hostFails,
220 onpass="ONOS correctly discovered all hosts",
221 onfail="ONOS incorrectly discovered hosts on nodes: " +
222 str( hostFails ) )
223 topoResults = hostsResults and linksResults and devicesResults
224 utilities.assert_equals( expect=main.TRUE,
225 actual=topoResults,
226 onpass="ONOS correctly discovered the topology",
227 onfail="ONOS incorrectly discovered the topology" )
Devin Lim142b5342017-07-20 15:22:39 -0700228 return topoResults