blob: 14a08983e24dbe352bb3ecf936101e3b82cff2dc [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002Copyright 2015 Open Networking Foundation ( ONF )
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07003
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
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070011 ( at your option ) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070012
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"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070021"""
Jon Hall5cf14d52015-07-16 12:15:19 -070022Description: This test is to determine if ONOS can handle
23 all of it's nodes restarting
24
25List of test cases:
26CASE1: Compile ONOS and push it to the test machines
27CASE2: Assign devices to controllers
28CASE21: Assign mastership to controllers
29CASE3: Assign intents
30CASE4: Ping across added host intents
31CASE5: Reading state of ONOS
32CASE6: The Failure case.
33CASE7: Check state after control plane failure
34CASE8: Compare topo
35CASE9: Link s3-s28 down
36CASE10: Link s3-s28 up
37CASE11: Switch down
38CASE12: Switch up
39CASE13: Clean up
40CASE14: start election app on all onos nodes
41CASE15: Check that Leadership Election is still functional
42CASE16: Install Distributed Primitives app
43CASE17: Check for basic functionality with distributed primitives
44"""
Jon Hall5cf14d52015-07-16 12:15:19 -070045class HAclusterRestart:
46
47 def __init__( self ):
48 self.default = ''
49
50 def CASE1( self, main ):
51 """
52 CASE1 is to compile ONOS and push it to the test machines
53
54 Startup sequence:
55 cell <name>
56 onos-verify-cell
57 NOTE: temporary - onos-remove-raft-logs
58 onos-uninstall
59 start mininet
60 git pull
61 mvn clean install
62 onos-package
63 onos-install -f
64 onos-wait-for-start
65 start cli sessions
66 start tcpdump
67 """
68 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
69 "initialization" )
Jon Hall5cf14d52015-07-16 12:15:19 -070070 # These are for csv plotting in jenkins
Devin Lim58046fa2017-07-05 16:55:00 -070071 main.HAlabels = []
72 main.HAdata = []
73 try:
74 from tests.dependencies.ONOSSetup import ONOSSetup
75 main.testSetUp = ONOSSetup()
76 except ImportError:
Jon Hallab611372018-02-21 15:26:05 -080077 main.log.error( "ONOSSetup not found. exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -070078 main.cleanAndExit()
Devin Lim58046fa2017-07-05 16:55:00 -070079 main.testSetUp.envSetupDescription()
Jon Halle1a3b752015-07-22 13:02:46 -070080 try:
Jon Hall53c5e662016-04-13 16:06:56 -070081 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070082 main.HA = HA()
Devin Lim58046fa2017-07-05 16:55:00 -070083 # load some variables from the params file
84 cellName = main.params[ 'ENV' ][ 'cellName' ]
85 main.apps = main.params[ 'ENV' ][ 'appString' ]
Jon Hallab611372018-02-21 15:26:05 -080086 stepResult = main.testSetUp.envSetup( includeCaseDesc=False )
Jon Halle1a3b752015-07-22 13:02:46 -070087 except Exception as e:
Devin Lim58046fa2017-07-05 16:55:00 -070088 main.testSetUp.envSetupException( e )
89 main.testSetUp.evnSetupConclusion( stepResult )
Jon Halle1a3b752015-07-22 13:02:46 -070090
Jon Hallab611372018-02-21 15:26:05 -080091 try:
92 if main.params[ 'topology' ][ 'topoFile' ]:
93 main.log.info( 'Skipping start of Mininet in this case, make sure you start it elsewhere' )
94 applyFuncs = None
95 else:
96 applyFuncs = main.HA.startingMininet
97 except (KeyError, IndexError):
98 applyFuncs = main.HA.startingMininet
99
Jon Hall3e6edb32018-08-21 16:20:30 -0700100 main.testSetUp.ONOSSetUp( main.Cluster, cellName=cellName, extraApply=applyFuncs )
Jon Hall5cf14d52015-07-16 12:15:19 -0700101
Devin Lim58046fa2017-07-05 16:55:00 -0700102 main.HA.initialSetUp()
Jon Hall9d2dcad2016-04-08 10:15:20 -0700103
Jon Hallab611372018-02-21 15:26:05 -0800104 main.step( 'Set logging levels' )
105 logging = True
106 try:
107 logs = main.params.get( 'ONOS_Logging', False )
108 if logs:
109 for namespace, level in logs.items():
110 for ctrl in main.Cluster.active():
111 ctrl.CLI.logSet( level, namespace )
112 except AttributeError:
113 logging = False
114 utilities.assert_equals( expect=True, actual=logging,
115 onpass="Set log levels",
116 onfail="Failed to set log levels" )
117
Jon Hall5cf14d52015-07-16 12:15:19 -0700118 def CASE2( self, main ):
119 """
120 Assign devices to controllers
121 """
Devin Lim58046fa2017-07-05 16:55:00 -0700122 main.HA.assignDevices( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700123
Jon Hallab611372018-02-21 15:26:05 -0800124 def CASE102( self, main ):
125 """
126 Set up Spine-Leaf fabric topology in Mininet
127 """
128 main.HA.startTopology( main )
129
Jon Hall5cf14d52015-07-16 12:15:19 -0700130 def CASE21( self, main ):
131 """
132 Assign mastership to controllers
133 """
Devin Lim58046fa2017-07-05 16:55:00 -0700134 main.HA.assignMastership( main )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700135
Jon Hall5cf14d52015-07-16 12:15:19 -0700136 def CASE3( self, main ):
137 """
138 Assign intents
139 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700140 main.HA.assignIntents( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700141
142 def CASE4( self, main ):
143 """
144 Ping across added host intents
145 """
Jon Hallca319892017-06-15 15:25:22 -0700146 main.HA.pingAcrossHostIntent( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700147
Jon Hallab611372018-02-21 15:26:05 -0800148 def CASE104( self, main ):
149 """
150 Ping Hosts
151 """
152 main.case( "Check connectivity" )
153 main.step( "Ping between all hosts" )
154 pingResult = main.Mininet1.pingall()
155 utilities.assert_equals( expect=main.TRUE, actual=pingResult,
156 onpass="All Pings Passed",
157 onfail="Failed to ping between all hosts" )
158
Jon Hall5cf14d52015-07-16 12:15:19 -0700159 def CASE5( self, main ):
160 """
161 Reading state of ONOS
162 """
Devin Lim58046fa2017-07-05 16:55:00 -0700163 main.HA.readingState( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700164
165 def CASE6( self, main ):
166 """
167 The Failure case.
168 """
169 import time
Jon Hall5cf14d52015-07-16 12:15:19 -0700170 assert main, "main not defined"
171 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700172 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700173 main.HAlabels
174 except ( NameError, AttributeError ):
175 main.log.error( "main.HAlabels not defined, setting to []" )
176 main.HAlabels = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700177 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700178 main.HAdata
179 except ( NameError, AttributeError ):
180 main.log.error( "main.HAdata not defined, setting to []" )
181 main.HAdata = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700182
183 main.case( "Restart entire ONOS cluster" )
184
Jon Hall5ec6b1b2015-09-17 18:20:14 -0700185 main.step( "Checking ONOS Logs for errors" )
Devin Lim142b5342017-07-20 15:22:39 -0700186 for ctrl in main.Cluster.active():
187 main.log.debug( "Checking logs for errors on " + ctrl.name + ":" )
188 main.log.warn( main.ONOSbench.checkLogs( ctrl.ipAddress ) )
Devin Lim6301b742017-08-07 11:00:21 -0700189 killTime = time.time()
Devin Lim142b5342017-07-20 15:22:39 -0700190 main.testSetUp.killingAllOnos( main.Cluster, True, False )
Jon Hall5cf14d52015-07-16 12:15:19 -0700191
Devin Lim142b5342017-07-20 15:22:39 -0700192 main.testSetUp.checkOnosService( main.Cluster )
Jon Hall5cf14d52015-07-16 12:15:19 -0700193
Devin Lim142b5342017-07-20 15:22:39 -0700194 main.testSetUp.startOnosClis( main.Cluster )
Jon Hall5cf14d52015-07-16 12:15:19 -0700195
Devin Lim142b5342017-07-20 15:22:39 -0700196 ready = utilities.retry( main.Cluster.command,
197 False,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700198 kwargs={ "function": "summary", "contentCheck": True },
Devin Lim142b5342017-07-20 15:22:39 -0700199 sleep=30,
200 attempts=10 )
Jon Hall6e709752016-02-01 13:38:46 -0800201 utilities.assert_equals( expect=True, actual=ready,
202 onpass="ONOS summary command succeded",
203 onfail="ONOS summary command failed" )
204 if not ready:
Devin Lim44075962017-08-11 10:56:37 -0700205 main.cleanAndExit()
Jon Hall6e709752016-02-01 13:38:46 -0800206
Jon Hall5cf14d52015-07-16 12:15:19 -0700207 # Grab the time of restart so we chan check how long the gossip
208 # protocol has had time to work
209 main.restartTime = time.time() - killTime
210 main.log.debug( "Restart time: " + str( main.restartTime ) )
Devin Lim58046fa2017-07-05 16:55:00 -0700211 main.HAlabels.append( "Restart" )
212 main.HAdata.append( str( main.restartTime ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700213
Jon Hall5cf14d52015-07-16 12:15:19 -0700214 # Rerun for election on restarted nodes
Devin Lim142b5342017-07-20 15:22:39 -0700215 runResults = main.Cluster.command( "electionTestRun", returnBool=True )
216 utilities.assert_equals( expect=True, actual=runResults,
Jon Hall5cf14d52015-07-16 12:15:19 -0700217 onpass="Reran for election",
218 onfail="Failed to rerun for election" )
219
220 # TODO: Make this configurable
221 time.sleep( 60 )
Devin Lim142b5342017-07-20 15:22:39 -0700222
223 main.HA.commonChecks()
Jon Hall5cf14d52015-07-16 12:15:19 -0700224
225 def CASE7( self, main ):
226 """
227 Check state after ONOS failure
228 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700229 # NOTE: Store has no durability, so intents are lost across system
230 # restarts
Devin Lim142b5342017-07-20 15:22:39 -0700231 main.HA.checkStateAfterEvent( main, afterWhich=0, isRestart=True )
Jon Hall5cf14d52015-07-16 12:15:19 -0700232
Jon Hall5cf14d52015-07-16 12:15:19 -0700233 main.step( "Leadership Election is still functional" )
234 # Test of LeadershipElection
235 leaderList = []
236 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700237
Devin Lim142b5342017-07-20 15:22:39 -0700238 for ctrl in main.Cluster.active():
Devin Lim142b5342017-07-20 15:22:39 -0700239 leaderN = ctrl.CLI.electionTestLeader()
Jon Hall5cf14d52015-07-16 12:15:19 -0700240 leaderList.append( leaderN )
241 if leaderN == main.FALSE:
242 # error in response
243 main.log.error( "Something is wrong with " +
244 "electionTestLeader function, check the" +
245 " error logs" )
246 leaderResult = main.FALSE
247 elif leaderN is None:
Jon Halla478b852017-12-04 15:00:15 -0800248 main.log.error( ctrl.name +
Jon Hall5cf14d52015-07-16 12:15:19 -0700249 " shows no leader for the election-app." )
250 leaderResult = main.FALSE
251 if len( set( leaderList ) ) != 1:
252 leaderResult = main.FALSE
253 main.log.error(
254 "Inconsistent view of leader for the election test app" )
Jon Hallab611372018-02-21 15:26:05 -0800255 main.log.debug( leaderList )
Jon Hall5cf14d52015-07-16 12:15:19 -0700256 utilities.assert_equals(
257 expect=main.TRUE,
258 actual=leaderResult,
259 onpass="Leadership election passed",
260 onfail="Something went wrong with Leadership election" )
261
262 def CASE8( self, main ):
263 """
264 Compare topo
265 """
Devin Lim58046fa2017-07-05 16:55:00 -0700266 main.HA.compareTopo( main )
Jon Halld2871c22016-07-26 11:01:14 -0700267
Jon Hall5cf14d52015-07-16 12:15:19 -0700268 def CASE9( self, main ):
269 """
Jon Hallab611372018-02-21 15:26:05 -0800270 Link down
Jon Hall5cf14d52015-07-16 12:15:19 -0700271 """
Jon Hallab611372018-02-21 15:26:05 -0800272 src = main.params['kill']['linkSrc']
273 dst = main.params['kill']['linkDst']
274 main.HA.linkDown( main, src, dst )
Jon Hall5cf14d52015-07-16 12:15:19 -0700275
276 def CASE10( self, main ):
277 """
Jon Hallab611372018-02-21 15:26:05 -0800278 Link up
Jon Hall5cf14d52015-07-16 12:15:19 -0700279 """
Jon Hallab611372018-02-21 15:26:05 -0800280 src = main.params['kill']['linkSrc']
281 dst = main.params['kill']['linkDst']
282 main.HA.linkUp( main, src, dst )
Jon Hall5cf14d52015-07-16 12:15:19 -0700283
284 def CASE11( self, main ):
285 """
286 Switch Down
287 """
288 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700289 main.HA.switchDown( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700290
291 def CASE12( self, main ):
292 """
293 Switch Up
294 """
295 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700296 main.HA.switchUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700297
298 def CASE13( self, main ):
299 """
300 Clean up
301 """
Devin Lim58046fa2017-07-05 16:55:00 -0700302 main.HA.cleanUp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700303
304 def CASE14( self, main ):
305 """
Jon Hallab611372018-02-21 15:26:05 -0800306 Start election app on all onos nodes
Jon Hall5cf14d52015-07-16 12:15:19 -0700307 """
Devin Lim58046fa2017-07-05 16:55:00 -0700308 main.HA.startElectionApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700309
310 def CASE15( self, main ):
311 """
312 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -0700313 15.1 Run election on each node
314 15.2 Check that each node has the same leaders and candidates
315 15.3 Find current leader and withdraw
316 15.4 Check that a new node was elected leader
317 15.5 Check that that new leader was the candidate of old leader
318 15.6 Run for election on old leader
319 15.7 Check that oldLeader is a candidate, and leader if only 1 node
320 15.8 Make sure that the old leader was added to the candidate list
321
322 old and new variable prefixes refer to data from before vs after
323 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -0700324 """
Devin Lim58046fa2017-07-05 16:55:00 -0700325 main.HA.isElectionFunctional( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700326
327 def CASE16( self, main ):
328 """
329 Install Distributed Primitives app
330 """
Devin Lim58046fa2017-07-05 16:55:00 -0700331 main.HA.installDistributedPrimitiveApp( main )
Jon Hall5cf14d52015-07-16 12:15:19 -0700332
333 def CASE17( self, main ):
334 """
335 Check for basic functionality with distributed primitives
336 """
Devin Lim58046fa2017-07-05 16:55:00 -0700337 main.HA.checkDistPrimitivesFunc( main )