blob: 14ffc7cb61b75acbaff3641c7c71e4f44b494dee [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"""
23
Jon Hall5cf14d52015-07-16 12:15:19 -070024Description: This test is to determine if ONOS can handle
25 all of it's nodes restarting
26
27List of test cases:
28CASE1: Compile ONOS and push it to the test machines
29CASE2: Assign devices to controllers
30CASE21: Assign mastership to controllers
31CASE3: Assign intents
32CASE4: Ping across added host intents
33CASE5: Reading state of ONOS
34CASE6: The Failure case.
35CASE7: 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 Hall5cf14d52015-07-16 12:15:19 -070047class HAclusterRestart:
48
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 Hallf3d16e72015-12-16 17:45:08 -080071 import time
Jon Halla440e872016-03-31 15:15:50 -070072 import json
Jon Hall5cf14d52015-07-16 12:15:19 -070073 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
74 "initialization" )
Jon Hall5cf14d52015-07-16 12:15:19 -070075 # These are for csv plotting in jenkins
Devin Lim58046fa2017-07-05 16:55:00 -070076 main.HAlabels = []
77 main.HAdata = []
78 try:
79 from tests.dependencies.ONOSSetup import ONOSSetup
80 main.testSetUp = ONOSSetup()
81 except ImportError:
82 main.log.error( "ONOSSetup not found exiting the test" )
83 main.exit()
84 main.testSetUp.envSetupDescription()
Jon Halle1a3b752015-07-22 13:02:46 -070085 try:
Jon Hall53c5e662016-04-13 16:06:56 -070086 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070087 main.HA = HA()
Devin Lim58046fa2017-07-05 16:55:00 -070088 # load some variables from the params file
89 cellName = main.params[ 'ENV' ][ 'cellName' ]
90 main.apps = main.params[ 'ENV' ][ 'appString' ]
91 main.numCtrls = int( main.params[ 'num_controllers' ] )
92 if main.ONOSbench.maxNodes and \
93 main.ONOSbench.maxNodes < main.numCtrls:
94 main.numCtrls = int( main.ONOSbench.maxNodes )
95 main.maxNodes = main.numCtrls
96 stepResult = main.testSetUp.envSetup( hasNode=True )
Jon Halle1a3b752015-07-22 13:02:46 -070097 except Exception as e:
Devin Lim58046fa2017-07-05 16:55:00 -070098 main.testSetUp.envSetupException( e )
99 main.testSetUp.evnSetupConclusion( stepResult )
100 main.HA.generateGraph( "HAclusterRestart" )
Jon Halle1a3b752015-07-22 13:02:46 -0700101
Devin Lim58046fa2017-07-05 16:55:00 -0700102 main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
103 extraApply=main.HA.startingMininet )
Jon Hall5cf14d52015-07-16 12:15:19 -0700104
Devin Lim58046fa2017-07-05 16:55:00 -0700105 main.HA.initialSetUp()
Jon Hall9d2dcad2016-04-08 10:15:20 -0700106
Jon Hall5cf14d52015-07-16 12:15:19 -0700107 def CASE2( self, main ):
108 """
109 Assign devices to controllers
110 """
Devin Lim58046fa2017-07-05 16:55:00 -0700111 main.HA.assignDevices( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700112
113 def CASE21( self, main ):
114 """
115 Assign mastership to controllers
116 """
Devin Lim58046fa2017-07-05 16:55:00 -0700117 main.HA.assignMastership( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700118 def CASE3( self, main ):
119 """
120 Assign intents
121 """
Devin Lim58046fa2017-07-05 16:55:00 -0700122 main.HA.assignIntents(main)
Jon Hall5cf14d52015-07-16 12:15:19 -0700123
124 def CASE4( self, main ):
125 """
126 Ping across added host intents
127 """
Jon Hallca319892017-06-15 15:25:22 -0700128 main.HA.pingAcrossHostIntent( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700129
130 def CASE5( self, main ):
131 """
132 Reading state of ONOS
133 """
Devin Lim58046fa2017-07-05 16:55:00 -0700134 main.HA.readingState( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700135
136 def CASE6( self, main ):
137 """
138 The Failure case.
139 """
140 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700141 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700142 assert main, "main not defined"
143 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700144 assert main.CLIs, "main.CLIs not defined"
145 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700146 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700147 main.HAlabels
148 except ( NameError, AttributeError ):
149 main.log.error( "main.HAlabels not defined, setting to []" )
150 main.HAlabels = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700152 main.HAdata
153 except ( NameError, AttributeError ):
154 main.log.error( "main.HAdata not defined, setting to []" )
155 main.HAdata = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700156 # Reset non-persistent variables
157 try:
158 iCounterValue = 0
159 except NameError:
160 main.log.error( "iCounterValue not defined, setting to 0" )
161 iCounterValue = 0
162
163 main.case( "Restart entire ONOS cluster" )
164
Jon Hall5ec6b1b2015-09-17 18:20:14 -0700165 main.step( "Checking ONOS Logs for errors" )
166 for node in main.nodes:
167 main.log.debug( "Checking logs for errors on " + node.name + ":" )
168 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
169
Jon Hall5cf14d52015-07-16 12:15:19 -0700170 main.step( "Killing ONOS nodes" )
171 killResults = main.TRUE
172 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -0700173 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700174 killed = main.ONOSbench.onosKill( node.ip_address )
175 killResults = killResults and killed
176 utilities.assert_equals( expect=main.TRUE, actual=killResults,
177 onpass="ONOS nodes killed",
178 onfail="ONOS kill unsuccessful" )
179
180 main.step( "Checking if ONOS is up yet" )
181 for i in range( 2 ):
182 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700183 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700184 started = main.ONOSbench.isup( node.ip_address )
185 if not started:
186 main.log.error( node.name + " didn't start!" )
187 onosIsupResult = onosIsupResult and started
188 if onosIsupResult == main.TRUE:
189 break
190 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
191 onpass="ONOS restarted",
192 onfail="ONOS restart NOT successful" )
193
Jon Hall6509dbf2016-06-21 17:01:17 -0700194 main.step( "Starting ONOS CLI sessions" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700195 cliResults = main.TRUE
196 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700197 for i in range( main.numCtrls ):
Jon Hallf37d44d2017-05-24 10:37:30 -0700198 t = main.Thread( target=main.CLIs[ i ].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700199 name="startOnosCli-" + str( i ),
Jon Hallf37d44d2017-05-24 10:37:30 -0700200 args=[ main.nodes[ i ].ip_address ] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700201 threads.append( t )
202 t.start()
203
204 for t in threads:
205 t.join()
206 cliResults = cliResults and t.result
207 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
208 onpass="ONOS cli started",
209 onfail="ONOS clis did not restart" )
210
Jon Hall6e709752016-02-01 13:38:46 -0800211 for i in range( 10 ):
212 ready = True
Jon Hall7ac7bc32016-05-05 10:57:02 -0700213 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700214 cli = main.CLIs[ i ]
Jon Hall6e709752016-02-01 13:38:46 -0800215 output = cli.summary()
216 if not output:
217 ready = False
Jon Halld2871c22016-07-26 11:01:14 -0700218 if ready:
219 break
Jon Hall6e709752016-02-01 13:38:46 -0800220 time.sleep( 30 )
221 utilities.assert_equals( expect=True, actual=ready,
222 onpass="ONOS summary command succeded",
223 onfail="ONOS summary command failed" )
224 if not ready:
225 main.cleanup()
226 main.exit()
227
Jon Hall5cf14d52015-07-16 12:15:19 -0700228 # Grab the time of restart so we chan check how long the gossip
229 # protocol has had time to work
230 main.restartTime = time.time() - killTime
231 main.log.debug( "Restart time: " + str( main.restartTime ) )
Devin Lim58046fa2017-07-05 16:55:00 -0700232 main.HAlabels.append( "Restart" )
233 main.HAdata.append( str( main.restartTime ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700234
Jon Hall5cf14d52015-07-16 12:15:19 -0700235 # Rerun for election on restarted nodes
236 runResults = main.TRUE
Jon Hall7ac7bc32016-05-05 10:57:02 -0700237 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700238 cli = main.CLIs[ i ]
Jon Halla440e872016-03-31 15:15:50 -0700239 run = cli.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -0700240 if run != main.TRUE:
241 main.log.error( "Error running for election on " + cli.name )
242 runResults = runResults and run
243 utilities.assert_equals( expect=main.TRUE, actual=runResults,
244 onpass="Reran for election",
245 onfail="Failed to rerun for election" )
246
247 # TODO: Make this configurable
248 time.sleep( 60 )
Jon Hallf37d44d2017-05-24 10:37:30 -0700249 node = main.activeNodes[ 0 ]
250 main.log.debug( main.CLIs[ node ].nodes( jsonFormat=False ) )
251 main.log.debug( main.CLIs[ node ].leaders( jsonFormat=False ) )
252 main.log.debug( main.CLIs[ node ].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700253
254 def CASE7( self, main ):
255 """
256 Check state after ONOS failure
257 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700258 # NOTE: Store has no durability, so intents are lost across system
259 # restarts
Devin Lim58046fa2017-07-05 16:55:00 -0700260 main.HA.checkStateAfterONOS( main, afterWhich=0, isRestart=True )
Jon Hall5cf14d52015-07-16 12:15:19 -0700261
Jon Hall5cf14d52015-07-16 12:15:19 -0700262 main.step( "Leadership Election is still functional" )
263 # Test of LeadershipElection
264 leaderList = []
265 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700266
267 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700268 cli = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700269 leaderN = cli.electionTestLeader()
270 leaderList.append( leaderN )
271 if leaderN == main.FALSE:
272 # error in response
273 main.log.error( "Something is wrong with " +
274 "electionTestLeader function, check the" +
275 " error logs" )
276 leaderResult = main.FALSE
277 elif leaderN is None:
278 main.log.error( cli.name +
279 " shows no leader for the election-app." )
280 leaderResult = main.FALSE
281 if len( set( leaderList ) ) != 1:
282 leaderResult = main.FALSE
283 main.log.error(
284 "Inconsistent view of leader for the election test app" )
285 # TODO: print the list
286 utilities.assert_equals(
287 expect=main.TRUE,
288 actual=leaderResult,
289 onpass="Leadership election passed",
290 onfail="Something went wrong with Leadership election" )
291
292 def CASE8( self, main ):
293 """
294 Compare topo
295 """
Devin Lim58046fa2017-07-05 16:55:00 -0700296 main.HA.compareTopo( main )
Jon Halld2871c22016-07-26 11:01:14 -0700297
Jon Hall5cf14d52015-07-16 12:15:19 -0700298 def CASE9( self, main ):
299 """
300 Link s3-s28 down
301 """
Devin Lim58046fa2017-07-05 16:55:00 -0700302 main.HA.linkDown( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700303
304 def CASE10( self, main ):
305 """
306 Link s3-s28 up
307 """
Devin Lim58046fa2017-07-05 16:55:00 -0700308 main.HA.linkUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700309
310 def CASE11( self, main ):
311 """
312 Switch Down
313 """
314 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700315 main.HA.switchDown( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700316
317 def CASE12( self, main ):
318 """
319 Switch Up
320 """
321 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700322 main.HA.switchUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700323
324 def CASE13( self, main ):
325 """
326 Clean up
327 """
Devin Lim58046fa2017-07-05 16:55:00 -0700328 main.HA.cleanUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700329
330 def CASE14( self, main ):
331 """
332 start election app on all onos nodes
333 """
Devin Lim58046fa2017-07-05 16:55:00 -0700334 main.HA.startElectionApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700335
336 def CASE15( self, main ):
337 """
338 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -0700339 15.1 Run election on each node
340 15.2 Check that each node has the same leaders and candidates
341 15.3 Find current leader and withdraw
342 15.4 Check that a new node was elected leader
343 15.5 Check that that new leader was the candidate of old leader
344 15.6 Run for election on old leader
345 15.7 Check that oldLeader is a candidate, and leader if only 1 node
346 15.8 Make sure that the old leader was added to the candidate list
347
348 old and new variable prefixes refer to data from before vs after
349 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -0700350 """
Devin Lim58046fa2017-07-05 16:55:00 -0700351 main.HA.isElectionFunctional( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700352
353 def CASE16( self, main ):
354 """
355 Install Distributed Primitives app
356 """
Devin Lim58046fa2017-07-05 16:55:00 -0700357 main.HA.installDistributedPrimitiveApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700358
359 def CASE17( self, main ):
360 """
361 Check for basic functionality with distributed primitives
362 """
Devin Lim58046fa2017-07-05 16:55:00 -0700363 main.HA.checkDistPrimitivesFunc( main )