blob: 50fb721ef0bd9e9ca5d015df484071239e9c81f6 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
Jon Hallb3ed8ed2015-10-28 16:43:55 -070012CASE61: The Failure inducing case.
13CASE62: The Failure recovery case.
Jon Hall5cf14d52015-07-16 12:15:19 -070014CASE7: Check state after control plane failure
15CASE8: Compare topo
16CASE9: Link s3-s28 down
17CASE10: Link s3-s28 up
18CASE11: Switch down
19CASE12: Switch up
20CASE13: Clean up
21CASE14: start election app on all onos nodes
22CASE15: Check that Leadership Election is still functional
23CASE16: Install Distributed Primitives app
24CASE17: Check for basic functionality with distributed primitives
25"""
Jon Hallb3ed8ed2015-10-28 16:43:55 -070026class HAstopNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -070027
28 def __init__( self ):
29 self.default = ''
30
31 def CASE1( self, main ):
32 """
33 CASE1 is to compile ONOS and push it to the test machines
34
35 Startup sequence:
36 cell <name>
37 onos-verify-cell
38 NOTE: temporary - onos-remove-raft-logs
39 onos-uninstall
40 start mininet
41 git pull
42 mvn clean install
43 onos-package
44 onos-install -f
45 onos-wait-for-start
46 start cli sessions
47 start tcpdump
48 """
Jon Halle1a3b752015-07-22 13:02:46 -070049 import imp
Jon Hall3b489db2015-10-05 14:38:37 -070050 import pexpect
Jon Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Halla440e872016-03-31 15:15:50 -070052 import json
Jon Hallb3ed8ed2015-10-28 16:43:55 -070053 main.log.info( "ONOS HA test: Stop a minority of ONOS nodes - " +
Jon Hall5cf14d52015-07-16 12:15:19 -070054 "initialization" )
Jon Halle1a3b752015-07-22 13:02:46 -070055 # set global variables
Jon Halla440e872016-03-31 15:15:50 -070056 # These are for csv plotting in jenkins
Devin Lim58046fa2017-07-05 16:55:00 -070057 main.HAlabels = []
58 main.HAdata = []
59 try:
60 from tests.dependencies.ONOSSetup import ONOSSetup
61 main.testSetUp = ONOSSetup()
62 except ImportError:
63 main.log.error( "ONOSSetup not found. exiting the test" )
64 main.exit()
65 main.testSetUp.envSetupDescription()
Jon Halle1a3b752015-07-22 13:02:46 -070066 try:
Jon Hall53c5e662016-04-13 16:06:56 -070067 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070068 main.HA = HA()
Devin Lim58046fa2017-07-05 16:55:00 -070069 # load some variables from the params file
70 cellName = main.params[ 'ENV' ][ 'cellName' ]
71 main.apps = main.params[ 'ENV' ][ 'appString' ]
72 main.numCtrls = int( main.params[ 'num_controllers' ] )
73 if main.ONOSbench.maxNodes and\
74 main.ONOSbench.maxNodes < main.numCtrls:
75 main.numCtrls = int( main.ONOSbench.maxNodes )
76 main.maxNodes = main.numCtrls
77 stepResult = main.testSetUp.envSetup( hasNode=True )
Jon Halle1a3b752015-07-22 13:02:46 -070078 except Exception as e:
Devin Lim58046fa2017-07-05 16:55:00 -070079 main.testSetUp.envSetupException( e )
80 main.testSetUp.evnSetupConclusion( stepResult )
81 main.HA.generateGraph( "HAstopNodes" )
Jon Halle1a3b752015-07-22 13:02:46 -070082
Devin Lim58046fa2017-07-05 16:55:00 -070083 main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
84 extraApply=main.HA.customizeOnosGenPartitions,
85 extraClean=main.HA.cleanUpGenPartition )
Jon Hall5cf14d52015-07-16 12:15:19 -070086
Devin Lim58046fa2017-07-05 16:55:00 -070087 main.HA.initialSetUp()
Jon Hall9d2dcad2016-04-08 10:15:20 -070088
Jon Hall5cf14d52015-07-16 12:15:19 -070089 def CASE2( self, main ):
90 """
91 Assign devices to controllers
92 """
Devin Lim58046fa2017-07-05 16:55:00 -070093 main.HA.assignDevices( main )
Jon Hall5cf14d52015-07-16 12:15:19 -070094
95 def CASE21( self, main ):
96 """
97 Assign mastership to controllers
98 """
Devin Lim58046fa2017-07-05 16:55:00 -070099 main.HA.assignMastership( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700100
Jon Hall5cf14d52015-07-16 12:15:19 -0700101
102 def CASE3( self, main ):
103 """
104 Assign intents
105 """
Devin Lim58046fa2017-07-05 16:55:00 -0700106 main.HA.assignIntents( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700107
Jon Hall5cf14d52015-07-16 12:15:19 -0700108
Jon Hall5cf14d52015-07-16 12:15:19 -0700109
110 def CASE4( self, main ):
111 """
112 Ping across added host intents
113 """
Devin Lim58046fa2017-07-05 16:55:00 -0700114 main.HA.pingAcrossHostIntent( main, True, False )
Jon Hall5cf14d52015-07-16 12:15:19 -0700115
116 def CASE5( self, main ):
117 """
118 Reading state of ONOS
119 """
Devin Lim58046fa2017-07-05 16:55:00 -0700120 main.HA.readingState( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700121
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700122 def CASE61( self, main ):
Jon Hall5cf14d52015-07-16 12:15:19 -0700123 """
124 The Failure case.
125 """
Jon Halle1a3b752015-07-22 13:02:46 -0700126 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700127 assert main, "main not defined"
128 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700129 assert main.CLIs, "main.CLIs not defined"
130 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700131 main.case( "Stop minority of ONOS nodes" )
Jon Hall96091e62015-09-21 17:34:17 -0700132
133 main.step( "Checking ONOS Logs for errors" )
134 for node in main.nodes:
135 main.log.debug( "Checking logs for errors on " + node.name + ":" )
136 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
137
Jon Hall3b489db2015-10-05 14:38:37 -0700138 n = len( main.nodes ) # Number of nodes
139 p = ( ( n + 1 ) / 2 ) + 1 # Number of partitions
140 main.kill = [ 0 ] # ONOS node to kill, listed by index in main.nodes
141 if n > 3:
142 main.kill.append( p - 1 )
143 # NOTE: This only works for cluster sizes of 3,5, or 7.
144
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700145 main.step( "Stopping " + str( len( main.kill ) ) + " ONOS nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -0700146 killResults = main.TRUE
147 for i in main.kill:
148 killResults = killResults and\
Jon Hallf37d44d2017-05-24 10:37:30 -0700149 main.ONOSbench.onosStop( main.nodes[ i ].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700150 main.activeNodes.remove( i )
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 utilities.assert_equals( expect=main.TRUE, actual=killResults,
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700152 onpass="ONOS nodes stopped successfully",
153 onfail="ONOS nodes NOT successfully stopped" )
154
Jon Halld2871c22016-07-26 11:01:14 -0700155 main.step( "Checking ONOS nodes" )
156 nodeResults = utilities.retry( main.HA.nodesCheck,
157 False,
Jon Hallf37d44d2017-05-24 10:37:30 -0700158 args=[ main.activeNodes ],
Jon Halld2871c22016-07-26 11:01:14 -0700159 sleep=15,
160 attempts=5 )
161
162 utilities.assert_equals( expect=True, actual=nodeResults,
163 onpass="Nodes check successful",
164 onfail="Nodes check NOT successful" )
165
166 if not nodeResults:
167 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700168 cli = main.CLIs[ i ]
Jon Halld2871c22016-07-26 11:01:14 -0700169 main.log.debug( "{} components not ACTIVE: \n{}".format(
170 cli.name,
171 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
172 main.log.error( "Failed to start ONOS, stopping test" )
173 main.cleanup()
174 main.exit()
175
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700176 def CASE62( self, main ):
177 """
178 The bring up stopped nodes
179 """
Devin Lim58046fa2017-07-05 16:55:00 -0700180 main.HA.bringUpStoppedNode( main )
Jon Halla440e872016-03-31 15:15:50 -0700181
Jon Hall5cf14d52015-07-16 12:15:19 -0700182 def CASE7( self, main ):
183 """
184 Check state after ONOS failure
185 """
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700186 try:
187 main.kill
188 except AttributeError:
189 main.kill = []
190
Jon Hall5cf14d52015-07-16 12:15:19 -0700191
Devin Lim58046fa2017-07-05 16:55:00 -0700192 main.HA.checkStateAfterONOS( main, afterWhich=0 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700193
Jon Hall5cf14d52015-07-16 12:15:19 -0700194 main.step( "Leadership Election is still functional" )
195 # Test of LeadershipElection
196 leaderList = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700197
Jon Hall3b489db2015-10-05 14:38:37 -0700198 restarted = []
199 for i in main.kill:
Jon Hallf37d44d2017-05-24 10:37:30 -0700200 restarted.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700201 leaderResult = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700202
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700203 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700204 cli = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700205 leaderN = cli.electionTestLeader()
206 leaderList.append( leaderN )
207 if leaderN == main.FALSE:
208 # error in response
209 main.log.error( "Something is wrong with " +
210 "electionTestLeader function, check the" +
211 " error logs" )
212 leaderResult = main.FALSE
213 elif leaderN is None:
214 main.log.error( cli.name +
215 " shows no leader for the election-app was" +
216 " elected after the old one died" )
217 leaderResult = main.FALSE
218 elif leaderN in restarted:
219 main.log.error( cli.name + " shows " + str( leaderN ) +
220 " as leader for the election-app, but it " +
221 "was restarted" )
222 leaderResult = main.FALSE
223 if len( set( leaderList ) ) != 1:
224 leaderResult = main.FALSE
225 main.log.error(
226 "Inconsistent view of leader for the election test app" )
227 # TODO: print the list
228 utilities.assert_equals(
229 expect=main.TRUE,
230 actual=leaderResult,
231 onpass="Leadership election passed",
232 onfail="Something went wrong with Leadership election" )
233
234 def CASE8( self, main ):
235 """
236 Compare topo
237 """
Devin Lim58046fa2017-07-05 16:55:00 -0700238 main.HA.compareTopo( main )
Jon Halld2871c22016-07-26 11:01:14 -0700239
Jon Hall5cf14d52015-07-16 12:15:19 -0700240 def CASE9( self, main ):
241 """
242 Link s3-s28 down
243 """
Devin Lim58046fa2017-07-05 16:55:00 -0700244 main.HA.linkDown( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700245
246 def CASE10( self, main ):
247 """
248 Link s3-s28 up
249 """
Devin Lim58046fa2017-07-05 16:55:00 -0700250 main.HA.linkUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700251
252 def CASE11( self, main ):
253 """
254 Switch Down
255 """
256 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700257 main.HA.switchDown( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700258
259 def CASE12( self, main ):
260 """
261 Switch Up
262 """
263 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700264 main.HA.switchUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700265
266 def CASE13( self, main ):
267 """
268 Clean up
269 """
Devin Lim58046fa2017-07-05 16:55:00 -0700270 main.HAlabels.append( "Restart" )
271 main.HAdata.append( str( main.restartTime ) )
272 main.HA.cleanUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700273
274 def CASE14( self, main ):
275 """
276 start election app on all onos nodes
277 """
Devin Lim58046fa2017-07-05 16:55:00 -0700278 main.HA.startElectionApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700279
280 def CASE15( self, main ):
281 """
282 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -0700283 15.1 Run election on each node
284 15.2 Check that each node has the same leaders and candidates
285 15.3 Find current leader and withdraw
286 15.4 Check that a new node was elected leader
287 15.5 Check that that new leader was the candidate of old leader
288 15.6 Run for election on old leader
289 15.7 Check that oldLeader is a candidate, and leader if only 1 node
290 15.8 Make sure that the old leader was added to the candidate list
291
292 old and new variable prefixes refer to data from before vs after
293 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -0700294 """
Devin Lim58046fa2017-07-05 16:55:00 -0700295 main.HA.isElectionFunctional( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700296
297 def CASE16( self, main ):
298 """
299 Install Distributed Primitives app
300 """
Devin Lim58046fa2017-07-05 16:55:00 -0700301 main.HA.installDistributedPrimitiveApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700302
303 def CASE17( self, main ):
304 """
305 Check for basic functionality with distributed primitives
306 """
Devin Lim58046fa2017-07-05 16:55:00 -0700307 main.HA.checkDistPrimitivesFunc( main )