blob: 149007983ff7e13e1677e45b52ed2ad5d3e05fcc [file] [log] [blame]
Jon Hall43060f62020-06-23 13:13:33 -07001#!/usr/bin/env python
2"""
3Copyright 2020 Open Networking Foundation (ONF)
4
5Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
6the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
7or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
8
9TestON is free software: you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation, either version 2 of the License, or
12( at your option ) any later version.
13
14TestON is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with TestON. If not, see <http://www.gnu.org/licenses/>.
21"""
22
23import pexpect
24import types
25import os
26from drivers.common.clidriver import CLI
27
28class StratumOSSwitchDriver( CLI ):
29
30 def __init__( self ):
31 """
32 Initialize client
33 """
34 super( CLI, self ).__init__()
35 self.name = None
36 self.shortName = None
37 self.handle = None
38 self.prompt = "~(/TestON)?#"
39 self.dockerPrompt = "/run/stratum#"
40
41 self.home = "/root"
42 # Local home for functions using scp
43 self.tempDirectory = "/tmp/"
44 self.ports = []
45 self.isup = True
46
47 def connect( self, **connectargs ):
48 """
49 Creates ssh handle for cli.
50 """
51 try:
52 # Parse keys in xml object
53 for key in connectargs:
54 vars( self )[ key ] = connectargs[ key ]
55 # Get the name
56 self.name = self.options[ 'name' ]
57 self.shortName = self.options[ 'shortName' ]
58 # Parse the IP address
59 try:
60 if os.getenv( str( self.ip_address ) ) is not None:
61 self.ip_address = os.getenv( str( self.ip_address ) )
62 # Otherwise is an ip address
63 else:
64 main.log.info( self.name + ": Trying to connect to " + self.ip_address )
65 # Error handling
66 except KeyError:
67 main.log.info( "Invalid host name," + " connecting to local host instead" )
68 self.ip_address = 'localhost'
69 except Exception as inst:
70 main.log.error( "Uncaught exception: " + str( inst ) )
71 self.handle = super( StratumOSSwitchDriver, self ).connect(
72 user_name=self.user_name,
73 ip_address=self.ip_address,
74 port=None,
75 pwd=self.pwd)
76 # Successful connection
77 if self.handle:
78 main.log.info( "Connection successful to the host " + self.user_name + "@" + self.ip_address )
79 self.handle.sendline( "" )
80 self.handle.expect( self.prompt )
81 return main.TRUE
82 # Connection failed
83 else:
84 main.log.error( "Connection failed to the host " + self.user_name + "@" + self.ip_address )
85 main.log.error( "Failed to connect to the Stratum Switch" )
86 return main.FALSE
87 # Error handling
88 except TypeError:
89 main.log.exception( self.name + ": Object not as expected" )
90 return None
91 except pexpect.EOF:
92 main.log.error( self.name + ": EOF exception found" )
93 main.log.error( self.name + ": " + self.handle.before )
94 main.cleanup()
95 main.exit()
96 except Exception:
97 main.log.exception( self.name + ": Uncaught exception!" )
98 main.cleanup()
99 main.exit()
100
101 def disconnect( self ):
102 """
103 Called when Test is complete to disconnect the component handle.
104 """
105 response = main.TRUE
106 try:
107 if self.handle:
108 # Stop the agent
Jon Hall627b1572020-12-01 12:01:15 -0800109 if not main.persistentSetup:
110 self.stopSwitchAgent()
111 main.log.debug( self.name + ": Disconnected" )
Jon Hall43060f62020-06-23 13:13:33 -0700112 # Disconnect from the device
113 self.handle.sendline( "" )
114 self.handle.expect( self.prompt )
115 self.handle.sendline( "exit" )
116 self.handle.expect( "closed" )
117 # Errors handling
118 except pexpect.TIMEOUT:
119 main.log.error( self.name + ": pexpect.TIMEOUT found" )
120 main.log.debug( self.handle.before )
121 return main.FALSE
122 except TypeError:
123 main.log.exception( self.name + ": Object not as expected" )
124 response = main.FALSE
125 except pexpect.EOF:
126 main.log.error( self.name + ": EOF exception found" )
127 main.log.error( self.name + ": " + self.handle.before )
128 except ValueError:
129 main.log.exception( "Exception in disconnect of " + self.name )
130 response = main.TRUE
131 except Exception:
132 main.log.exception( self.name + ": Connection failed to the host" )
133 response = main.FALSE
134 return response
135
136 def assignSwController( self, ip, updateConf=True, **kwargs ):
137 """
138 Description:
139 Edit the config file for the switch and upload it to the onos
140 controller to connect the switch and controller
141
142 NOTE that this function is available on all switch drivers,
143 and the name is a hold over from ovs switches.
144 kwargs contains any arguments for other types of switches
145 Required:
146 ip - Ip addresses of controllers. This can be a list or a string.
147 updateConf - whether to pull and update configurations and scripts
148 Return:
149 Returns main.TRUE if the switch is correctly assigned to controllers,
150 otherwise it will return main.FALSE or an appropriate exception(s)
151 """
152 assignResult = main.TRUE
153 onosIp = ""
154 # Parses the controller option
155 # We only need one onos ip
156 try:
157 if isinstance( ip, types.StringType ):
158 onosIp = str( ip )
159 elif isinstance( ip, types.ListType ):
160 onosIp = ip[ 0 ]
161 else:
162 main.log.error( self.name + ": Invalid controller ip address" )
163 return main.FALSE
164 if updateConf:
165 self.setupContainer()
166 main.ONOSbench.onosNetCfg( onosIp, self.options[ 'onosConfigPath' ], self.options[ 'onosConfigFile' ] )
167
168 assignResult = self.startSwitchAgent()
169 if not assignResult:
170 self.isup = False
171 else:
172 self.isup = True
173 # Done return true
174 return assignResult
175 # Errors handling
176 except pexpect.TIMEOUT:
177 main.log.error( self.name + ": pexpect.TIMEOUT found" )
178 return main.FALSE
179 except pexpect.EOF:
180 main.log.error( self.name + ": EOF exception found" )
181 main.log.error( self.name + ": " + self.handle.before )
182 main.cleanAndExit()
183 except Exception:
184 main.log.exception( self.name + ": Uncaught exception!" )
185 main.cleanAndExit()
186
187 def setupContainer( self ):
188 """
189 Prepare for the container to be run. Includes pulling scripts
190 and modifying them
191 """
192 try:
193 #TODO Remove hardcoding
194 main.log.info( "Creating working directory" )
195 self.handle.sendline( "mkdir TestON" )
196 self.handle.expect( self.prompt )
197 self.handle.sendline( "cd TestON" )
198 self.handle.expect( self.prompt )
199
200 main.log.info( "Getting start container script" )
201 # TODO: Parameterize this
202 self.handle.sendline( "wget --backups=1 https://raw.githubusercontent.com/stratum/stratum/master/stratum/hal/bin/barefoot/docker/start-stratum-container.sh" )
203 self.handle.expect( self.prompt )
204 main.log.info( "Modify start container script" )
205 self.handle.sendline( "sed -i '/--privileged/a \ --name stratum \\\\' start-stratum-container.sh" )
206 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -0700207 # TODO: Add docker pull command to the start-stratum-container.sh script
208
209 main.log.info( "Getting chassis config" )
210 # TODO: Parameterize this
Jon Hall39570262020-11-17 12:18:19 -0800211 filename = "~/TestON/tests/USECASE/SegmentRouting/dependencies/chassis_config.pb.txt.qa"
212 main.ONOSbench.secureCopy( self.user_name, self.ip_address, filename, "~/TestON/chassis_config.pb.txt", pwd=self.pwd, direction="to" )
Jon Hall43060f62020-06-23 13:13:33 -0700213 main.log.info( "Modify chassis config" )
214 # TODO: Parameterize this
Jon Hall43060f62020-06-23 13:13:33 -0700215 self.handle.sendline( "export CHASSIS_CONFIG=~/TestON/chassis_config.pb.txt" )
216 self.handle.expect( self.prompt )
Jon Hall39570262020-11-17 12:18:19 -0800217 #self.handle.sendline( "export DOCKER_IMAGE=registry.aetherproject.org/tost/stratum-bfrt" )
218 self.handle.sendline( "export DOCKER_IMAGE=stratumproject/stratum-bf" )
219 self.handle.expect( self.prompt )
220 self.handle.sendline( "export DOCKER_IMAGE_TAG=9.2.0" )
221 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -0700222 self.handle.sendline( "chmod +x start-stratum-container.sh" )
223 self.handle.expect( self.prompt )
224 except pexpect.TIMEOUT:
225 main.log.error( self.name + ": pexpect.TIMEOUT found" )
226 main.log.debug( self.handle.before )
227 return main.FALSE
228 except pexpect.EOF:
229 main.log.error( self.name + ": EOF exception found" )
230 main.log.error( self.name + ": " + self.handle.before )
231 main.cleanAndExit()
232 except Exception:
233 main.log.exception( self.name + ": Uncaught exception!" )
234 main.cleanAndExit()
235
236 def startSwitchAgent( self ):
237 """
238 Start the stratum agent on the device
239 """
240 try:
241 main.log.info( "Starting switch agent" )
Jon Hall39570262020-11-17 12:18:19 -0800242 self.handle.sendline( "./start-stratum-container.sh --bf-sim --bf-switchd-background=false" )
Jon Hall43060f62020-06-23 13:13:33 -0700243 self.handle.expect( "Chassis config pushed successfully." )
244 return main.TRUE
245 except pexpect.TIMEOUT:
246 main.log.error( self.name + ": pexpect.TIMEOUT found" )
247 main.log.debug( self.handle.before )
248 return main.FALSE
249 except pexpect.EOF:
250 main.log.error( self.name + ": EOF exception found" )
251 main.log.error( self.name + ": " + self.handle.before )
252 main.cleanAndExit()
253 except Exception:
254 main.log.exception( self.name + ": Uncaught exception!" )
255 main.cleanAndExit()
256
257 def stopSwitchAgent( self ):
258 """
259 Stop the strratum agent on the device
260 """
261 try:
262 main.log.info( self.name + ": stopping Stratum Switch agent" )
263 while True:
264 self.handle.sendline( "" )
265 i = self.handle.expect( [ self.prompt, self.dockerPrompt, pexpect.TIMEOUT, "Aborted at" ] )
266 if i == 2:
267 self.handle.send( "\x03" ) # ctrl-c to close switch agent
268 self.handle.sendline( "" )
269 elif i == 1:
270 self.handle.sendline( "exit" ) # exit docker
271 self.handle.expect( self.prompt )
272 elif i == 0:
273 self.handle.sendline( "docker stop stratum" ) # Make sure the container is stopped
274 self.handle.expect( self.prompt )
275 main.log.debug( self.name + ": Stratum Switch agent stopped" )
276 return
277 elif i == 3:
278 main.log.error( "Stratum agent aborted" )
279 # TODO: Find and save any extra logs
280 output = self.handle.before + self.handle.after
281 self.handle.sendline( "" )
282 self.handle.expect( self.prompt )
283 output += self.handle.before + self.handle.after
284 main.log.debug( output )
285 main.cleanAndExit()
286 except pexpect.TIMEOUT:
287 main.log.error( self.name + ": pexpect.TIMEOUT found" )
288 main.log.debug( self.handle.before )
289 return main.FALSE
290 except pexpect.EOF:
291 main.log.error( self.name + ": EOF exception found" )
292 main.log.error( self.name + ": " + self.handle.before )
293 main.cleanAndExit()
294 except Exception:
295 main.log.exception( self.name + ": Uncaught exception!" )
296 main.cleanAndExit()