blob: e1a66a3f1bc6cfec736e3fc4f2894a6758beafbc [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07002Copyright 2015 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 Hall5cf14d52015-07-16 12:15:19 -070023Description: This test is to determine if ONOS can handle
24 a minority of it's nodes restarting
25
26List of test cases:
27CASE1: Compile ONOS and push it to the test machines
28CASE2: Assign devices to controllers
29CASE21: Assign mastership to controllers
30CASE3: Assign intents
31CASE4: Ping across added host intents
32CASE5: Reading state of ONOS
Jon Hallb3ed8ed2015-10-28 16:43:55 -070033CASE61: The Failure inducing case.
34CASE62: The Failure recovery case.
Jon Hall5cf14d52015-07-16 12:15:19 -070035CASE7: Check state after control plane failure
36CASE8: Compare topo
37CASE9: Link s3-s28 down
38CASE10: Link s3-s28 up
39CASE11: Switch down
40CASE12: Switch up
41CASE13: Clean up
42CASE14: start election app on all onos nodes
43CASE15: Check that Leadership Election is still functional
44CASE16: Install Distributed Primitives app
45CASE17: Check for basic functionality with distributed primitives
46"""
Jon Hallb3ed8ed2015-10-28 16:43:55 -070047class HAstopNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -070048
49 def __init__( self ):
50 self.default = ''
51
52 def CASE1( self, main ):
53 """
54 CASE1 is to compile ONOS and push it to the test machines
55
56 Startup sequence:
57 cell <name>
58 onos-verify-cell
59 NOTE: temporary - onos-remove-raft-logs
60 onos-uninstall
61 start mininet
62 git pull
63 mvn clean install
64 onos-package
65 onos-install -f
66 onos-wait-for-start
67 start cli sessions
68 start tcpdump
69 """
Jon Halle1a3b752015-07-22 13:02:46 -070070 import imp
Jon Hall3b489db2015-10-05 14:38:37 -070071 import pexpect
Jon Hallf3d16e72015-12-16 17:45:08 -080072 import time
Jon Halla440e872016-03-31 15:15:50 -070073 import json
Jon Hallb3ed8ed2015-10-28 16:43:55 -070074 main.log.info( "ONOS HA test: Stop a minority of ONOS nodes - " +
Jon Hall5cf14d52015-07-16 12:15:19 -070075 "initialization" )
Jon Halle1a3b752015-07-22 13:02:46 -070076 # set global variables
Jon Halla440e872016-03-31 15:15:50 -070077 # These are for csv plotting in jenkins
Devin Lim58046fa2017-07-05 16:55:00 -070078 main.HAlabels = []
79 main.HAdata = []
80 try:
81 from tests.dependencies.ONOSSetup import ONOSSetup
82 main.testSetUp = ONOSSetup()
83 except ImportError:
84 main.log.error( "ONOSSetup not found. exiting the test" )
85 main.exit()
86 main.testSetUp.envSetupDescription()
Jon Halle1a3b752015-07-22 13:02:46 -070087 try:
Jon Hall53c5e662016-04-13 16:06:56 -070088 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070089 main.HA = HA()
Devin Lim58046fa2017-07-05 16:55:00 -070090 # load some variables from the params file
91 cellName = main.params[ 'ENV' ][ 'cellName' ]
92 main.apps = main.params[ 'ENV' ][ 'appString' ]
93 main.numCtrls = int( main.params[ 'num_controllers' ] )
94 if main.ONOSbench.maxNodes and\
95 main.ONOSbench.maxNodes < main.numCtrls:
96 main.numCtrls = int( main.ONOSbench.maxNodes )
97 main.maxNodes = main.numCtrls
98 stepResult = main.testSetUp.envSetup( hasNode=True )
Jon Halle1a3b752015-07-22 13:02:46 -070099 except Exception as e:
Devin Lim58046fa2017-07-05 16:55:00 -0700100 main.testSetUp.envSetupException( e )
101 main.testSetUp.evnSetupConclusion( stepResult )
102 main.HA.generateGraph( "HAstopNodes" )
Jon Halle1a3b752015-07-22 13:02:46 -0700103
Devin Lim58046fa2017-07-05 16:55:00 -0700104 main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
105 extraApply=main.HA.customizeOnosGenPartitions,
106 extraClean=main.HA.cleanUpGenPartition )
Jon Hall5cf14d52015-07-16 12:15:19 -0700107
Devin Lim58046fa2017-07-05 16:55:00 -0700108 main.HA.initialSetUp()
Jon Hall9d2dcad2016-04-08 10:15:20 -0700109
Jon Hall5cf14d52015-07-16 12:15:19 -0700110 def CASE2( self, main ):
111 """
112 Assign devices to controllers
113 """
Devin Lim58046fa2017-07-05 16:55:00 -0700114 main.HA.assignDevices( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700115
116 def CASE21( self, main ):
117 """
118 Assign mastership to controllers
119 """
Devin Lim58046fa2017-07-05 16:55:00 -0700120 main.HA.assignMastership( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700121
Jon Hall5cf14d52015-07-16 12:15:19 -0700122
123 def CASE3( self, main ):
124 """
125 Assign intents
126 """
Devin Lim58046fa2017-07-05 16:55:00 -0700127 main.HA.assignIntents( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700128
Jon Hall5cf14d52015-07-16 12:15:19 -0700129
Jon Hall5cf14d52015-07-16 12:15:19 -0700130
131 def CASE4( self, main ):
132 """
133 Ping across added host intents
134 """
Devin Lim58046fa2017-07-05 16:55:00 -0700135 main.HA.pingAcrossHostIntent( main, True, False )
Jon Hall5cf14d52015-07-16 12:15:19 -0700136
137 def CASE5( self, main ):
138 """
139 Reading state of ONOS
140 """
Devin Lim58046fa2017-07-05 16:55:00 -0700141 main.HA.readingState( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700142
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700143 def CASE61( self, main ):
Jon Hall5cf14d52015-07-16 12:15:19 -0700144 """
145 The Failure case.
146 """
Jon Halle1a3b752015-07-22 13:02:46 -0700147 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700148 assert main, "main not defined"
149 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700150 assert main.CLIs, "main.CLIs not defined"
151 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700152 main.case( "Stop minority of ONOS nodes" )
Jon Hall96091e62015-09-21 17:34:17 -0700153
154 main.step( "Checking ONOS Logs for errors" )
155 for node in main.nodes:
156 main.log.debug( "Checking logs for errors on " + node.name + ":" )
157 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
158
Jon Hall3b489db2015-10-05 14:38:37 -0700159 n = len( main.nodes ) # Number of nodes
160 p = ( ( n + 1 ) / 2 ) + 1 # Number of partitions
161 main.kill = [ 0 ] # ONOS node to kill, listed by index in main.nodes
162 if n > 3:
163 main.kill.append( p - 1 )
164 # NOTE: This only works for cluster sizes of 3,5, or 7.
165
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700166 main.step( "Stopping " + str( len( main.kill ) ) + " ONOS nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -0700167 killResults = main.TRUE
168 for i in main.kill:
169 killResults = killResults and\
Jon Hallf37d44d2017-05-24 10:37:30 -0700170 main.ONOSbench.onosStop( main.nodes[ i ].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700171 main.activeNodes.remove( i )
Jon Hall5cf14d52015-07-16 12:15:19 -0700172 utilities.assert_equals( expect=main.TRUE, actual=killResults,
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700173 onpass="ONOS nodes stopped successfully",
174 onfail="ONOS nodes NOT successfully stopped" )
175
Jon Halld2871c22016-07-26 11:01:14 -0700176 main.step( "Checking ONOS nodes" )
177 nodeResults = utilities.retry( main.HA.nodesCheck,
178 False,
Jon Hallf37d44d2017-05-24 10:37:30 -0700179 args=[ main.activeNodes ],
Jon Halld2871c22016-07-26 11:01:14 -0700180 sleep=15,
181 attempts=5 )
182
183 utilities.assert_equals( expect=True, actual=nodeResults,
184 onpass="Nodes check successful",
185 onfail="Nodes check NOT successful" )
186
187 if not nodeResults:
188 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700189 cli = main.CLIs[ i ]
Jon Halld2871c22016-07-26 11:01:14 -0700190 main.log.debug( "{} components not ACTIVE: \n{}".format(
191 cli.name,
192 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
193 main.log.error( "Failed to start ONOS, stopping test" )
194 main.cleanup()
195 main.exit()
196
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700197 def CASE62( self, main ):
198 """
199 The bring up stopped nodes
200 """
Devin Lim58046fa2017-07-05 16:55:00 -0700201 main.HA.bringUpStoppedNode( main )
Jon Halla440e872016-03-31 15:15:50 -0700202
Jon Hall5cf14d52015-07-16 12:15:19 -0700203 def CASE7( self, main ):
204 """
205 Check state after ONOS failure
206 """
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700207 try:
208 main.kill
209 except AttributeError:
210 main.kill = []
211
Jon Hall5cf14d52015-07-16 12:15:19 -0700212
Devin Lim58046fa2017-07-05 16:55:00 -0700213 main.HA.checkStateAfterONOS( main, afterWhich=0 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700214
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 main.step( "Leadership Election is still functional" )
216 # Test of LeadershipElection
217 leaderList = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700218
Jon Hall3b489db2015-10-05 14:38:37 -0700219 restarted = []
220 for i in main.kill:
Jon Hallf37d44d2017-05-24 10:37:30 -0700221 restarted.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700222 leaderResult = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700223
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700224 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700225 cli = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700226 leaderN = cli.electionTestLeader()
227 leaderList.append( leaderN )
228 if leaderN == main.FALSE:
229 # error in response
230 main.log.error( "Something is wrong with " +
231 "electionTestLeader function, check the" +
232 " error logs" )
233 leaderResult = main.FALSE
234 elif leaderN is None:
235 main.log.error( cli.name +
236 " shows no leader for the election-app was" +
237 " elected after the old one died" )
238 leaderResult = main.FALSE
239 elif leaderN in restarted:
240 main.log.error( cli.name + " shows " + str( leaderN ) +
241 " as leader for the election-app, but it " +
242 "was restarted" )
243 leaderResult = main.FALSE
244 if len( set( leaderList ) ) != 1:
245 leaderResult = main.FALSE
246 main.log.error(
247 "Inconsistent view of leader for the election test app" )
248 # TODO: print the list
249 utilities.assert_equals(
250 expect=main.TRUE,
251 actual=leaderResult,
252 onpass="Leadership election passed",
253 onfail="Something went wrong with Leadership election" )
254
255 def CASE8( self, main ):
256 """
257 Compare topo
258 """
Devin Lim58046fa2017-07-05 16:55:00 -0700259 main.HA.compareTopo( main )
Jon Halld2871c22016-07-26 11:01:14 -0700260
Jon Hall5cf14d52015-07-16 12:15:19 -0700261 def CASE9( self, main ):
262 """
263 Link s3-s28 down
264 """
Devin Lim58046fa2017-07-05 16:55:00 -0700265 main.HA.linkDown( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700266
267 def CASE10( self, main ):
268 """
269 Link s3-s28 up
270 """
Devin Lim58046fa2017-07-05 16:55:00 -0700271 main.HA.linkUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700272
273 def CASE11( self, main ):
274 """
275 Switch Down
276 """
277 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700278 main.HA.switchDown( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700279
280 def CASE12( self, main ):
281 """
282 Switch Up
283 """
284 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700285 main.HA.switchUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700286
287 def CASE13( self, main ):
288 """
289 Clean up
290 """
Devin Lim58046fa2017-07-05 16:55:00 -0700291 main.HAlabels.append( "Restart" )
292 main.HAdata.append( str( main.restartTime ) )
293 main.HA.cleanUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700294
295 def CASE14( self, main ):
296 """
297 start election app on all onos nodes
298 """
Devin Lim58046fa2017-07-05 16:55:00 -0700299 main.HA.startElectionApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700300
301 def CASE15( self, main ):
302 """
303 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -0700304 15.1 Run election on each node
305 15.2 Check that each node has the same leaders and candidates
306 15.3 Find current leader and withdraw
307 15.4 Check that a new node was elected leader
308 15.5 Check that that new leader was the candidate of old leader
309 15.6 Run for election on old leader
310 15.7 Check that oldLeader is a candidate, and leader if only 1 node
311 15.8 Make sure that the old leader was added to the candidate list
312
313 old and new variable prefixes refer to data from before vs after
314 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -0700315 """
Devin Lim58046fa2017-07-05 16:55:00 -0700316 main.HA.isElectionFunctional( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700317
318 def CASE16( self, main ):
319 """
320 Install Distributed Primitives app
321 """
Devin Lim58046fa2017-07-05 16:55:00 -0700322 main.HA.installDistributedPrimitiveApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700323
324 def CASE17( self, main ):
325 """
326 Check for basic functionality with distributed primitives
327 """
Devin Lim58046fa2017-07-05 16:55:00 -0700328 main.HA.checkDistPrimitivesFunc( main )