blob: 10e8fdcde8e8b228dc77fa51dff35b71b893bde5 [file] [log] [blame]
Jon Halla478b852017-12-04 15:00:15 -08001"""
2Copyright 2015 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"""
23Description: 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 HAupgrade:
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 main.log.info( "ONOS HA test: Stop a minority of ONOS nodes - " +
71 "initialization" )
72 # These are for csv plotting in jenkins
73 main.HAlabels = []
74 main.HAdata = []
75 try:
76 from tests.dependencies.ONOSSetup import ONOSSetup
77 main.testSetUp = ONOSSetup()
78 except ImportError:
79 main.log.error( "ONOSSetup not found. exiting the test" )
80 main.cleanAndExit()
81 main.testSetUp.envSetupDescription()
82 try:
83 from tests.HA.dependencies.HA import HA
84 main.HA = HA()
85 cellName = main.params[ 'ENV' ][ 'cellName' ]
86 main.apps = main.params[ 'ENV' ][ 'appString' ]
87 stepResult = main.testSetUp.envSetup()
88 except Exception as e:
89 main.testSetUp.envSetupException( e )
90 main.testSetUp.evnSetupConclusion( stepResult )
91 main.HA.generateGraph( "HAupgrade" )
92
93 main.testSetUp.ONOSSetUp( main.Mininet1, main.Cluster, cellName=cellName, removeLog=True,
94 extraApply=[ main.HA.startingMininet,
95 main.HA.copyBackupConfig ],
96 extraClean=main.HA.cleanUpGenPartition )
97
98 main.HA.initialSetUp( serviceClean=True )
99
100 def CASE2( self, main ):
101 """
102 Assign devices to controllers
103 """
104 main.HA.assignDevices( main )
105
106 def CASE21( self, main ):
107 """
108 Assign mastership to controllers
109 """
110 main.HA.assignMastership( main )
111
112 def CASE3( self, main ):
113 """
114 Assign intents
115 """
116 main.HA.assignIntents( main )
117
118 def CASE4( self, main ):
119 """
120 Ping across added host intents
121 """
122 main.HA.pingAcrossHostIntent( main )
123
124 def CASE5( self, main ):
125 """
126 Reading state of ONOS
127 """
128 main.HA.readingState( main )
129
130 def CASE60( self, main ):
131 """
132 Initialize the upgrade.
133 """
134 assert main, "main not defined"
135 assert utilities.assert_equals, "utilities.assert_equals not defined"
136 main.case( "Initialize upgrade" )
137 main.HA.upgradeInit( main )
138
139 def CASE61( self, main ):
140 """
141 Upgrade a minority of nodes PHASE 1
142 """
143 assert main, "main not defined"
144 assert utilities.assert_equals, "utilities.assert_equals not defined"
145 main.case( "Upgrade minority of ONOS nodes" )
146
147 main.step( "Checking ONOS Logs for errors" )
148 for ctrl in main.Cluster.active():
149 main.log.debug( "Checking logs for errors on " + ctrl.name + ":" )
150 main.log.warn( ctrl.checkLogs( ctrl.ipAddress ) )
151
152 main.kill = []
153 n = len( main.Cluster.runningNodes ) # Number of nodes
154 p = n / 2 # Number of nodes in the minority
155 for i in range( p ):
156 main.kill.append( main.Cluster.runningNodes[ i ] ) # ONOS node to kill, listed by index in main.nodes
157 main.HA.upgradeNodes( main )
158
159 main.step( "Checking ONOS nodes" )
160 nodeResults = utilities.retry( main.Cluster.nodesCheck,
161 False,
162 sleep=15,
163 attempts=5 )
164 utilities.assert_equals( expect=True, actual=nodeResults,
165 onpass="Nodes check successful",
166 onfail="Nodes check NOT successful" )
167
168 if not nodeResults:
169 for ctrl in main.Cluster.active():
170 main.log.debug( "{} components not ACTIVE: \n{}".format(
171 ctrl.name,
172 ctrl.CLI.sendline( "scr:list | grep -v ACTIVE" ) ) )
173 main.log.error( "Failed to start ONOS, stopping test" )
174 main.cleanAndExit()
175
176 def CASE62( self, main ):
177 """
178 Transfer to new version. PHASE 2
179 """
180 assert main, "main not defined"
181 assert utilities.assert_equals, "utilities.assert_equals not defined"
182 main.case( "Start the upgrade" )
183
184 main.step( "Send the command to switch to new version" )
185 ctrl = main.Cluster.next().CLI
186 upgraded = ctrl.issuUpgrade()
187 utilities.assert_equals( expect=main.TRUE, actual=upgraded,
188 onpass="Cluster has moved to the upgraded nodes",
189 onfail="Error transitioning to the upgraded nodes" )
190
191 main.step( "Check the status of the upgrade" )
192 ctrl = main.Cluster.next().CLI
193 status = ctrl.issu()
194 main.log.debug( status )
195 # TODO: check things here?
196
197 main.step( "Checking ONOS nodes" )
198 nodeResults = utilities.retry( main.Cluster.nodesCheck,
199 False,
200 sleep=15,
201 attempts=5 )
202 utilities.assert_equals( expect=True, actual=nodeResults,
203 onpass="Nodes check successful",
204 onfail="Nodes check NOT successful" )
205
206 def CASE63( self, main ):
207 """
208 Upgrade the rest of the nodes
209 """
210 main.case( "Upgrade remaining nodes" )
211 upgraded = main.kill
212 main.kill = []
213 for node in main.Cluster.runningNodes:
214 if node not in upgraded:
215 main.kill.append( node )
216
217 main.HA.upgradeNodes( main )
218
219 def CASE64( self, main ):
220 """
221 Commit to the upgrade.
222 """
223 assert main, "main not defined"
224 assert utilities.assert_equals, "utilities.assert_equals not defined"
225 main.case( "Commit upgrade" )
226
227 main.step( "Send the command to commit the upgrade" )
228 ctrl = main.Cluster.next().CLI
229 committed = ctrl.issuCommit()
230 utilities.assert_equals( expect=main.TRUE, actual=committed,
231 onpass="Upgrade has been committed",
232 onfail="Error committing the upgrade" )
233
234 main.step( "Check the status of the upgrade" )
235 ctrl = main.Cluster.next().CLI
236 status = ctrl.issu()
237 main.log.debug( status )
238 # TODO: check things here?
239
240 def CASE7( self, main ):
241 """
242 Check state after ONOS failure
243 """
244 try:
245 main.kill
246 except AttributeError:
247 main.kill = []
248
249 main.HA.checkStateAfterEvent( main, afterWhich=0 )
250 main.step( "Leadership Election is still functional" )
251 # Test of LeadershipElection
252 leaderList = []
253
254 restarted = []
255 for ctrl in main.kill:
256 restarted.append( ctrl.ipAddress )
257 leaderResult = main.TRUE
258
259 for ctrl in main.Cluster.active():
260 leaderN = ctrl.electionTestLeader()
261 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( ctrl.name +
270 " shows no leader for the election-app was" +
271 " elected after the old one died" )
272 leaderResult = main.FALSE
273 elif leaderN in restarted:
274 main.log.error( ctrl.name + " shows " + str( leaderN ) +
275 " as leader for the election-app, but it " +
276 "was restarted" )
277 leaderResult = main.FALSE
278 if len( set( leaderList ) ) != 1:
279 leaderResult = main.FALSE
280 main.log.error(
281 "Inconsistent view of leader for the election test app" )
282 # TODO: print the list
283 utilities.assert_equals(
284 expect=main.TRUE,
285 actual=leaderResult,
286 onpass="Leadership election passed",
287 onfail="Something went wrong with Leadership election" )
288
289 def CASE8( self, main ):
290 """
291 Compare topo
292 """
293 main.HA.compareTopo( main )
294
295 def CASE9( self, main ):
296 """
297 Link s3-s28 down
298 """
299 main.HA.linkDown( main )
300
301 def CASE10( self, main ):
302 """
303 Link s3-s28 up
304 """
305 main.HA.linkUp( main )
306
307 def CASE11( self, main ):
308 """
309 Switch Down
310 """
311 # NOTE: You should probably run a topology check after this
312 main.HA.switchDown( main )
313
314 def CASE12( self, main ):
315 """
316 Switch Up
317 """
318 # NOTE: You should probably run a topology check after this
319 main.HA.switchUp( main )
320
321 def CASE13( self, main ):
322 """
323 Clean up
324 """
325 main.HAlabels.append( "Restart" )
326 main.HAdata.append( str( main.restartTime ) )
327 main.HA.cleanUp( main )
328
329 def CASE14( self, main ):
330 """
331 start election app on all onos nodes
332 """
333 main.HA.startElectionApp( main )
334
335 def CASE15( self, main ):
336 """
337 Check that Leadership Election is still functional
338 15.1 Run election on each node
339 15.2 Check that each node has the same leaders and candidates
340 15.3 Find current leader and withdraw
341 15.4 Check that a new node was elected leader
342 15.5 Check that that new leader was the candidate of old leader
343 15.6 Run for election on old leader
344 15.7 Check that oldLeader is a candidate, and leader if only 1 node
345 15.8 Make sure that the old leader was added to the candidate list
346
347 old and new variable prefixes refer to data from before vs after
348 withdrawl and later before withdrawl vs after re-election
349 """
350 main.HA.isElectionFunctional( main )
351
352 def CASE16( self, main ):
353 """
354 Install Distributed Primitives app
355 """
356 main.HA.installDistributedPrimitiveApp( main )
357
358 def CASE17( self, main ):
359 """
360 Check for basic functionality with distributed primitives
361 """
362 main.HA.checkDistPrimitivesFunc( main )