blob: 5e9d2bcf8cb802eb36b042f13fff3b006cafb067 [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:
77 main.log.error( "ONOSSetup not found exiting the test" )
78 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' ]
86 stepResult = main.testSetUp.envSetup()
87 except Exception as e:
88 main.testSetUp.envSetupException( e )
89 main.testSetUp.evnSetupConclusion( stepResult )
90
91 main.testSetUp.ONOSSetUp( main.Cluster, cellName=cellName, removeLog=True,
92 extraApply=main.HA.startingMininet )
93
94 main.HA.initialSetUp()
95
96 def CASE2( self, main ):
97 """
98 Assign devices to controllers
99 """
100 main.HA.assignDevices( main )
101
102 def CASE21( self, main ):
103 """
104 Assign mastership to controllers
105 """
106 main.HA.assignMastership( main )
107
108 def CASE3( self, main ):
109 """
110 Assign intents
111 """
112 main.HA.assignIntents( main )
113
114 def CASE4( self, main ):
115 """
116 Ping across added host intents
117 """
118 main.HA.pingAcrossHostIntent( main )
119
120 def CASE5( self, main ):
121 """
122 Reading state of ONOS
123 """
124 main.HA.readingState( main )
125
126 def CASE6( self, main ):
127 """
128 The Failure case.
129 """
130 import time
131 assert main, "main not defined"
132 assert utilities.assert_equals, "utilities.assert_equals not defined"
133 try:
134 main.HAlabels
135 except ( NameError, AttributeError ):
136 main.log.error( "main.HAlabels not defined, setting to []" )
137 main.HAlabels = []
138 try:
139 main.HAdata
140 except ( NameError, AttributeError ):
141 main.log.error( "main.HAdata not defined, setting to []" )
142 main.HAdata = []
143
144 main.case( "Restart entire ONOS cluster with backed up state" )
145
146 main.step( "Backup ONOS data" )
147 location = "/tmp/" + main.TEST + ".tar.gz"
148 backupResult = main.HA.backupData( main, location )
149 utilities.assert_equals( expect=True, actual=backupResult,
150 onpass="ONOS backup succeded",
151 onfail="ONOS backup failed" )
152
153 main.step( "Checking ONOS Logs for errors" )
154 for ctrl in main.Cluster.active():
155 main.log.debug( "Checking logs for errors on " + ctrl.name + ":" )
156 main.log.warn( main.ONOSbench.checkLogs( ctrl.ipAddress ) )
157
158 killTime = time.time()
159 main.testSetUp.uninstallOnos( main.Cluster, uninstallMax=True )
160
161 clusterSize = len( main.Cluster.active() )
162 main.Cluster.setRunningNode( 0 ) # So we can install without starting ONOS
163 main.testSetUp.installOnos( main.Cluster, installMax=True )
164 main.Cluster.setRunningNode( clusterSize )
165
166 main.step( "Restore ONOS data" )
167 restoreResult = main.HA.restoreData( main, location )
168 utilities.assert_equals( expect=True, actual=restoreResult,
169 onpass="ONOS restore succeded",
170 onfail="ONOS restore failed" )
171
172 main.step( "Restart ONOS nodes" )
173 started = main.Cluster.command( "onosStart",
174 args=[ "ipAddress" ],
175 getFrom=0,
176 funcFromCtrl=True )
177 for ctrl in main.Cluster.controllers:
178 ctrl.active = True
179 main.log.debug( repr( ctrl ) )
180
181 main.testSetUp.setupSsh( main.Cluster )
182 main.testSetUp.checkOnosService( main.Cluster )
183 main.testSetUp.startOnosClis( main.Cluster )
184
185 ready = utilities.retry( main.Cluster.command,
186 False,
187 kwargs={ "function": "summary", "contentCheck": True },
188 sleep=30,
189 attempts=10 )
190 utilities.assert_equals( expect=True, actual=ready,
191 onpass="ONOS summary command succeded",
192 onfail="ONOS summary command failed" )
193 if not ready:
194 main.cleanAndExit()
195
196 # Grab the time of restart so we chan check how long the gossip
197 # protocol has had time to work
198 main.restartTime = time.time() - killTime
199 main.log.debug( "Restart time: " + str( main.restartTime ) )
200 main.HAlabels.append( "Restart" )
201 main.HAdata.append( str( main.restartTime ) )
202
203 # Rerun for election on restarted nodes
204 runResults = main.Cluster.command( "electionTestRun", returnBool=True )
205 utilities.assert_equals( expect=True, actual=runResults,
206 onpass="Reran for election",
207 onfail="Failed to rerun for election" )
208
209 main.HA.commonChecks()
210
211 def CASE7( self, main ):
212 """
213 Check state after ONOS failure
214 """
215 # NOTE: Store has no durability, so intents are lost across system
216 # restarts
217 main.HA.checkStateAfterEvent( main, afterWhich=0, isRestart=True )
218
219 main.step( "Leadership Election is still functional" )
220 # Test of LeadershipElection
221 leaderList = []
222 leaderResult = main.TRUE
223
224 for ctrl in main.Cluster.active():
225 ctrl.CLI.electionTestLeader()
226 leaderN = ctrl.CLI.electionTestLeader()
227 leaderList.append( leaderN )
228 if leaderN == main.FALSE:
229 # error in response
230 main.log.error( "Something is wrong with " +
231 "electionTestLeader function, check the" +
232 " error logs" )
233 leaderResult = main.FALSE
234 elif leaderN is None:
235 main.log.error( ctrl.name +
236 " shows no leader for the election-app." )
237 leaderResult = main.FALSE
238 if len( set( leaderList ) ) != 1:
239 leaderResult = main.FALSE
240 main.log.error(
241 "Inconsistent view of leader for the election test app" )
242 # TODO: print the list
243 utilities.assert_equals(
244 expect=main.TRUE,
245 actual=leaderResult,
246 onpass="Leadership election passed",
247 onfail="Something went wrong with Leadership election" )
248
249 def CASE8( self, main ):
250 """
251 Compare topo
252 """
253 main.HA.compareTopo( main )
254
255 def CASE9( self, main ):
256 """
257 Link s3-s28 down
258 """
259 main.HA.linkDown( main )
260
261 def CASE10( self, main ):
262 """
263 Link s3-s28 up
264 """
265 main.HA.linkUp( main )
266
267 def CASE11( self, main ):
268 """
269 Switch Down
270 """
271 # NOTE: You should probably run a topology check after this
272 main.HA.switchDown( main )
273
274 def CASE12( self, main ):
275 """
276 Switch Up
277 """
278 # NOTE: You should probably run a topology check after this
279 main.HA.switchUp( main )
280
281 def CASE13( self, main ):
282 """
283 Clean up
284 """
285 main.HA.cleanUp( main )
286
287 def CASE14( self, main ):
288 """
289 start election app on all onos nodes
290 """
291 try:
292 main.HA.startElectionApp( main )
293 except Exception as e:
294 main.log.error( e )
295
296 def CASE15( self, main ):
297 """
298 Check that Leadership Election is still functional
299 15.1 Run election on each node
300 15.2 Check that each node has the same leaders and candidates
301 15.3 Find current leader and withdraw
302 15.4 Check that a new node was elected leader
303 15.5 Check that that new leader was the candidate of old leader
304 15.6 Run for election on old leader
305 15.7 Check that oldLeader is a candidate, and leader if only 1 node
306 15.8 Make sure that the old leader was added to the candidate list
307
308 old and new variable prefixes refer to data from before vs after
309 withdrawl and later before withdrawl vs after re-election
310 """
311 main.HA.isElectionFunctional( main )
312
313 def CASE16( self, main ):
314 """
315 Install Distributed Primitives app
316 """
317 main.HA.installDistributedPrimitiveApp( main )
318
319 def CASE17( self, main ):
320 """
321 Check for basic functionality with distributed primitives
322 """
323 main.HA.checkDistPrimitivesFunc( main )