blob: 46e9edfcd104b691bd125074bcec29725f649d2d [file] [log] [blame]
Jon Hall2c8959e2016-12-16 12:17:34 -08001"""
2Functions for the vpls tests
3"""
4import time
5import json
6
Jon Halled258232017-05-24 17:30:18 -07007
Jon Hall2c8959e2016-12-16 12:17:34 -08008def sanitizeConfig( config ):
9 """
10 Take a python json object for vpls config and normalize it.
11 Things it does:
12 Converts all strings to the same format
13 Make sure each network has an encapsulation key:value
14 Makes sure encapsulation type is all uppercase
15 Make sure an empty list of interfaces is formated consistently
16 Sorts the list of interfaces
Jon Hall0dccfa52017-05-18 11:21:11 -070017 Sorts the list of networks
Jon Hall2c8959e2016-12-16 12:17:34 -080018 """
19 # Convert to same string formats
20 config = json.loads( json.dumps( config ) )
21 for network in config:
22 encap = network.get( 'encapsulation', None )
23 if encap is None:
24 encap = "NONE"
25 network[ 'encapsulation' ] = encap.upper()
26 ifaces = network.get( 'interfaces' )
Jon Halled258232017-05-24 17:30:18 -070027 if ifaces == [ '' ]:
Jon Hall2c8959e2016-12-16 12:17:34 -080028 ifaces = []
29 else:
30 ifaces = sorted( ifaces )
Jon Halled258232017-05-24 17:30:18 -070031 network[ 'interfaces' ] = ifaces
32 config = sorted( config, key=lambda k: k[ 'name' ] )
Jon Hall2c8959e2016-12-16 12:17:34 -080033 return config
34
Jon Halled258232017-05-24 17:30:18 -070035
Jon Hall2c8959e2016-12-16 12:17:34 -080036def verify( main ):
37 """
38 Runs some tests to verify the vpls configurations.
39 - Compare sent vpls network configuration to what is stored in each:
40 - ONOS network configuration
41 - ONOS VPLS application configuration
42 - Ping between each pair of hosts to check connectivity
43
44 NOTE: This requires the expected/sent network config json for the vpls
45 application be stored in main.vplsConfig
46 """
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -070047
48
Jon Hall2c8959e2016-12-16 12:17:34 -080049 # Variables
Jon Halled258232017-05-24 17:30:18 -070050 app = main.params[ 'vpls' ][ 'name' ]
Jon Hall2c8959e2016-12-16 12:17:34 -080051 pprint = main.ONOSrest1.pprint
Jon Halled258232017-05-24 17:30:18 -070052 SLEEP = int( main.params[ 'SLEEP' ][ 'netcfg' ] )
Jon Hall2c8959e2016-12-16 12:17:34 -080053
54 main.step( "Check network configurations for vpls application" )
55 clusterResult = True
56 for node in main.RESTs:
57 result = False
Jeremy Ronquillo4a30ffe2017-06-07 11:36:35 -070058 getVPLS = utilities.retry( f=node.getNetCfg,
59 retValue=False,
60 kwargs={"subjectClass":"apps", "subjectKey":app},
61 sleep=SLEEP )
Jon Hall2c8959e2016-12-16 12:17:34 -080062 onosCfg = json.loads( getVPLS ).get( 'vpls' ).get( 'vplsList' )
63 onosCfg = pprint( sanitizeConfig( onosCfg ) )
64 sentCfg = pprint( sanitizeConfig( main.vplsConfig ) )
65 result = onosCfg == sentCfg
66 if result:
67 main.log.info( "ONOS NetCfg matches what was sent" )
68 else:
69 clusterResult = False
70 main.log.error( "ONOS NetCfg doesn't match what was sent" )
71 main.log.debug( "ONOS config: {}".format( onosCfg ) )
72 main.log.debug( "Sent config: {}".format( sentCfg ) )
73 utilities.assert_equals( expect=True,
74 actual=clusterResult,
75 onpass="Net Cfg added for vpls",
76 onfail="Net Cfg not added for vpls" )
77
78 main.step( "Check vpls app configurations" )
79 clusterResult = True
80 for node in main.CLIs:
81 result = False
82 #TODO Read from vpls show and match to pushed json
83 vpls = node.parseVplsShow()
84 parsedVpls = pprint( sanitizeConfig( vpls ) )
85 sentVpls = pprint( sanitizeConfig( main.vplsConfig ) )
86 result = parsedVpls == sentVpls
87 if result:
88 main.log.info( "VPLS config matches sent NetCfg" )
89 else:
90 clusterResult = False
91 main.log.error( "VPLS config doesn't match sent NetCfg" )
92 main.log.debug( "ONOS config: {}".format( parsedVpls ) )
93 main.log.debug( "Sent config: {}".format( sentVpls ) )
94 utilities.assert_equals( expect=True,
95 actual=clusterResult,
96 onpass="VPLS successfully configured",
97 onfail="VPLS not configured correctly" )
98
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -070099 checkIntentState( main )
100
Jon Hall2c8959e2016-12-16 12:17:34 -0800101 main.step( "Check connectivity" )
102 connectivityCheck = True
Jon Halled258232017-05-24 17:30:18 -0700103 hosts = int( main.params[ 'vpls' ][ 'hosts' ] )
Jon Hall2c8959e2016-12-16 12:17:34 -0800104 networks = []
105 for network in main.vplsConfig:
106 nodes = network.get( 'interfaces', None )
107 if nodes:
108 networks.append( nodes )
109 for i in range( 1, hosts + 1 ):
110 src = "h" + str( i )
111 for j in range( 1, hosts + 1 ):
112 if j == i:
113 continue
114 dst = "h" + str( j )
115 pingResult = main.Mininet1.pingHost( SRC=src, TARGET=dst )
116 expected = main.FALSE
117 for network in networks:
118 if src in network and dst in network:
119 expected = main.TRUE
120 break
121 if pingResult != expected:
122 connectivityCheck = False
123 main.log.error( "%s <-> %s: %s; Expected: %s" %
124 ( src, dst, pingResult, expected ) )
125 utilities.assert_equals( expect=True,
126 actual=connectivityCheck,
127 onpass="Connectivity is as expected",
128 onfail="Connectivity is not as expected" )
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -0700129
130
131
132# TODO: if encapsulation is set, look for that
133# TODO: can we look at the intent keys?
134
135def checkIntentState( main , bl=[] ):
136 # Print the intent states
137 intents = main.CLIs[ 0 ].intents()
138 count = 0
139 while count <= 5:
140 installedCheck = True
141 try:
142 i = 1
143 for intent in json.loads( intents ):
144 state = intent.get( 'state', None )
145 if "INSTALLED" not in state or ( "WITHDRAWN" not in state and "h" + str( i ) in bl ):
146 installedCheck = False
147 i += 1
148 except ( ValueError, TypeError ):
149 main.log.exception( "Error parsing intents" )
150 if installedCheck:
151 break
152 count += 1
153 return installedCheck
154
155
156def getVplsHashtable( main, bl=[] ):
157 """
158 Returns a hashtable of vpls to hosts
159 """
160 result = {}
161 vplsConfig = main.vplsConfig
162 for v in vplsConfig:
163 interfaces = v[ 'interfaces' ][:]
164 for i in bl:
165 if i in interfaces:
166 interfaces.remove( i )
167 result[ v[ 'name' ] ] = interfaces
168 return result
169
170
171def testConnectivityVpls( main, blacklist=[], isNodeUp=True ):
172
173 # Can't do intent check when onos node is stopped/killed yet
174 if isNodeUp:
175 main.step( "Check intent states" )
176 intentsCheck = utilities.retry( f=checkIntentState,
177 retValue=False,
178 args=( main, blacklist ),
179 sleep=main.timeSleep,
180 attempts=main.numAttempts )
181
182 utilities.assert_equals( expect=True,
183 actual=intentsCheck,
184 onpass="All Intents in installed state",
185 onfail="Not all Intents in installed state" )
186
187 main.step( "Testing connectivity..." )
188
189 vplsHashtable = getVplsHashtable( main, blacklist )
190 main.log.debug( "vplsHashtable: " + str( vplsHashtable ) )
191 result = True
192 for key in vplsHashtable:
193 pingResult = utilities.retry( f=main.Mininet1.pingallHosts,
194 retValue=False,
195 args=( vplsHashtable[ key ], ),
196 sleep=main.timeSleep,
197 attempts=main.numAttempts )
198 result = result and pingResult
199
200 utilities.assert_equals( expect=main.TRUE, actual=result,
201 onpass="Connectivity succeeded.",
202 onfail="Connectivity failed." )
203 return result
204
205
206def compareApps( main ):
207 result = True
208 first = None
209 for cli in main.CLIs:
210 currentApps = cli.apps( summary=True, active=True )
211 if not result:
212 first = currentApps
213 else:
214 result = result and ( currentApps == first )
215 return result