blob: 10b5152bd58d9681c58c3fb9151efd7ac3dccd5c [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
kelvin8ec71442015-01-15 16:57:00 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 24-Oct-2012
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004Copyright 2012 Open Networking Foundation (ONF)
kelvin8ec71442015-01-15 16:57:00 -08005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
10 TestON is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo82705492017-10-18 14:19:55 -070013 (at your option) any later version.
adminbae64d82013-08-01 10:50:15 -070014
15 TestON is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
kelvin8ec71442015-01-15 16:57:00 -080021 along with TestON. If not, see <http://www.gnu.org/licenses/>.
kelvin8ec71442015-01-15 16:57:00 -080022"""
adminbae64d82013-08-01 10:50:15 -070023import pexpect
kelvin8ec71442015-01-15 16:57:00 -080024import re
adminbae64d82013-08-01 10:50:15 -070025
26from drivers.component import Component
kelvin8ec71442015-01-15 16:57:00 -080027
28
29class CLI( Component ):
30
31 """
adminbae64d82013-08-01 10:50:15 -070032 This will define common functions for CLI included.
kelvin8ec71442015-01-15 16:57:00 -080033 """
34 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070035 super( CLI, self ).__init__()
Jon Hallca319892017-06-15 15:25:22 -070036
Jeremy Ronquillo82705492017-10-18 14:19:55 -070037 def checkPrompt( self ):
Devin Limdc78e202017-06-09 18:30:07 -070038 for key in self.options:
Jeremy Ronquillo82705492017-10-18 14:19:55 -070039 if key == "prompt" and self.options[ 'prompt' ] is not None:
40 self.prompt = self.options[ 'prompt' ]
Devin Limdc78e202017-06-09 18:30:07 -070041 break
kelvin8ec71442015-01-15 16:57:00 -080042
43 def connect( self, **connectargs ):
44 """
adminbae64d82013-08-01 10:50:15 -070045 Connection will establish to the remote host using ssh.
46 It will take user_name ,ip_address and password as arguments<br>
kelvin8ec71442015-01-15 16:57:00 -080047 and will return the handle.
48 """
adminbae64d82013-08-01 10:50:15 -070049 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080050 vars( self )[ key ] = connectargs[ key ]
Devin Limdc78e202017-06-09 18:30:07 -070051 self.checkPrompt()
adminbae64d82013-08-01 10:50:15 -070052
kelvin8ec71442015-01-15 16:57:00 -080053 connect_result = super( CLI, self ).connect()
adminbae64d82013-08-01 10:50:15 -070054 ssh_newkey = 'Are you sure you want to continue connecting'
kelvin8ec71442015-01-15 16:57:00 -080055 refused = "ssh: connect to host " + \
56 self.ip_address + " port 22: Connection refused"
adminbae64d82013-08-01 10:50:15 -070057 if self.port:
kelvin8ec71442015-01-15 16:57:00 -080058 self.handle = pexpect.spawn(
Jon Hall7a5e0a22017-12-11 10:35:50 -080059 'ssh -X -p ' +
kelvin8ec71442015-01-15 16:57:00 -080060 self.port +
61 ' ' +
62 self.user_name +
63 '@' +
Jon Hall7a5e0a22017-12-11 10:35:50 -080064 self.ip_address +
65 ' -o ServerAliveInterval=120 -o TCPKeepAlive=yes',
Jon Hall9aaba882015-01-19 15:05:15 -080066 env={ "TERM": "xterm-mono" },
Jon Hall7a5e0a22017-12-11 10:35:50 -080067 maxread=1000000 )
kelvin8ec71442015-01-15 16:57:00 -080068 else:
69 self.handle = pexpect.spawn(
70 'ssh -X ' +
71 self.user_name +
72 '@' +
Jon Hall7a5e0a22017-12-11 10:35:50 -080073 self.ip_address +
74 ' -o ServerAliveInterval=120 -o TCPKeepAlive=yes',
Jon Hall9aaba882015-01-19 15:05:15 -080075 env={ "TERM": "xterm-mono" },
kelvin8ec71442015-01-15 16:57:00 -080076 maxread=1000000,
77 timeout=60 )
adminbae64d82013-08-01 10:50:15 -070078
Jon Hall73057ee2016-08-23 09:57:26 -070079 # set tty window size
80 self.handle.setwinsize( 24, 250 )
81
adminbae64d82013-08-01 10:50:15 -070082 self.handle.logfile = self.logfile_handler
kelvin8ec71442015-01-15 16:57:00 -080083 i = 5
84 while i == 5:
Jon Hall4173b242017-09-12 17:04:38 -070085 i = self.handle.expect( [ ssh_newkey,
86 'password:|Password:',
87 pexpect.EOF,
88 pexpect.TIMEOUT,
89 refused,
90 'teston>',
91 self.prompt ],
92 120 )
acsmars32de0bc2015-06-30 09:57:12 -070093 if i == 0: # Accept key, then expect either a password prompt or access
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.info( "ssh key confirmation received, send yes" )
95 self.handle.sendline( 'yes' )
acsmars32de0bc2015-06-30 09:57:12 -070096 i = 5 # Run the loop again
acsmars07f9d392015-07-15 10:30:58 -070097 continue
98 if i == 1: # Password required
Jon Hall63604932015-02-26 17:09:50 -080099 if self.pwd:
100 main.log.info(
Jon Hall4173b242017-09-12 17:04:38 -0700101 "ssh connection asked for password, gave password" )
Jon Hall63604932015-02-26 17:09:50 -0800102 else:
acsmars07f9d392015-07-15 10:30:58 -0700103 main.log.info( "Server asked for password, but none was "
104 "given in the .topo file. Trying "
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700105 "no password." )
acsmars07f9d392015-07-15 10:30:58 -0700106 self.pwd = ""
107 self.handle.sendline( self.pwd )
108 j = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700109 self.prompt,
acsmars07f9d392015-07-15 10:30:58 -0700110 'password:|Password:',
111 pexpect.EOF,
112 pexpect.TIMEOUT ],
113 120 )
114 if j != 0:
115 main.log.error( "Incorrect Password" )
116 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800117 elif i == 2:
118 main.log.error( "Connection timeout" )
119 return main.FALSE
120 elif i == 3: # timeout
121 main.log.error(
122 "No route to the Host " +
123 self.user_name +
124 "@" +
125 self.ip_address )
126 return main.FALSE
127 elif i == 4:
128 main.log.error(
129 "ssh: connect to host " +
130 self.ip_address +
131 " port 22: Connection refused" )
132 return main.FALSE
133 elif i == 6:
134 main.log.info( "Password not required logged in" )
adminbae64d82013-08-01 10:50:15 -0700135
kelvin8ec71442015-01-15 16:57:00 -0800136 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700137 self.handle.expect( self.prompt )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -0700138 self.handle.sendline( "cd" )
139 self.handle.expect( self.prompt )
adminbae64d82013-08-01 10:50:15 -0700140 return self.handle
141
kelvin8ec71442015-01-15 16:57:00 -0800142 def disconnect( self ):
143 result = super( CLI, self ).disconnect( self )
adminbae64d82013-08-01 10:50:15 -0700144 result = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800145 # self.execute( cmd="exit",timeout=120,prompt="(.*)" )
146
147 def execute( self, **execparams ):
148 """
adminbae64d82013-08-01 10:50:15 -0700149 It facilitates the command line execution of a given command. It has arguments as :
150 cmd => represents command to be executed,
151 prompt => represents expect command prompt or output,
152 timeout => timeout for command execution,
153 more => to provide a key press if it is on.
154
155 It will return output of command exection.
kelvin8ec71442015-01-15 16:57:00 -0800156 """
157 result = super( CLI, self ).execute( self )
adminaef00552014-05-08 09:18:36 -0700158 defaultPrompt = '.*[$>\#]'
Jon Hall3b489db2015-10-05 14:38:37 -0700159 args = utilities.parse_args( [ "CMD",
160 "TIMEOUT",
161 "PROMPT",
162 "MORE" ],
163 **execparams )
kelvin8ec71442015-01-15 16:57:00 -0800164
165 expectPrompt = args[ "PROMPT" ] if args[ "PROMPT" ] else defaultPrompt
adminbae64d82013-08-01 10:50:15 -0700166 self.LASTRSP = ""
kelvin8ec71442015-01-15 16:57:00 -0800167 timeoutVar = args[ "TIMEOUT" ] if args[ "TIMEOUT" ] else 10
adminbae64d82013-08-01 10:50:15 -0700168 cmd = ''
kelvin8ec71442015-01-15 16:57:00 -0800169 if args[ "CMD" ]:
170 cmd = args[ "CMD" ]
171 else:
adminbae64d82013-08-01 10:50:15 -0700172 return 0
kelvin8ec71442015-01-15 16:57:00 -0800173 if args[ "MORE" ] is None:
174 args[ "MORE" ] = " "
175 self.handle.sendline( cmd )
adminbae64d82013-08-01 10:50:15 -0700176 self.lastCommand = cmd
Jon Hall3b489db2015-10-05 14:38:37 -0700177 index = self.handle.expect( [ expectPrompt,
178 "--More--",
179 'Command not found.',
180 pexpect.TIMEOUT,
181 "^:$" ],
182 timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700183 if index == 0:
kelvin8ec71442015-01-15 16:57:00 -0800184 self.LASTRSP = self.LASTRSP + \
185 self.handle.before + self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700186 main.log.info( "Executed :" + str( cmd ) +
187 " \t\t Expected Prompt '" + str( expectPrompt ) +
Jon Hall3b489db2015-10-05 14:38:37 -0700188 "' Found" )
adminbae64d82013-08-01 10:50:15 -0700189 elif index == 1:
190 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800191 self.handle.send( args[ "MORE" ] )
192 main.log.info(
193 "Found More screen to go , Sending a key to proceed" )
194 indexMore = self.handle.expect(
195 [ "--More--", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700196 while indexMore == 0:
kelvin8ec71442015-01-15 16:57:00 -0800197 main.log.info(
198 "Found anoother More screen to go , Sending a key to proceed" )
199 self.handle.send( args[ "MORE" ] )
200 indexMore = self.handle.expect(
201 [ "--More--", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700202 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800203 elif index == 2:
204 main.log.error( "Command not found" )
adminbae64d82013-08-01 10:50:15 -0700205 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800206 elif index == 3:
Jon Hall3b489db2015-10-05 14:38:37 -0700207 main.log.error( "Expected Prompt not found, Time Out!!" )
kelvin8ec71442015-01-15 16:57:00 -0800208 main.log.error( expectPrompt )
Jon Hall3b489db2015-10-05 14:38:37 -0700209 self.LASTRSP = self.LASTRSP + self.handle.before
210 return self.LASTRSP
adminbae64d82013-08-01 10:50:15 -0700211 elif index == 4:
212 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800213 # self.handle.send( args[ "MORE" ] )
214 self.handle.sendcontrol( "D" )
215 main.log.info(
Jon Hall3b489db2015-10-05 14:38:37 -0700216 "Found More screen to go, Sending a key to proceed" )
kelvin8ec71442015-01-15 16:57:00 -0800217 indexMore = self.handle.expect(
218 [ "^:$", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700219 while indexMore == 0:
kelvin8ec71442015-01-15 16:57:00 -0800220 main.log.info(
Jon Hall3b489db2015-10-05 14:38:37 -0700221 "Found another More screen to go, Sending a key to proceed" )
kelvin8ec71442015-01-15 16:57:00 -0800222 self.handle.sendcontrol( "D" )
223 indexMore = self.handle.expect(
224 [ "^:$", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700225 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800226 main.last_response = self.remove_contol_chars( self.LASTRSP )
adminbae64d82013-08-01 10:50:15 -0700227 return self.LASTRSP
kelvin8ec71442015-01-15 16:57:00 -0800228
229 def remove_contol_chars( self, response ):
230 # RE_XML_ILLEGAL = '([\u0000-\u0008\u000b-\u000c\u000e-\u001f\ufffe-\uffff])|([%s-%s][^%s-%s])|([^%s-%s][%s-%s])|([%s-%s]$)|(^[%s-%s])'%( unichr( 0xd800 ),unichr( 0xdbff ),unichr( 0xdc00 ),unichr( 0xdfff ),unichr( 0xd800 ),unichr( 0xdbff ),unichr( 0xdc00 ),unichr( 0xdfff ),unichr( 0xd800 ),unichr( 0xdbff ),unichr( 0xdc00 ),unichr( 0xdfff ) )
231 # response = re.sub( RE_XML_ILLEGAL, "\n", response )
232 response = re.sub( r"[\x01-\x1F\x7F]", "", response )
233 # response = re.sub( r"\[\d+\;1H", "\n", response )
234 response = re.sub( r"\[\d+\;\d+H", "", response )
adminbae64d82013-08-01 10:50:15 -0700235 return response
adminbae64d82013-08-01 10:50:15 -0700236
kelvin8ec71442015-01-15 16:57:00 -0800237 def runAsSudoUser( self, handle, pwd, default ):
238
239 i = handle.expect( [ ".ssword:*", default, pexpect.EOF ] )
240 if i == 0:
241 handle.sendline( pwd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -0700242 handle.sendline( "\n" )
kelvin8ec71442015-01-15 16:57:00 -0800243
244 if i == 1:
245 handle.expect( default )
246
247 if i == 2:
248 main.log.error( "Unable to run as Sudo user" )
249
adminbae64d82013-08-01 10:50:15 -0700250 return handle
adminbae64d82013-08-01 10:50:15 -0700251
kelvin8ec71442015-01-15 16:57:00 -0800252 def onfail( self ):
253 if 'onfail' in main.componentDictionary[ self.name ]:
254 commandList = main.componentDictionary[
255 self.name ][ 'onfail' ].split( "," )
256 for command in commandList:
257 response = self.execute(
258 cmd=command,
259 prompt="(.*)",
260 timeout=120 )
adminbae64d82013-08-01 10:50:15 -0700261
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700262 def secureCopy( self, userName, ipAddress, filePath, dstPath, pwd="",
263 direction="from" ):
kelvin8ec71442015-01-15 16:57:00 -0800264 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700265 Definition:
266 Execute scp command in linux to copy to/from a remote host
267 Required:
268 str userName - User name of the remote host
269 str ipAddress - IP address of the remote host
270 str filePath - File path including the file it self
271 str dstPath - Destination path
272 Optional:
273 str pwd - Password of the host
274 str direction - Direction of the scp, default to "from" which means
275 copy "from" the remote machine to local machine,
276 while "to" means copy "to" the remote machine from
277 local machine
kelvin8ec71442015-01-15 16:57:00 -0800278 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700279 returnVal = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700280 ssh_newkey = 'Are you sure you want to continue connecting'
kelvin8ec71442015-01-15 16:57:00 -0800281 refused = "ssh: connect to host " + \
Jon Hall547e0582015-09-21 17:35:40 -0700282 ipAddress + " port 22: Connection refused"
acsmars07f9d392015-07-15 10:30:58 -0700283
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700284 if direction == "from":
285 cmd = 'scp ' + str( userName ) + '@' + str( ipAddress ) + ':' + \
Jon Hall547e0582015-09-21 17:35:40 -0700286 str( filePath ) + ' ' + str( dstPath )
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700287 elif direction == "to":
288 cmd = 'scp ' + str( filePath ) + ' ' + str( userName ) + \
Jon Hall547e0582015-09-21 17:35:40 -0700289 '@' + str( ipAddress ) + ':' + str( dstPath )
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700290 else:
291 main.log.debug( "Wrong direction using secure copy command!" )
292 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800293
294 main.log.info( "Sending: " + cmd )
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700295 self.handle.sendline( cmd )
Jon Hall547e0582015-09-21 17:35:40 -0700296 i = 0
297 while i < 2:
298 i = self.handle.expect( [
299 ssh_newkey,
300 'password:',
301 "100%",
302 refused,
303 "No such file or directory",
Jon Hall53c5e662016-04-13 16:06:56 -0700304 "Permission denied",
Devin Limdc78e202017-06-09 18:30:07 -0700305 self.prompt,
Jon Hall547e0582015-09-21 17:35:40 -0700306 pexpect.EOF,
307 pexpect.TIMEOUT ],
308 120 )
Jon Hall547e0582015-09-21 17:35:40 -0700309 if i == 0: # ask for ssh key confirmation
310 main.log.info( "ssh key confirmation received, sending yes" )
311 self.handle.sendline( 'yes' )
312 elif i == 1: # Asked for ssh password
313 main.log.info( "ssh connection asked for password, gave password" )
314 self.handle.sendline( pwd )
315 elif i == 2: # File finished transfering
316 main.log.info( "Secure copy successful" )
317 returnVal = main.TRUE
318 elif i == 3: # Connection refused
319 main.log.error(
320 "ssh: connect to host " +
321 ipAddress +
322 " port 22: Connection refused" )
323 returnVal = main.FALSE
324 elif i == 4: # File Not found
325 main.log.error( "No such file found" )
326 returnVal = main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700327 elif i == 5: # Permission denied
328 main.log.error( "Permission denied. Check folder permissions" )
329 returnVal = main.FALSE
330 elif i == 6: # prompt returned
Jon Hall4173b242017-09-12 17:04:38 -0700331 return returnVal
Jon Hall53c5e662016-04-13 16:06:56 -0700332 elif i == 7: # EOF
Jon Hall547e0582015-09-21 17:35:40 -0700333 main.log.error( "Pexpect.EOF found!!!" )
Devin Lim44075962017-08-11 10:56:37 -0700334 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700335 elif i == 8: # timeout
Jon Hall547e0582015-09-21 17:35:40 -0700336 main.log.error(
337 "No route to the Host " +
338 userName +
339 "@" +
340 ipAddress )
341 returnVal = main.FALSE
Devin Limdc78e202017-06-09 18:30:07 -0700342 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700343 return returnVal
344
345 def scp( self, remoteHost, filePath, dstPath, direction="from" ):
346 """
347 Definition:
348 Execute scp command in linux to copy to/from a remote host
349 Required:
350 * remoteHost - Test ON component to be parsed
351 str filePath - File path including the file it self
352 str dstPath - Destination path
353 Optional:
354 str direction - Direction of the scp, default to "from" which means
355 copy "from" the remote machine to local machine,
356 while "to" means copy "to" the remote machine from
357 local machine
358 """
359 return self.secureCopy( remoteHost.user_name,
360 remoteHost.ip_address,
361 filePath,
362 dstPath,
363 pwd=remoteHost.pwd,
364 direction=direction )
Devin Lim142b5342017-07-20 15:22:39 -0700365
366 def sshToNode( self, ipAddress, uName="sdn", pwd="rocks" ):
367 ssh_newkey = 'Are you sure you want to continue connecting'
368 refused = "ssh: connect to host " + ipAddress + " port 22: Connection refused"
369 handle = pexpect.spawn( 'ssh -X ' +
370 uName +
371 '@' +
372 ipAddress,
373 env={ "TERM": "xterm-mono" },
374 maxread=1000000,
375 timeout=60 )
376
377 # set tty window size
378 handle.setwinsize( 24, 250 )
379
380 i = 5
381 while i == 5:
Jon Hall4173b242017-09-12 17:04:38 -0700382 i = handle.expect( [ ssh_newkey,
383 'password:|Password:',
384 pexpect.EOF,
385 pexpect.TIMEOUT,
386 refused,
387 'teston>',
388 self.prompt ],
389 120 )
Devin Lim142b5342017-07-20 15:22:39 -0700390 if i == 0: # Accept key, then expect either a password prompt or access
391 main.log.info( "ssh key confirmation received, send yes" )
392 handle.sendline( 'yes' )
393 i = 5 # Run the loop again
394 continue
395 if i == 1: # Password required
396 if pwd:
397 main.log.info(
Jon Hall4173b242017-09-12 17:04:38 -0700398 "ssh connection asked for password, gave password" )
Devin Lim142b5342017-07-20 15:22:39 -0700399 else:
400 main.log.info( "Server asked for password, but none was "
401 "given in the .topo file. Trying "
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700402 "no password." )
Devin Lim142b5342017-07-20 15:22:39 -0700403 pwd = ""
404 handle.sendline( pwd )
405 j = handle.expect( [ self.prompt,
406 'password:|Password:',
407 pexpect.EOF,
408 pexpect.TIMEOUT ],
409 120 )
410 if j != 0:
411 main.log.error( "Incorrect Password" )
Devin Lim44075962017-08-11 10:56:37 -0700412 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -0700413 elif i == 2:
414 main.log.error( "Connection timeout" )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -0700416 elif i == 3: # timeout
417 main.log.error(
418 "No route to the Host " +
419 uName +
420 "@" +
421 ipAddress )
Devin Lim44075962017-08-11 10:56:37 -0700422 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -0700423 elif i == 4:
424 main.log.error(
425 "ssh: connect to host " +
426 ipAddress +
427 " port 22: Connection refused" )
Devin Lim44075962017-08-11 10:56:37 -0700428 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -0700429 elif i == 6:
430 main.log.info( "Password not required logged in" )
431
432 handle.sendline( "" )
433 handle.expect( self.prompt )
434 handle.sendline( "cd" )
435 handle.expect( self.prompt )
436
Jon Hall4173b242017-09-12 17:04:38 -0700437 main.log.info( "Successfully ssh to " + ipAddress + "." )
Devin Lim142b5342017-07-20 15:22:39 -0700438 return handle
439
440 def exitFromSsh( self, handle, ipAddress ):
Devin Lim142b5342017-07-20 15:22:39 -0700441 try:
Jon Hall4f360bc2017-09-07 10:19:52 -0700442 handle.sendline( "logout" )
Devin Lim142b5342017-07-20 15:22:39 -0700443 handle.expect( "closed." )
Jon Hall4173b242017-09-12 17:04:38 -0700444 main.log.info( "Successfully closed ssh connection from " + ipAddress )
Devin Lim142b5342017-07-20 15:22:39 -0700445 except pexpect.EOF:
446 main.log.error( "Failed to close the connection from " + ipAddress )
Jon Hall4f360bc2017-09-07 10:19:52 -0700447 try:
448 # check that this component handle still works
449 self.handle.sendline( "" )
450 self.handle.expect( self.prompt )
451 except pexpect.EOF:
452 main.log.error( self.handle.before )
453 main.log.error( "EOF after closing ssh connection" )
Jon Hall4173b242017-09-12 17:04:38 -0700454
455 def folderSize( self, path, size='10', unit='M', ignoreRoot=True ):
456 """
457 Run `du -h` on the folder path and verifies the folder(s) size is
458 less than the given size. Note that if multiple subdirectories are
459 present, the result will be the OR of all the individual subdirectories.
460
461 Arguments:
462 path - A string containing the path supplied to the du command
463 size - The number portion of the file size that the results will be compared to
464 unit - The unit portion of the file size that the results will be compared to
465 ignoreRoot - If True, will ignore the "root" of the path supplied to du. I.E. will ignore `.`
466
467 Returns True if the folder(s) size(s) are less than SIZE UNITS, else returns False
468 """
469 sizeRe = r'(?P<number>\d+\.*\d*)(?P<unit>\D)'
470 unitsList = [ 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ]
471 try:
472 # make sure we convert units if size is too big
473 size = float( size )
474 if size >= 1000:
475 size = size / 1000
476 unit = unitsList[ unitsList.index( unit + 1 ) ]
477 cmdStr = "du -h " + path
478 self.handle.sendline( cmdStr )
479 self.handle.expect( self.prompt )
480 output = self.handle.before
481 assert "cannot access" not in output
482 assert "command not found" not in output
483 main.log.debug( output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700484 lines = [ line for line in output.split( '\r\n' ) ]
Jon Hall4173b242017-09-12 17:04:38 -0700485 retValue = True
486 if ignoreRoot:
487 lastIndex = -2
488 else:
489 lastIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700490 for line in lines[ 1:lastIndex ]:
Jon Hall4173b242017-09-12 17:04:38 -0700491 parsed = line.split()
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700492 sizeMatch = parsed[ 0 ]
493 folder = parsed[ 1 ]
Jon Hall4173b242017-09-12 17:04:38 -0700494 match = re.search( sizeRe, sizeMatch )
495 num = match.group( 'number' )
496 unitMatch = match.group( 'unit' )
497 if unitsList.index( unitMatch ) < unitsList.index( unit ):
498 retValue &= True
499 elif unitsList.index( unitMatch ) == unitsList.index( unit ):
500 if float( num ) < float( size ):
501 retValue &= True
502 else:
503 retValue &= False
504 elif unitsList.index( unitMatch ) > unitsList.index( unit ):
505 retValue &= False
506 return retValue
507 except AssertionError:
508 main.log.error( self.name + ": Could not execute command: " + output )
509 return False
510 except pexpect.TIMEOUT:
511 main.log.exception( self.name + ": TIMEOUT exception found" )
512 main.log.error( self.name + ": " + self.handle.before )
513 return False
514 except pexpect.EOF:
515 main.log.error( self.name + ": EOF exception found" )
516 main.log.error( self.name + ": " + self.handle.before )
517 main.cleanAndExit()