blob: 05989fdabf92c5bfdd6dd171c2c7f35512836074 [file] [log] [blame]
Jon Hall69b2b982016-05-11 12:04:59 -07001"""
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002Copyright 2016 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 Hall69b2b982016-05-11 12:04:59 -070022Description: This test is to determine if ONOS can handle
23 dynamic swapping of cluster nodes.
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: Swap nodes
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 Hall69b2b982016-05-11 12:04:59 -070045class HAswapNodes:
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 """
Jon Hall69b2b982016-05-11 12:04:59 -070068 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
69 "initialization" )
Jon Hall69b2b982016-05-11 12:04:59 -070070 # set global variables
71 # These are for csv plotting in jenkins
Devin Lim58046fa2017-07-05 16:55:00 -070072 main.HAlabels = []
73 main.HAdata = []
74 try:
75 from tests.dependencies.ONOSSetup import ONOSSetup
76 main.testSetUp = ONOSSetup()
77 except ImportError:
78 main.log.error( "ONOSSetup not found. exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -070079 main.cleanAndExit()
Devin Lim58046fa2017-07-05 16:55:00 -070080 main.testSetUp.envSetupDescription()
Jon Hall69b2b982016-05-11 12:04:59 -070081 try:
82 from tests.HA.dependencies.HA import HA
83 main.HA = HA()
84 from tests.HA.HAswapNodes.dependencies.Server import Server
85 main.Server = Server()
Devin Lim58046fa2017-07-05 16:55:00 -070086 # load some variables from the params file
87 cellName = main.params[ 'ENV' ][ 'cellName' ]
88 main.apps = main.params[ 'ENV' ][ 'appString' ]
Devin Lim142b5342017-07-20 15:22:39 -070089 stepResult = main.testSetUp.envSetup()
Jon Hall69b2b982016-05-11 12:04:59 -070090 except Exception as e:
Devin Lim58046fa2017-07-05 16:55:00 -070091 main.testSetUp.envSetupException( e )
92 main.testSetUp.evnSetupConclusion( stepResult )
Jon Hall69b2b982016-05-11 12:04:59 -070093
You Wanga0f6ff62018-01-11 15:46:30 -080094 main.testSetUp.ONOSSetUp( main.Cluster, cellName=cellName, removeLog=True,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070095 extraApply=[ main.HA.setServerForCluster,
96 main.HA.swapNodeMetadata,
97 main.HA.startingMininet,
98 main.HA.copyBackupConfig,
99 main.HA.setMetadataUrl ],
100 extraClean=main.HA.cleanUpOnosService,
101 installMax=True )
Devin Lim58046fa2017-07-05 16:55:00 -0700102 main.HA.initialSetUp()
Jon Hall69b2b982016-05-11 12:04:59 -0700103
104 def CASE2( self, main ):
105 """
106 Assign devices to controllers
107 """
Devin Lim58046fa2017-07-05 16:55:00 -0700108 main.HA.assignDevices( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700109
110 def CASE21( self, main ):
111 """
112 Assign mastership to controllers
113 """
Devin Lim58046fa2017-07-05 16:55:00 -0700114 main.HA.assignMastership( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700115
116 def CASE3( self, main ):
117 """
118 Assign intents
119 """
Devin Lim58046fa2017-07-05 16:55:00 -0700120 main.HA.assignIntents( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700121
122 def CASE4( self, main ):
123 """
124 Ping across added host intents
125 """
Jon Hallca319892017-06-15 15:25:22 -0700126 main.HA.pingAcrossHostIntent( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700127
128 def CASE5( self, main ):
129 """
130 Reading state of ONOS
131 """
Devin Lim58046fa2017-07-05 16:55:00 -0700132 main.HA.readingState( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700133
134 def CASE6( self, main ):
135 """
136 The Scaling case.
137 """
138 import time
Jon Hall69b2b982016-05-11 12:04:59 -0700139 assert main, "main not defined"
140 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall69b2b982016-05-11 12:04:59 -0700141 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700142 main.HAlabels
143 except ( NameError, AttributeError ):
144 main.log.error( "main.HAlabels not defined, setting to []" )
145 main.HAlabels = []
Jon Hall69b2b982016-05-11 12:04:59 -0700146 try:
Devin Lim58046fa2017-07-05 16:55:00 -0700147 main.HAdata
148 except ( NameError, AttributeError ):
149 main.log.error( "main.HAdata not defined, setting to []" )
150 main.HAdata = []
Jon Hall69b2b982016-05-11 12:04:59 -0700151
152 main.case( "Swap some of the ONOS nodes" )
153
154 main.step( "Checking ONOS Logs for errors" )
Devin Lim142b5342017-07-20 15:22:39 -0700155 for ctrl in main.Cluster.active():
156 main.log.debug( "Checking logs for errors on " + ctrl.name + ":" )
157 main.log.warn( main.ONOSbench.checkLogs( ctrl.ipAddress ) )
Jon Hall69b2b982016-05-11 12:04:59 -0700158
Devin Lim142b5342017-07-20 15:22:39 -0700159 activeNodes = main.Cluster.getRunningPos()
160 # Todo : this could be wrong. need to double check.
Jon Hall69b2b982016-05-11 12:04:59 -0700161 main.step( "Generate new metadata file" )
Devin Lim142b5342017-07-20 15:22:39 -0700162 old = [ activeNodes[ 1 ], activeNodes[ -2 ] ]
163 new = range( main.Cluster.maxCtrls )[ -2: ]
Jon Hall69b2b982016-05-11 12:04:59 -0700164 assert len( old ) == len( new ), "Length of nodes to swap don't match"
165 handle = main.ONOSbench.handle
166 for x, y in zip( old, new ):
167 handle.sendline( "export OC{}=$OC{}".format( x + 1, y + 1 ) )
168 handle.expect( "\$" ) # from the variable
169 ret = handle.before
170 handle.expect( "\$" ) # From the prompt
171 ret += handle.before
172 main.log.debug( ret )
Devin Lim142b5342017-07-20 15:22:39 -0700173 activeNodes.remove( x )
174 activeNodes.append( y )
Jon Hall69b2b982016-05-11 12:04:59 -0700175
Devin Lim142b5342017-07-20 15:22:39 -0700176 genResult = main.Server.generateFile( main.Cluster.numCtrls )
Jon Hall69b2b982016-05-11 12:04:59 -0700177 utilities.assert_equals( expect=main.TRUE, actual=genResult,
178 onpass="New cluster metadata file generated",
179 onfail="Failled to generate new metadata file" )
180 time.sleep( 5 ) # Give time for nodes to read new file
Devin Lim142b5342017-07-20 15:22:39 -0700181 main.Cluster.resetActive()
182 # Note : done up to this point.
Jon Hall69b2b982016-05-11 12:04:59 -0700183 main.step( "Start new nodes" ) # OR stop old nodes?
184 started = main.TRUE
185 for i in new:
Devin Lim142b5342017-07-20 15:22:39 -0700186 started = main.ONOSbench.onosStart( main.Cluster.controllers[ i ].ipAddress ) and main.TRUE
Jon Hall69b2b982016-05-11 12:04:59 -0700187 utilities.assert_equals( expect=main.TRUE, actual=started,
188 onpass="ONOS started",
189 onfail="ONOS start NOT successful" )
190
Devin Lim142b5342017-07-20 15:22:39 -0700191 main.Cluster.setRunningNode( activeNodes )
Jon Hall69b2b982016-05-11 12:04:59 -0700192
Devin Lim142b5342017-07-20 15:22:39 -0700193 main.testSetUp.setupSsh( main.Cluster )
194 main.testSetUp.checkOnosService( main.Cluster )
Jon Hall69b2b982016-05-11 12:04:59 -0700195
Devin Lim142b5342017-07-20 15:22:39 -0700196 main.testSetUp.startOnosClis( main.Cluster )
Jon Hall69b2b982016-05-11 12:04:59 -0700197
198 main.step( "Checking ONOS nodes" )
Devin Lim3ebd5e72017-11-14 10:38:00 -0800199 nodeResults = utilities.retry( main.Cluster.nodesCheck,
Jon Hall69b2b982016-05-11 12:04:59 -0700200 False,
Jon Hall69b2b982016-05-11 12:04:59 -0700201 attempts=5 )
202 utilities.assert_equals( expect=True, actual=nodeResults,
203 onpass="Nodes check successful",
204 onfail="Nodes check NOT successful" )
205
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700206 ready = utilities.retry( main.Cluster.command,
Devin Lim142b5342017-07-20 15:22:39 -0700207 False,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700208 kwargs={ "function": "summary", "contentCheck": True },
Devin Lim142b5342017-07-20 15:22:39 -0700209 sleep=30,
210 attempts=10 )
Jon Hall69b2b982016-05-11 12:04:59 -0700211 utilities.assert_equals( expect=True, actual=ready,
212 onpass="ONOS summary command succeded",
213 onfail="ONOS summary command failed" )
214 if not ready:
Devin Lim44075962017-08-11 10:56:37 -0700215 main.cleanAndExit()
Jon Hall69b2b982016-05-11 12:04:59 -0700216
217 # Rerun for election on new nodes
218 runResults = main.TRUE
Devin Lim142b5342017-07-20 15:22:39 -0700219 for ctrl in main.Cluster.active():
220 run = ctrl.CLI.electionTestRun()
Jon Hall69b2b982016-05-11 12:04:59 -0700221 if run != main.TRUE:
Devin Lim142b5342017-07-20 15:22:39 -0700222 main.log.error( "Error running for election on " + ctrl.name )
Jon Hall69b2b982016-05-11 12:04:59 -0700223 runResults = runResults and run
224 utilities.assert_equals( expect=main.TRUE, actual=runResults,
225 onpass="Reran for election",
226 onfail="Failed to rerun for election" )
227
Devin Lim142b5342017-07-20 15:22:39 -0700228 main.HA.commonChecks()
229
Jon Hall69b2b982016-05-11 12:04:59 -0700230 def CASE7( self, main ):
231 """
232 Check state after ONOS scaling
233 """
Devin Lim142b5342017-07-20 15:22:39 -0700234 main.HA.checkStateAfterEvent( main, afterWhich=1 )
Jon Hall69b2b982016-05-11 12:04:59 -0700235
Jon Hall69b2b982016-05-11 12:04:59 -0700236 main.step( "Leadership Election is still functional" )
237 # Test of LeadershipElection
238 leaderList = []
239 leaderResult = main.TRUE
240
Devin Lim142b5342017-07-20 15:22:39 -0700241 for ctrl in main.Cluster.active():
242 leaderN = ctrl.CLI.electionTestLeader()
Jon Hall69b2b982016-05-11 12:04:59 -0700243 leaderList.append( leaderN )
244 if leaderN == main.FALSE:
245 # error in response
246 main.log.error( "Something is wrong with " +
247 "electionTestLeader function, check the" +
248 " error logs" )
249 leaderResult = main.FALSE
250 elif leaderN is None:
Devin Lim142b5342017-07-20 15:22:39 -0700251 main.log.error( ctrl.name +
Jon Hall69b2b982016-05-11 12:04:59 -0700252 " shows no leader for the election-app." )
253 leaderResult = main.FALSE
254 if len( set( leaderList ) ) != 1:
255 leaderResult = main.FALSE
256 main.log.error(
257 "Inconsistent view of leader for the election test app" )
258 # TODO: print the list
259 utilities.assert_equals(
260 expect=main.TRUE,
261 actual=leaderResult,
262 onpass="Leadership election passed",
263 onfail="Something went wrong with Leadership election" )
264
265 def CASE8( self, main ):
266 """
267 Compare topo
268 """
Devin Lim58046fa2017-07-05 16:55:00 -0700269 main.HA.compareTopo( main )
Jon Halld2871c22016-07-26 11:01:14 -0700270
Jon Hall69b2b982016-05-11 12:04:59 -0700271 def CASE9( self, main ):
272 """
273 Link s3-s28 down
274 """
Devin Lim58046fa2017-07-05 16:55:00 -0700275 main.HA.linkDown( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700276
277 def CASE10( self, main ):
278 """
279 Link s3-s28 up
280 """
Devin Lim58046fa2017-07-05 16:55:00 -0700281 main.HA.linkUp( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700282
283 def CASE11( self, main ):
284 """
285 Switch Down
286 """
287 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700288 main.HA.switchDown( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700289
290 def CASE12( self, main ):
291 """
292 Switch Up
293 """
294 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700295 main.HA.switchUp( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700296
297 def CASE13( self, main ):
298 """
299 Clean up
300 """
Devin Lim58046fa2017-07-05 16:55:00 -0700301 main.HA.cleanUp( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700302
303 main.step( "Stopping webserver" )
Jon Hallf37d44d2017-05-24 10:37:30 -0700304 status = main.Server.stop()
Jon Hall69b2b982016-05-11 12:04:59 -0700305 utilities.assert_equals( expect=main.TRUE, actual=status,
306 onpass="Stop Server",
307 onfail="Failled to stop SimpleHTTPServer" )
308 del main.Server
309
310 def CASE14( self, main ):
311 """
312 start election app on all onos nodes
313 """
Devin Lim58046fa2017-07-05 16:55:00 -0700314 main.HA.startElectionApp( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700315
316 def CASE15( self, main ):
317 """
318 Check that Leadership Election is still functional
319 15.1 Run election on each node
320 15.2 Check that each node has the same leaders and candidates
321 15.3 Find current leader and withdraw
322 15.4 Check that a new node was elected leader
323 15.5 Check that that new leader was the candidate of old leader
324 15.6 Run for election on old leader
325 15.7 Check that oldLeader is a candidate, and leader if only 1 node
326 15.8 Make sure that the old leader was added to the candidate list
327
328 old and new variable prefixes refer to data from before vs after
329 withdrawl and later before withdrawl vs after re-election
330 """
Devin Lim58046fa2017-07-05 16:55:00 -0700331 main.HA.isElectionFunctional( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700332
333 def CASE16( self, main ):
334 """
335 Install Distributed Primitives app
336 """
Devin Lim58046fa2017-07-05 16:55:00 -0700337 main.HA.installDistributedPrimitiveApp( main )
Jon Hall69b2b982016-05-11 12:04:59 -0700338
339 def CASE17( self, main ):
340 """
341 Check for basic functionality with distributed primitives
342 """
Devin Lim58046fa2017-07-05 16:55:00 -0700343 main.HA.checkDistPrimitivesFunc( main )