blob: c5dc29ac19c21089fb218af0ec476a823e03d3aa [file] [log] [blame]
Jon Hallb5488012017-06-21 14:08:36 -07001"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07002Copyright 2017 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 Hallb5488012017-06-21 14:08:36 -070023Description: This test is to determine if ONOS can handle
24 a minority of it's nodes restarting
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
33CASE61: The Failure inducing case.
34CASE62: The Failure recovery 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"""
47class HAcontinuousStopNodes:
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 """
70 import imp
71 import pexpect
72 import time
73 import json
74 main.log.info( "ONOS HA test: Stop a minority of ONOS nodes - " +
75 "initialization" )
Jon Hallb5488012017-06-21 14:08:36 -070076 # set global variables
Jon Hallb5488012017-06-21 14:08:36 -070077 # These are for csv plotting in jenkins
Devin Lim58046fa2017-07-05 16:55:00 -070078 main.HAlabels = []
79 main.HAdata = []
80 try:
81 from tests.dependencies.ONOSSetup import ONOSSetup
82 main.testSetUp = ONOSSetup()
83 except ImportError:
84 main.log.error( "ONOSSetup not found. exiting the test" )
85 main.exit()
86 main.testSetUp.envSetupDescription()
Jon Hallb5488012017-06-21 14:08:36 -070087 try:
88 from tests.HA.dependencies.HA import HA
89 main.HA = HA()
Devin Lim58046fa2017-07-05 16:55:00 -070090 # load some variables from the params file
91 cellName = main.params[ 'ENV' ][ 'cellName' ]
92 main.apps = main.params[ 'ENV' ][ 'appString' ]
93 main.numCtrls = int( main.params[ 'num_controllers' ] )
94 if main.ONOSbench.maxNodes and\
95 main.ONOSbench.maxNodes < main.numCtrls:
96 main.numCtrls = int( main.ONOSbench.maxNodes )
97 main.maxNodes = main.numCtrls
98 stepResult = main.testSetUp.envSetup( hasNode=True )
Jon Hallb5488012017-06-21 14:08:36 -070099 except Exception as e:
Devin Lim58046fa2017-07-05 16:55:00 -0700100 main.testSetUp.envSetupException( e )
101 main.testSetUp.evnSetupConclusion( stepResult )
102 main.HA.generateGraph( "HAcontinuousStopNodes" )
Jon Hallb5488012017-06-21 14:08:36 -0700103
Devin Lim58046fa2017-07-05 16:55:00 -0700104 main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
105 extraApply=main.HA.customizeOnosGenPartitions,
106 extraClean=main.HA.cleanUpGenPartition )
Jon Hallb5488012017-06-21 14:08:36 -0700107
Devin Lim58046fa2017-07-05 16:55:00 -0700108 main.HA.initialSetUp()
Jon Hallb5488012017-06-21 14:08:36 -0700109
Jon Hallb5488012017-06-21 14:08:36 -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 Hallb5488012017-06-21 14:08:36 -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 Hallb5488012017-06-21 14:08:36 -0700122
123 def CASE3( self, main ):
124 """
125 Assign intents
126 """
Devin Lim58046fa2017-07-05 16:55:00 -0700127 main.HA.assignIntents( main )
Jon Hallb5488012017-06-21 14:08:36 -0700128
129 def CASE4( self, main ):
130 """
131 Ping across added host intents
132 """
Devin Lim58046fa2017-07-05 16:55:00 -0700133 main.HA.pingAcrossHostIntent( main, True, False )
Jon Hallb5488012017-06-21 14:08:36 -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 Hallb5488012017-06-21 14:08:36 -0700140
141 def CASE61( self, main ):
142 """
143 The Failure case.
144 """
145 assert main.numCtrls, "main.numCtrls not defined"
146 assert main, "main not defined"
147 assert utilities.assert_equals, "utilities.assert_equals not defined"
148 assert main.CLIs, "main.CLIs not defined"
149 assert main.nodes, "main.nodes not defined"
150 try:
151 assert main.nodeIndex is not None, "main.nodeIndex not defined"
152 assert main.killCount is not None, "main.killCount not defined"
153 except AttributeError as e:
154 main.log.warn( "Node to kill not selected, defaulting to node 1" )
155 main.nodeIndex = 0
156 main.killCount = 1
157
158 main.case( "Stopping ONOS nodes - iteration " + str( main.killCount ) )
159
160 main.step( "Checking ONOS Logs for errors" )
161 for node in main.nodes:
162 main.log.debug( "Checking logs for errors on " + node.name + ":" )
163 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
164
165 # NOTE: For now only kill one node. If we move to killing more, we need to
166 # make sure we don't lose any partitions
167 n = len( main.nodes ) # Number of nodes
168 main.nodeIndex = ( main.nodeIndex + 1 ) % n
169 main.kill = [ main.nodeIndex ] # ONOS node to kill, listed by index in main.nodes
170
171 # TODO: Be able to configure bringing up old node vs. a new/fresh installation
172 main.step( "Stopping " + str( len( main.kill ) ) + " ONOS nodes" )
173 killResults = main.TRUE
174 for i in main.kill:
175 killResults = killResults and\
176 main.ONOSbench.onosStop( main.nodes[ i ].ip_address )
177 main.activeNodes.remove( i )
178 utilities.assert_equals( expect=main.TRUE, actual=killResults,
179 onpass="ONOS nodes stopped successfully",
180 onfail="ONOS nodes NOT successfully stopped" )
181
182 main.step( "Checking ONOS nodes" )
183 nodeResults = utilities.retry( main.HA.nodesCheck,
184 False,
185 args=[ main.activeNodes ],
186 sleep=15,
187 attempts=5 )
188
189 utilities.assert_equals( expect=True, actual=nodeResults,
190 onpass="Nodes check successful",
191 onfail="Nodes check NOT successful" )
192
193 if not nodeResults:
194 for i in main.activeNodes:
195 cli = main.CLIs[ i ]
196 main.log.debug( "{} components not ACTIVE: \n{}".format(
197 cli.name,
198 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
199 main.log.error( "Failed to start ONOS, stopping test" )
200 main.cleanup()
201 main.exit()
202
203 main.killCount += 1
204
205 def CASE62( self, main ):
206 """
207 The bring up stopped nodes
208 """
Devin Lim58046fa2017-07-05 16:55:00 -0700209 main.HA.bringUpStoppedNode( main )
Jon Hallb5488012017-06-21 14:08:36 -0700210
211 def CASE7( self, main ):
212 """
213 Check state after ONOS failure
214 """
Jon Hallb5488012017-06-21 14:08:36 -0700215 try:
216 main.kill
217 except AttributeError:
218 main.kill = []
219
Devin Lim58046fa2017-07-05 16:55:00 -0700220 main.HA.checkStateAfterONOS( main, afterWhich=0 )
Jon Hallb5488012017-06-21 14:08:36 -0700221
Jon Hallb5488012017-06-21 14:08:36 -0700222 main.step( "Leadership Election is still functional" )
223 # Test of LeadershipElection
224 leaderList = []
225
226 restarted = []
227 for i in main.kill:
228 restarted.append( main.nodes[ i ].ip_address )
229 leaderResult = main.TRUE
230
231 for i in main.activeNodes:
232 cli = main.CLIs[ i ]
233 leaderN = cli.electionTestLeader()
234 leaderList.append( leaderN )
235 if leaderN == main.FALSE:
236 # error in response
237 main.log.error( "Something is wrong with " +
238 "electionTestLeader function, check the" +
239 " error logs" )
240 leaderResult = main.FALSE
241 elif leaderN is None:
242 main.log.error( cli.name +
243 " shows no leader for the election-app was" +
244 " elected after the old one died" )
245 leaderResult = main.FALSE
246 elif leaderN in restarted:
247 main.log.error( cli.name + " shows " + str( leaderN ) +
248 " as leader for the election-app, but it " +
249 "was restarted" )
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" )
255 # TODO: print the list
256 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 Hallb5488012017-06-21 14:08:36 -0700267
Jon Hallb5488012017-06-21 14:08:36 -0700268
Jon Hallb5488012017-06-21 14:08:36 -0700269
270 def CASE9( self, main ):
271 """
272 Link s3-s28 down
273 """
Devin Lim58046fa2017-07-05 16:55:00 -0700274 main.HA.linkDown( main )
Jon Hallb5488012017-06-21 14:08:36 -0700275
276 def CASE10( self, main ):
277 """
278 Link s3-s28 up
279 """
Devin Lim58046fa2017-07-05 16:55:00 -0700280 main.HA.linkUp( main )
Jon Hallb5488012017-06-21 14:08:36 -0700281
282 def CASE11( self, main ):
283 """
284 Switch Down
285 """
286 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700287 main.HA.switchDown( main )
Jon Hallb5488012017-06-21 14:08:36 -0700288
289 def CASE12( self, main ):
290 """
291 Switch Up
292 """
293 # NOTE: You should probably run a topology check after this
Devin Lim58046fa2017-07-05 16:55:00 -0700294 main.HA.switchUp( main )
Jon Hallb5488012017-06-21 14:08:36 -0700295
296 def CASE13( self, main ):
297 """
298 Clean up
299 """
Devin Lim58046fa2017-07-05 16:55:00 -0700300 main.HAlabels.append( "Restart" )
301 main.HAdata.append( str( main.restartTime ) )
302 main.HA.cleanUp( main )
Jon Hallb5488012017-06-21 14:08:36 -0700303
304 def CASE14( self, main ):
305 """
306 start election app on all onos nodes
307 """
Devin Lim58046fa2017-07-05 16:55:00 -0700308 main.HA.startElectionApp( main )
Jon Hallb5488012017-06-21 14:08:36 -0700309
310 def CASE15( self, main ):
311 """
312 Check that Leadership Election is still functional
313 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
324 """
Devin Lim58046fa2017-07-05 16:55:00 -0700325 main.HA.isElectionFunctional( main )
Jon Hallb5488012017-06-21 14:08:36 -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 Hallb5488012017-06-21 14:08:36 -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 )