blob: 6a0abd4b5085ad34e89f3d35c1bc310facef07c2 [file] [log] [blame]
Jon Hall9ebd1bd2016-04-19 01:37:17 -07001"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07002Copyright 2016 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 Hall9ebd1bd2016-04-19 01:37:17 -070023Description: This test is to determine if ONOS can handle
24 dynamic scaling of the cluster size.
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
33CASE6: The scaling case.
34CASE7: Check state after control plane failure
35CASE8: Compare topo
36CASE9: Link s3-s28 down
37CASE10: Link s3-s28 up
38CASE11: Switch down
39CASE12: Switch up
40CASE13: Clean up
41CASE14: start election app on all onos nodes
42CASE15: Check that Leadership Election is still functional
43CASE16: Install Distributed Primitives app
44CASE17: Check for basic functionality with distributed primitives
45"""
Jon Hall9ebd1bd2016-04-19 01:37:17 -070046class HAscaling:
47
48 def __init__( self ):
49 self.default = ''
50
51 def CASE1( self, main ):
52 """
53 CASE1 is to compile ONOS and push it to the test machines
54
55 Startup sequence:
56 cell <name>
57 onos-verify-cell
58 NOTE: temporary - onos-remove-raft-logs
59 onos-uninstall
60 start mininet
61 git pull
62 mvn clean install
63 onos-package
64 onos-install -f
65 onos-wait-for-start
66 start cli sessions
67 start tcpdump
68 """
69 import time
70 import os
71 import re
72 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
73 "initialization" )
Jon Hall9ebd1bd2016-04-19 01:37:17 -070074 # set global variables
75 # 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()
Jon Hall9ebd1bd2016-04-19 01:37:17 -070084
Devin Lim58046fa2017-07-05 16:55:00 -070085 main.testSetUp.envSetupDescription()
Jon Hall9ebd1bd2016-04-19 01:37:17 -070086 try:
87 from tests.HA.dependencies.HA import HA
88 main.HA = HA()
Devin Lim58046fa2017-07-05 16:55:00 -070089 from tests.HA.HAswapNodes.dependencies.Server import Server
Jon Hall9ebd1bd2016-04-19 01:37:17 -070090 main.Server = Server()
Devin Lim58046fa2017-07-05 16:55:00 -070091
92 # load some variables from the params file
93 cellName = main.params[ 'ENV' ][ 'cellName' ]
94 main.apps = main.params[ 'ENV' ][ 'appString' ]
Devin Lim142b5342017-07-20 15:22:39 -070095 stepResult = main.testSetUp.envSetup()
Jon Hall9ebd1bd2016-04-19 01:37:17 -070096 except Exception as e:
Devin Lim58046fa2017-07-05 16:55:00 -070097 main.testSetUp.envSetupException( e )
98 main.testSetUp.evnSetupConclusion( stepResult )
99 main.HA.generateGraph( "HAscaling", index=1 )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700100
Devin Lim142b5342017-07-20 15:22:39 -0700101 main.testSetUp.ONOSSetUp( main.Mininet1, main.Cluster, cellName=cellName, removeLog=True,
102 extraApply=[ main.HA.setServerForCluster,
103 main.HA.scalingMetadata,
104 main.HA.startingMininet,
105 main.HA.copyingBackupConfig ],
Devin Lim58046fa2017-07-05 16:55:00 -0700106 extraClean=main.HA.cleanUpOnosService,
107 installMax=True )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700108
Devin Lim58046fa2017-07-05 16:55:00 -0700109 main.HA.initialSetUp( True )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700110
111 def CASE2( self, main ):
112 """
113 Assign devices to controllers
114 """
Devin Lim58046fa2017-07-05 16:55:00 -0700115 main.HA.assignDevices( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700116
117 def CASE21( self, main ):
118 """
119 Assign mastership to controllers
120 """
Devin Lim58046fa2017-07-05 16:55:00 -0700121 main.HA.assignMastership( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700122
123 def CASE3( self, main ):
124 """
125 Assign intents
126 """
Devin Lim58046fa2017-07-05 16:55:00 -0700127 main.HA.assignIntents( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700128
129 def CASE4( self, main ):
130 """
131 Ping across added host intents
132 """
Jon Hallca319892017-06-15 15:25:22 -0700133 main.HA.pingAcrossHostIntent( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700134
135 def CASE5( self, main ):
136 """
137 Reading state of ONOS
138 """
Devin Lim58046fa2017-07-05 16:55:00 -0700139 main.HA.readingState( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700140
141 def CASE6( self, main ):
142 """
143 The Scaling case.
144 """
145 import time
146 import re
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700147 assert main, "main not defined"
148 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700149 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700150 main.HAlabels
151 except ( NameError, AttributeError ):
152 main.log.error( "main.HAlabels not defined, setting to []" )
153 main.HAlabels = []
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700154 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700155 main.HAdata
156 except ( NameError, AttributeError ):
157 main.log.error( "main.HAdata not defined, setting to []" )
158 main.HAdata = []
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700159
Jon Hall69b2b982016-05-11 12:04:59 -0700160 main.case( "Scale the number of nodes in the ONOS cluster" )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700161
162 main.step( "Checking ONOS Logs for errors" )
Devin Lim142b5342017-07-20 15:22:39 -0700163 for ctrl in main.Cluster.active():
164 main.log.debug( "Checking logs for errors on " + ctrl.name + ":" )
165 main.log.warn( main.ONOSbench.checkLogs( ctrl.ipAddress ) )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700166
167 """
168 pop # of nodes from a list, might look like 1,3b,3,5b,5,7b,7,7b,5,5b,3...
169 modify cluster.json file appropriately
170 install/deactivate node as needed
171 """
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700172 try:
Devin Lim142b5342017-07-20 15:22:39 -0700173 prevNodes = main.Cluster.active()
Jon Hallf37d44d2017-05-24 10:37:30 -0700174 scale = main.scaling.pop( 0 )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700175 if "e" in scale:
176 equal = True
177 else:
178 equal = False
Devin Lim142b5342017-07-20 15:22:39 -0700179 main.Cluster.setRunningNode( int( re.search( "\d+", scale ).group( 0 ) ) )
180 main.log.info( "Scaling to {} nodes".format( main.Cluster.numCtrls ) )
181 genResult = main.Server.generateFile( main.Cluster.numCtrls, equal=equal )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700182 utilities.assert_equals( expect=main.TRUE, actual=genResult,
183 onpass="New cluster metadata file generated",
184 onfail="Failled to generate new metadata file" )
185 time.sleep( 5 ) # Give time for nodes to read new file
186 except IndexError:
187 main.cleanup()
188 main.exit()
189
Devin Lim142b5342017-07-20 15:22:39 -0700190 activeNodes = [ i for i in range( 0, main.Cluster.numCtrls ) ]
191 newNodes = [ x for x in activeNodes if x not in prevNodes ]
192 main.Cluster.resetActive()
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700193 main.step( "Start new nodes" ) # OR stop old nodes?
194 started = main.TRUE
195 for i in newNodes:
Devin Lim142b5342017-07-20 15:22:39 -0700196 started = main.ONOSbench.onosStart( main.Cluster.runningNodes[ i ].ipAddress ) and main.TRUE
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700197 utilities.assert_equals( expect=main.TRUE, actual=started,
198 onpass="ONOS started",
199 onfail="ONOS start NOT successful" )
200
Devin Lim142b5342017-07-20 15:22:39 -0700201 main.testSetUp.setupSsh( main.Cluster )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700202
Devin Lim142b5342017-07-20 15:22:39 -0700203 main.testSetUp.checkOnosService( main.Cluster )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700204
Devin Lim142b5342017-07-20 15:22:39 -0700205 main.Cluster.startCLIs()
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700206
207 main.step( "Checking ONOS nodes" )
208 nodeResults = utilities.retry( main.HA.nodesCheck,
209 False,
Devin Lim142b5342017-07-20 15:22:39 -0700210 args=[ main.Cluster.active() ],
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700211 attempts=5 )
212 utilities.assert_equals( expect=True, actual=nodeResults,
213 onpass="Nodes check successful",
214 onfail="Nodes check NOT successful" )
215
216 for i in range( 10 ):
217 ready = True
Devin Lim142b5342017-07-20 15:22:39 -0700218 for ctrl in main.Cluster.active():
219 output = ctrl.CLI.summary()
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700220 if not output:
221 ready = False
222 if ready:
223 break
224 time.sleep( 30 )
225 utilities.assert_equals( expect=True, actual=ready,
226 onpass="ONOS summary command succeded",
227 onfail="ONOS summary command failed" )
228 if not ready:
229 main.cleanup()
230 main.exit()
231
232 # Rerun for election on new nodes
233 runResults = main.TRUE
Devin Lim142b5342017-07-20 15:22:39 -0700234 for ctrl in main.Cluster.active():
235 run = ctrl.CLI.electionTestRun()
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700236 if run != main.TRUE:
Devin Lim142b5342017-07-20 15:22:39 -0700237 main.log.error( "Error running for election on " + ctrl.name )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700238 runResults = runResults and run
239 utilities.assert_equals( expect=main.TRUE, actual=runResults,
240 onpass="Reran for election",
241 onfail="Failed to rerun for election" )
242
243 # TODO: Make this configurable
244 time.sleep( 60 )
Devin Lim142b5342017-07-20 15:22:39 -0700245 main.HA.commonChecks()
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700246
247 def CASE7( self, main ):
248 """
249 Check state after ONOS scaling
250 """
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700251
Devin Lim142b5342017-07-20 15:22:39 -0700252 main.HA.checkStateAfterEvent( main, afterWhich=1 )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700253
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700254 main.step( "Leadership Election is still functional" )
255 # Test of LeadershipElection
256 leaderList = []
257 leaderResult = main.TRUE
258
Devin Lim142b5342017-07-20 15:22:39 -0700259 for ctrl in main.Cluster.active():
260 leaderN = ctrl.CLI.electionTestLeader()
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700261 leaderList.append( leaderN )
262 if leaderN == main.FALSE:
263 # error in response
264 main.log.error( "Something is wrong with " +
265 "electionTestLeader function, check the" +
266 " error logs" )
267 leaderResult = main.FALSE
268 elif leaderN is None:
269 main.log.error( cli.name +
270 " shows no leader for the election-app." )
271 leaderResult = main.FALSE
272 if len( set( leaderList ) ) != 1:
273 leaderResult = main.FALSE
274 main.log.error(
275 "Inconsistent view of leader for the election test app" )
276 # TODO: print the list
277 utilities.assert_equals(
278 expect=main.TRUE,
279 actual=leaderResult,
280 onpass="Leadership election passed",
281 onfail="Something went wrong with Leadership election" )
282
283 def CASE8( self, main ):
284 """
285 Compare topo
286 """
Devin Lim58046fa2017-07-05 16:55:00 -0700287 main.HA.compareTopo( main )
Jon Halld2871c22016-07-26 11:01:14 -0700288
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700289 def CASE9( self, main ):
290 """
291 Link s3-s28 down
292 """
Devin Lim58046fa2017-07-05 16:55:00 -0700293 main.HA.linkDown( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700294
295 def CASE10( self, main ):
296 """
297 Link s3-s28 up
298 """
Devin Lim58046fa2017-07-05 16:55:00 -0700299 main.HA.linkUp( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700300
301 def CASE11( self, main ):
302 """
303 Switch Down
304 """
305 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700306 main.HA.switchDown( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700307
308 def CASE12( self, main ):
309 """
310 Switch Up
311 """
312 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700313 main.HA.switchUp( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700314
315 def CASE13( self, main ):
316 """
317 Clean up
318 """
Devin Lim58046fa2017-07-05 16:55:00 -0700319 main.HA.cleanUp( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700320
321 main.step( "Stopping webserver" )
Jon Hallf37d44d2017-05-24 10:37:30 -0700322 status = main.Server.stop()
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700323 utilities.assert_equals( expect=main.TRUE, actual=status,
324 onpass="Stop Server",
325 onfail="Failled to stop SimpleHTTPServer" )
326 del main.Server
327
328 def CASE14( self, main ):
329 """
330 start election app on all onos nodes
331 """
Devin Lim58046fa2017-07-05 16:55:00 -0700332 main.HA.startElectionApp( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700333
334 def CASE15( self, main ):
335 """
336 Check that Leadership Election is still functional
337 15.1 Run election on each node
338 15.2 Check that each node has the same leaders and candidates
339 15.3 Find current leader and withdraw
340 15.4 Check that a new node was elected leader
341 15.5 Check that that new leader was the candidate of old leader
342 15.6 Run for election on old leader
343 15.7 Check that oldLeader is a candidate, and leader if only 1 node
344 15.8 Make sure that the old leader was added to the candidate list
345
346 old and new variable prefixes refer to data from before vs after
347 withdrawl and later before withdrawl vs after re-election
348 """
Devin Lim58046fa2017-07-05 16:55:00 -0700349 main.HA.isElectionFunctional( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700350
351 def CASE16( self, main ):
352 """
353 Install Distributed Primitives app
354 """
Devin Lim58046fa2017-07-05 16:55:00 -0700355 main.HA.installDistributedPrimitiveApp( main )
Jon Hall9ebd1bd2016-04-19 01:37:17 -0700356
357 def CASE17( self, main ):
358 """
359 Check for basic functionality with distributed primitives
360 """
Devin Lim58046fa2017-07-05 16:55:00 -0700361 main.HA.checkDistPrimitivesFunc( main )