blob: 34fffbbf82e178bea365ca5a402c618214c73526 [file] [log] [blame]
Jon Hall2c8959e2016-12-16 12:17:34 -08001"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07002Copyright 2016 Open Networking Foundation (ONF)
3
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
11 (at your option) any later version.
12
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"""
21
22"""
Jon Hall2c8959e2016-12-16 12:17:34 -080023Functions for the vpls tests
24"""
25import time
26import json
27
Jon Halled258232017-05-24 17:30:18 -070028
Jon Hall2c8959e2016-12-16 12:17:34 -080029def sanitizeConfig( config ):
30 """
31 Take a python json object for vpls config and normalize it.
32 Things it does:
33 Converts all strings to the same format
34 Make sure each network has an encapsulation key:value
35 Makes sure encapsulation type is all uppercase
36 Make sure an empty list of interfaces is formated consistently
37 Sorts the list of interfaces
Jon Hall0dccfa52017-05-18 11:21:11 -070038 Sorts the list of networks
Jon Hall2c8959e2016-12-16 12:17:34 -080039 """
40 # Convert to same string formats
41 config = json.loads( json.dumps( config ) )
42 for network in config:
43 encap = network.get( 'encapsulation', None )
44 if encap is None:
45 encap = "NONE"
46 network[ 'encapsulation' ] = encap.upper()
47 ifaces = network.get( 'interfaces' )
Jon Halled258232017-05-24 17:30:18 -070048 if ifaces == [ '' ]:
Jon Hall2c8959e2016-12-16 12:17:34 -080049 ifaces = []
50 else:
51 ifaces = sorted( ifaces )
Jon Halled258232017-05-24 17:30:18 -070052 network[ 'interfaces' ] = ifaces
53 config = sorted( config, key=lambda k: k[ 'name' ] )
Jon Hall2c8959e2016-12-16 12:17:34 -080054 return config
55
Jon Halled258232017-05-24 17:30:18 -070056
Jon Hall2c8959e2016-12-16 12:17:34 -080057def verify( main ):
58 """
59 Runs some tests to verify the vpls configurations.
60 - Compare sent vpls network configuration to what is stored in each:
61 - ONOS network configuration
62 - ONOS VPLS application configuration
63 - Ping between each pair of hosts to check connectivity
64
65 NOTE: This requires the expected/sent network config json for the vpls
66 application be stored in main.vplsConfig
67 """
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -070068
69
Jon Hall2c8959e2016-12-16 12:17:34 -080070 # Variables
Jon Halled258232017-05-24 17:30:18 -070071 app = main.params[ 'vpls' ][ 'name' ]
Jon Hall2c8959e2016-12-16 12:17:34 -080072 pprint = main.ONOSrest1.pprint
Jon Halled258232017-05-24 17:30:18 -070073 SLEEP = int( main.params[ 'SLEEP' ][ 'netcfg' ] )
Jon Hall2c8959e2016-12-16 12:17:34 -080074
75 main.step( "Check network configurations for vpls application" )
76 clusterResult = True
77 for node in main.RESTs:
78 result = False
Jeremy Ronquillo4a30ffe2017-06-07 11:36:35 -070079 getVPLS = utilities.retry( f=node.getNetCfg,
80 retValue=False,
81 kwargs={"subjectClass":"apps", "subjectKey":app},
82 sleep=SLEEP )
Jon Hall2c8959e2016-12-16 12:17:34 -080083 onosCfg = json.loads( getVPLS ).get( 'vpls' ).get( 'vplsList' )
84 onosCfg = pprint( sanitizeConfig( onosCfg ) )
85 sentCfg = pprint( sanitizeConfig( main.vplsConfig ) )
86 result = onosCfg == sentCfg
87 if result:
88 main.log.info( "ONOS NetCfg matches what was sent" )
89 else:
90 clusterResult = False
91 main.log.error( "ONOS NetCfg doesn't match what was sent" )
92 main.log.debug( "ONOS config: {}".format( onosCfg ) )
93 main.log.debug( "Sent config: {}".format( sentCfg ) )
94 utilities.assert_equals( expect=True,
95 actual=clusterResult,
96 onpass="Net Cfg added for vpls",
97 onfail="Net Cfg not added for vpls" )
98
99 main.step( "Check vpls app configurations" )
100 clusterResult = True
101 for node in main.CLIs:
102 result = False
103 #TODO Read from vpls show and match to pushed json
104 vpls = node.parseVplsShow()
105 parsedVpls = pprint( sanitizeConfig( vpls ) )
106 sentVpls = pprint( sanitizeConfig( main.vplsConfig ) )
107 result = parsedVpls == sentVpls
108 if result:
109 main.log.info( "VPLS config matches sent NetCfg" )
110 else:
111 clusterResult = False
112 main.log.error( "VPLS config doesn't match sent NetCfg" )
113 main.log.debug( "ONOS config: {}".format( parsedVpls ) )
114 main.log.debug( "Sent config: {}".format( sentVpls ) )
115 utilities.assert_equals( expect=True,
116 actual=clusterResult,
117 onpass="VPLS successfully configured",
118 onfail="VPLS not configured correctly" )
119
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -0700120 checkIntentState( main )
121
Jon Hall2c8959e2016-12-16 12:17:34 -0800122 main.step( "Check connectivity" )
123 connectivityCheck = True
Jon Halled258232017-05-24 17:30:18 -0700124 hosts = int( main.params[ 'vpls' ][ 'hosts' ] )
Jon Hall2c8959e2016-12-16 12:17:34 -0800125 networks = []
126 for network in main.vplsConfig:
127 nodes = network.get( 'interfaces', None )
128 if nodes:
129 networks.append( nodes )
130 for i in range( 1, hosts + 1 ):
131 src = "h" + str( i )
132 for j in range( 1, hosts + 1 ):
133 if j == i:
134 continue
135 dst = "h" + str( j )
136 pingResult = main.Mininet1.pingHost( SRC=src, TARGET=dst )
137 expected = main.FALSE
138 for network in networks:
139 if src in network and dst in network:
140 expected = main.TRUE
141 break
142 if pingResult != expected:
143 connectivityCheck = False
144 main.log.error( "%s <-> %s: %s; Expected: %s" %
145 ( src, dst, pingResult, expected ) )
146 utilities.assert_equals( expect=True,
147 actual=connectivityCheck,
148 onpass="Connectivity is as expected",
149 onfail="Connectivity is not as expected" )
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -0700150
151
152
153# TODO: if encapsulation is set, look for that
154# TODO: can we look at the intent keys?
155
156def checkIntentState( main , bl=[] ):
157 # Print the intent states
158 intents = main.CLIs[ 0 ].intents()
159 count = 0
160 while count <= 5:
161 installedCheck = True
162 try:
163 i = 1
164 for intent in json.loads( intents ):
165 state = intent.get( 'state', None )
166 if "INSTALLED" not in state or ( "WITHDRAWN" not in state and "h" + str( i ) in bl ):
167 installedCheck = False
168 i += 1
169 except ( ValueError, TypeError ):
170 main.log.exception( "Error parsing intents" )
171 if installedCheck:
172 break
173 count += 1
174 return installedCheck
175
176
177def getVplsHashtable( main, bl=[] ):
178 """
179 Returns a hashtable of vpls to hosts
180 """
181 result = {}
182 vplsConfig = main.vplsConfig
183 for v in vplsConfig:
184 interfaces = v[ 'interfaces' ][:]
185 for i in bl:
186 if i in interfaces:
187 interfaces.remove( i )
188 result[ v[ 'name' ] ] = interfaces
189 return result
190
191
192def testConnectivityVpls( main, blacklist=[], isNodeUp=True ):
193
194 # Can't do intent check when onos node is stopped/killed yet
195 if isNodeUp:
196 main.step( "Check intent states" )
197 intentsCheck = utilities.retry( f=checkIntentState,
198 retValue=False,
199 args=( main, blacklist ),
200 sleep=main.timeSleep,
201 attempts=main.numAttempts )
202
203 utilities.assert_equals( expect=True,
204 actual=intentsCheck,
205 onpass="All Intents in installed state",
206 onfail="Not all Intents in installed state" )
207
208 main.step( "Testing connectivity..." )
209
210 vplsHashtable = getVplsHashtable( main, blacklist )
211 main.log.debug( "vplsHashtable: " + str( vplsHashtable ) )
212 result = True
213 for key in vplsHashtable:
214 pingResult = utilities.retry( f=main.Mininet1.pingallHosts,
215 retValue=False,
216 args=( vplsHashtable[ key ], ),
217 sleep=main.timeSleep,
218 attempts=main.numAttempts )
219 result = result and pingResult
220
221 utilities.assert_equals( expect=main.TRUE, actual=result,
222 onpass="Connectivity succeeded.",
223 onfail="Connectivity failed." )
224 return result
225
226
227def compareApps( main ):
228 result = True
229 first = None
230 for cli in main.CLIs:
231 currentApps = cli.apps( summary=True, active=True )
232 if not result:
233 first = currentApps
234 else:
235 result = result and ( currentApps == first )
236 return result