blob: 7010f93240c90cbc72e3cd3bab2335ae44a1b5a8 [file] [log] [blame]
Jon Hall7ce46ea2018-02-05 12:20:59 -08001"""
2Copyright 2018 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"""
22Description: 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"""
45class HAbackupRecover:
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" )
70 # These are for csv plotting in jenkins
71 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" )
Jon Hall7ce46ea2018-02-05 12:20:59 -080078 main.cleanAndExit()
79 main.testSetUp.envSetupDescription()
80 try:
81 from tests.HA.dependencies.HA import HA
82 main.HA = HA()
83 # 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 Hall7ce46ea2018-02-05 12:20:59 -080087 except Exception as e:
88 main.testSetUp.envSetupException( e )
89 main.testSetUp.evnSetupConclusion( stepResult )
90
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 Hall7ce46ea2018-02-05 12:20:59 -0800101
102 main.HA.initialSetUp()
103
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 Hall7ce46ea2018-02-05 12:20:59 -0800118 def CASE2( self, main ):
119 """
120 Assign devices to controllers
121 """
122 main.HA.assignDevices( main )
123
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 Hall7ce46ea2018-02-05 12:20:59 -0800130 def CASE21( self, main ):
131 """
132 Assign mastership to controllers
133 """
134 main.HA.assignMastership( main )
135
136 def CASE3( self, main ):
137 """
138 Assign intents
139 """
140 main.HA.assignIntents( main )
141
142 def CASE4( self, main ):
143 """
144 Ping across added host intents
145 """
146 main.HA.pingAcrossHostIntent( main )
147
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 Hall7ce46ea2018-02-05 12:20:59 -0800159 def CASE5( self, main ):
160 """
161 Reading state of ONOS
162 """
163 main.HA.readingState( main )
164
165 def CASE6( self, main ):
166 """
167 The Failure case.
168 """
169 import time
170 assert main, "main not defined"
171 assert utilities.assert_equals, "utilities.assert_equals not defined"
172 try:
173 main.HAlabels
174 except ( NameError, AttributeError ):
175 main.log.error( "main.HAlabels not defined, setting to []" )
176 main.HAlabels = []
177 try:
178 main.HAdata
179 except ( NameError, AttributeError ):
180 main.log.error( "main.HAdata not defined, setting to []" )
181 main.HAdata = []
182
183 main.case( "Restart entire ONOS cluster with backed up state" )
184
185 main.step( "Backup ONOS data" )
186 location = "/tmp/" + main.TEST + ".tar.gz"
187 backupResult = main.HA.backupData( main, location )
188 utilities.assert_equals( expect=True, actual=backupResult,
189 onpass="ONOS backup succeded",
190 onfail="ONOS backup failed" )
191
192 main.step( "Checking ONOS Logs for errors" )
193 for ctrl in main.Cluster.active():
194 main.log.debug( "Checking logs for errors on " + ctrl.name + ":" )
195 main.log.warn( main.ONOSbench.checkLogs( ctrl.ipAddress ) )
196
197 killTime = time.time()
198 main.testSetUp.uninstallOnos( main.Cluster, uninstallMax=True )
199
200 clusterSize = len( main.Cluster.active() )
201 main.Cluster.setRunningNode( 0 ) # So we can install without starting ONOS
202 main.testSetUp.installOnos( main.Cluster, installMax=True )
203 main.Cluster.setRunningNode( clusterSize )
204
205 main.step( "Restore ONOS data" )
206 restoreResult = main.HA.restoreData( main, location )
207 utilities.assert_equals( expect=True, actual=restoreResult,
208 onpass="ONOS restore succeded",
209 onfail="ONOS restore failed" )
210
211 main.step( "Restart ONOS nodes" )
212 started = main.Cluster.command( "onosStart",
213 args=[ "ipAddress" ],
214 getFrom=0,
215 funcFromCtrl=True )
216 for ctrl in main.Cluster.controllers:
217 ctrl.active = True
218 main.log.debug( repr( ctrl ) )
219
220 main.testSetUp.setupSsh( main.Cluster )
221 main.testSetUp.checkOnosService( main.Cluster )
222 main.testSetUp.startOnosClis( main.Cluster )
223
224 ready = utilities.retry( main.Cluster.command,
225 False,
226 kwargs={ "function": "summary", "contentCheck": True },
227 sleep=30,
228 attempts=10 )
229 utilities.assert_equals( expect=True, actual=ready,
230 onpass="ONOS summary command succeded",
231 onfail="ONOS summary command failed" )
232 if not ready:
233 main.cleanAndExit()
234
235 # Grab the time of restart so we chan check how long the gossip
236 # protocol has had time to work
237 main.restartTime = time.time() - killTime
238 main.log.debug( "Restart time: " + str( main.restartTime ) )
239 main.HAlabels.append( "Restart" )
240 main.HAdata.append( str( main.restartTime ) )
241
242 # Rerun for election on restarted nodes
243 runResults = main.Cluster.command( "electionTestRun", returnBool=True )
244 utilities.assert_equals( expect=True, actual=runResults,
245 onpass="Reran for election",
246 onfail="Failed to rerun for election" )
247
248 main.HA.commonChecks()
Jon Hall9677ed32018-04-24 11:16:23 -0700249 time.sleep(60)
Jon Hall7ce46ea2018-02-05 12:20:59 -0800250
251 def CASE7( self, main ):
252 """
253 Check state after ONOS failure
254 """
255 # NOTE: Store has no durability, so intents are lost across system
256 # restarts
257 main.HA.checkStateAfterEvent( main, afterWhich=0, isRestart=True )
258
259 main.step( "Leadership Election is still functional" )
260 # Test of LeadershipElection
261 leaderList = []
262 leaderResult = main.TRUE
263
264 for ctrl in main.Cluster.active():
Jon Hall7ce46ea2018-02-05 12:20:59 -0800265 leaderN = ctrl.CLI.electionTestLeader()
266 leaderList.append( leaderN )
267 if leaderN == main.FALSE:
268 # error in response
269 main.log.error( "Something is wrong with " +
270 "electionTestLeader function, check the" +
271 " error logs" )
272 leaderResult = main.FALSE
273 elif leaderN is None:
274 main.log.error( ctrl.name +
275 " shows no leader for the election-app." )
276 leaderResult = main.FALSE
277 if len( set( leaderList ) ) != 1:
278 leaderResult = main.FALSE
279 main.log.error(
280 "Inconsistent view of leader for the election test app" )
Jon Hallab611372018-02-21 15:26:05 -0800281 main.log.debug( leaderList )
Jon Hall7ce46ea2018-02-05 12:20:59 -0800282 utilities.assert_equals(
283 expect=main.TRUE,
284 actual=leaderResult,
285 onpass="Leadership election passed",
286 onfail="Something went wrong with Leadership election" )
287
288 def CASE8( self, main ):
289 """
290 Compare topo
291 """
292 main.HA.compareTopo( main )
293
294 def CASE9( self, main ):
295 """
Jon Hallab611372018-02-21 15:26:05 -0800296 Link down
Jon Hall7ce46ea2018-02-05 12:20:59 -0800297 """
Jon Hallab611372018-02-21 15:26:05 -0800298 src = main.params['kill']['linkSrc']
299 dst = main.params['kill']['linkDst']
300 main.HA.linkDown( main, src, dst )
Jon Hall7ce46ea2018-02-05 12:20:59 -0800301
302 def CASE10( self, main ):
303 """
Jon Hallab611372018-02-21 15:26:05 -0800304 Link up
Jon Hall7ce46ea2018-02-05 12:20:59 -0800305 """
Jon Hallab611372018-02-21 15:26:05 -0800306 src = main.params['kill']['linkSrc']
307 dst = main.params['kill']['linkDst']
308 main.HA.linkUp( main, src, dst )
Jon Hall7ce46ea2018-02-05 12:20:59 -0800309
310 def CASE11( self, main ):
311 """
312 Switch Down
313 """
314 # NOTE: You should probably run a topology check after this
315 main.HA.switchDown( main )
316
317 def CASE12( self, main ):
318 """
319 Switch Up
320 """
321 # NOTE: You should probably run a topology check after this
322 main.HA.switchUp( main )
323
324 def CASE13( self, main ):
325 """
326 Clean up
327 """
328 main.HA.cleanUp( main )
329
330 def CASE14( self, main ):
331 """
Jon Hallab611372018-02-21 15:26:05 -0800332 Start election app on all onos nodes
Jon Hall7ce46ea2018-02-05 12:20:59 -0800333 """
334 try:
335 main.HA.startElectionApp( main )
336 except Exception as e:
337 main.log.error( e )
338
339 def CASE15( self, main ):
340 """
341 Check that Leadership Election is still functional
342 15.1 Run election on each node
343 15.2 Check that each node has the same leaders and candidates
344 15.3 Find current leader and withdraw
345 15.4 Check that a new node was elected leader
346 15.5 Check that that new leader was the candidate of old leader
347 15.6 Run for election on old leader
348 15.7 Check that oldLeader is a candidate, and leader if only 1 node
349 15.8 Make sure that the old leader was added to the candidate list
350
351 old and new variable prefixes refer to data from before vs after
352 withdrawl and later before withdrawl vs after re-election
353 """
354 main.HA.isElectionFunctional( main )
355
356 def CASE16( self, main ):
357 """
358 Install Distributed Primitives app
359 """
360 main.HA.installDistributedPrimitiveApp( main )
361
362 def CASE17( self, main ):
363 """
364 Check for basic functionality with distributed primitives
365 """
366 main.HA.checkDistPrimitivesFunc( main )