blob: 86c0c3825678489e1899d728712fc9003323375d [file] [log] [blame]
Pier6a0c4de2018-03-18 16:01:30 -07001#!/usr/bin/env python
2"""
3Copyright 2018 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 re
25import sys
26import types
27import os
28import time
29from math import pow
You Wang4cc61912018-08-28 10:10:58 -070030from drivers.common.cli.emulator.scapyclidriver import ScapyCliDriver
Pier6a0c4de2018-03-18 16:01:30 -070031
You Wang4cc61912018-08-28 10:10:58 -070032class HostDriver( ScapyCliDriver ):
Pier6a0c4de2018-03-18 16:01:30 -070033 """
34 This class is created as a standalone host driver.
35 """
36 def __init__( self ):
37 super( HostDriver, self ).__init__()
38 self.handle = self
39 self.name = None
40 self.shortName = None
41 self.home = None
You Wang4cc61912018-08-28 10:10:58 -070042 self.inband = False
43 self.prompt = "\$"
44 self.scapyPrompt = ">>>"
Pier6a0c4de2018-03-18 16:01:30 -070045
46 def connect( self, **connectargs ):
47 """
48 Creates ssh handle for host.
49 NOTE:
50 The ip_address would come from the topo file using the host tag, the
51 value can be an environment variable as well as a "localhost" to get
52 the ip address needed to ssh to the "bench"
53 """
54 try:
55 for key in connectargs:
56 vars( self )[ key ] = connectargs[ key ]
57 self.name = self.options[ 'name' ]
58 self.shortName = self.options[ 'shortName' ]
59
60 try:
61 if os.getenv( str( self.ip_address ) ) is not None:
62 self.ip_address = os.getenv( str( self.ip_address ) )
63 else:
64 main.log.info( self.name +
65 ": Trying to connect to " +
66 self.ip_address )
67 except KeyError:
68 main.log.info( "Invalid host name," +
69 " connecting to local host instead" )
70 self.ip_address = 'localhost'
71 except Exception as inst:
72 main.log.error( "Uncaught exception: " + str( inst ) )
73
74 self.handle = super(
75 HostDriver,
76 self ).connect(
77 user_name=self.user_name,
78 ip_address=self.ip_address,
79 port=None,
80 pwd=self.pwd )
81
82 if self.handle:
83 main.log.info( "Connection successful to the " +
84 self.user_name +
85 "@" +
86 self.ip_address )
87 self.handle.sendline( "" )
88 self.handle.expect( self.prompt )
89 return main.TRUE
90 else:
91 main.log.error( "Connection failed to " +
92 self.user_name +
93 "@" +
94 self.ip_address )
95 return main.FALSE
96 except pexpect.EOF:
97 main.log.error( self.name + ": EOF exception found" )
98 main.log.error( self.name + ": " + self.handle.before )
99 main.cleanAndExit()
100 except Exception:
101 main.log.exception( self.name + ": Uncaught exception!" )
102 main.cleanAndExit()
103
104 def disconnect( self, **connectargs ):
105 """
106 Called when test is complete to disconnect the handle.
107 """
108 response = main.TRUE
109 try:
110 if self.handle:
111 # Disconnect from the host
112 self.handle.sendline( "" )
113 self.handle.expect( self.prompt )
114 self.handle.sendline( "exit" )
115 i = self.handle.expect( [ "closed", pexpect.TIMEOUT ], timeout=2 )
116 if i == 1:
You Wang4cc61912018-08-28 10:10:58 -0700117 main.log.error( self.name + ": timeout when waiting for response" )
Pier6a0c4de2018-03-18 16:01:30 -0700118 main.log.error( "response: " + str( self.handle.before ) )
119 except TypeError:
120 main.log.exception( self.name + ": Object not as expected" )
121 response = main.FALSE
122 except pexpect.EOF:
123 main.log.error( self.name + ": EOF exception found" )
124 main.log.error( self.name + ": " + self.handle.before )
125 except ValueError:
126 main.log.exception( "Exception in disconnect of " + self.name )
127 response = main.TRUE
128 except Exception:
129 main.log.exception( self.name + ": Connection failed to the host" )
130 response = main.FALSE
131 return response
132
You Wang4cc61912018-08-28 10:10:58 -0700133 def connectInband( self ):
134 """
135 ssh to the host using its data plane IP
136 """
137 try:
138 if not self.options[ 'inband' ] == 'True':
139 main.log.info( "Skip connecting the host via data plane" )
140 return main.TRUE
141 self.handle.sendline( "" )
142 self.handle.expect( self.prompt )
143 self.handle.sendline( "ssh {}@{}".format( self.options[ 'username' ],
144 self.options[ 'ip' ] ) )
145 i = self.handle.expect( [ "password:|Password:", self.prompt, pexpect.TIMEOUT ], timeout=30 )
146 if i == 0:
147 self.handle.sendline( self.options[ 'password' ] )
148 j = self.handle.expect( [ "password:|Password:", self.prompt, pexpect.TIMEOUT ], timeout=10 )
149 if j != 1:
150 main.log.error( "Incorrect password" )
151 return main.FALSE
152 elif i == 1:
153 main.log.info( "Password not required logged in" )
154 else:
155 main.log.error( "Failed to connect to the host" )
156 return main.FALSE
157 self.inband = True
158 return main.TRUE
159 except KeyError:
160 main.log.error( self.name + ": host component not as expected" )
161 main.log.error( self.name + ": " + self.handle.before )
162 return main.FALSE
163 except pexpect.EOF:
164 main.log.error( self.name + ": EOF exception found" )
165 main.log.error( self.name + ": " + self.handle.before )
166 return main.FALSE
167 except Exception:
168 main.log.exception( self.name + ": Uncaught exception!" )
169 main.log.error( self.name + ": " + self.handle.before )
170 return main.FALSE
171
172 def disconnectInband( self ):
173 """
174 Terminate the ssh connection to the host's data plane IP
175 """
176 try:
177 if not self.options[ 'inband' ] == 'True':
178 main.log.info( "Skip disconnecting the host via data plane" )
179 return main.TRUE
180 self.handle.sendline( "" )
181 self.handle.expect( self.prompt )
182 self.handle.sendline( "exit" )
183 i = self.handle.expect( [ "closed", pexpect.TIMEOUT ], timeout=2 )
184 if i == 1:
185 main.log.error( self.name + ": timeout when waiting for response" )
186 main.log.error( "response: " + str( self.handle.before ) )
187 return main.TRUE
188 except pexpect.EOF:
189 main.log.error( self.name + ": EOF exception found" )
190 main.log.error( self.name + ": " + self.handle.before )
191 return main.FALSE
192 except Exception:
193 main.log.exception( self.name + ": Uncaught exception!" )
194 main.log.error( self.name + ": " + self.handle.before )
195 return main.FALSE
196
Pier6a0c4de2018-03-18 16:01:30 -0700197 def ping( self, dst, ipv6=False, wait=3 ):
198 """
199 Description:
200 Ping from this host to another
201 Required:
202 dst: IP address of destination host
203 Optional:
204 ipv6: will use ping6 command if True; otherwise use ping command
205 wait: timeout for ping command
206 """
207 try:
208 command = "ping6" if ipv6 else "ping"
209 command += " -c 1 -i 1 -W " + str( wait ) + " " + str( dst )
210 main.log.info( self.name + ": Sending: " + command )
211 self.handle.sendline( command )
212 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
Jon Halla604fd42018-05-04 14:27:27 -0700213 timeout=wait + 5 )
Pier6a0c4de2018-03-18 16:01:30 -0700214 if i == 1:
215 main.log.error(
216 self.name +
217 ": timeout when waiting for response" )
218 main.log.error( "response: " + str( self.handle.before ) )
219 self.handle.sendline( "" )
220 self.handle.expect( self.prompt )
221 response = self.handle.before
222 if re.search( ',\s0\%\spacket\sloss', response ):
223 main.log.info( self.name + ": no packets lost, host is reachable" )
224 return main.TRUE
225 else:
226 main.log.warn(
227 self.name +
228 ": PACKET LOST, HOST IS NOT REACHABLE" )
229 return main.FALSE
230 except pexpect.EOF:
231 main.log.error( self.name + ": EOF exception found" )
232 main.log.error( self.name + ": " + self.handle.before )
233 main.cleanAndExit()
234 except Exception:
235 main.log.exception( self.name + ": Uncaught exception!" )
236 main.cleanAndExit()
237
238 def ifconfig( self, wait=3 ):
239 """
240 Run ifconfig command on host and return output
241 """
242 try:
243 command = "ifconfig"
244 main.log.info( self.name + ": Sending: " + command )
245 self.handle.sendline( command )
246 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
Jon Halla604fd42018-05-04 14:27:27 -0700247 timeout=wait + 5 )
Pier6a0c4de2018-03-18 16:01:30 -0700248 if i == 1:
249 main.log.error(
250 self.name +
251 ": timeout when waiting for response" )
252 main.log.error( "response: " + str( self.handle.before ) )
Pier6a0c4de2018-03-18 16:01:30 -0700253 response = self.handle.before
254 return response
255 except pexpect.EOF:
256 main.log.error( self.name + ": EOF exception found" )
257 main.log.error( self.name + ": " + self.handle.before )
258 main.cleanAndExit()
259 except Exception:
You Wang4cc61912018-08-28 10:10:58 -0700260 main.log.exception( self.name + ": uncaught exception!" )
261 main.cleanAndExit()
262
263 def ip( self, options="a", wait=3 ):
264 """
265 Run ip command on host and return output
266 """
267 try:
268 command = "ip {}".format( options )
269 main.log.info( self.name + ": Sending: " + command )
270 self.handle.sendline( command )
271 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
272 timeout=wait + 5 )
273 if i == 1:
274 main.log.error( self.name + ": timeout when waiting for response" )
275 main.log.error( "response: " + str( self.handle.before ) )
276 response = self.handle.before
277 return response
278 except pexpect.EOF:
279 main.log.error( self.name + ": EOF exception found" )
280 main.log.error( self.name + ": " + self.handle.before )
281 main.cleanAndExit()
282 except Exception:
283 main.log.exception( self.name + ": uncaught exception!" )
284 main.cleanAndExit()
285
286 def command( self, cmd, wait=3 ):
287 """
288 Run shell command on host and return output
289 Required:
290 cmd: command to run on the host
291 """
292 try:
293 main.log.info( self.name + ": Sending: " + cmd )
294 self.handle.sendline( cmd )
295 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
296 timeout=wait + 5 )
297 if i == 1:
298 main.log.error( self.name + ": timeout when waiting for response" )
299 main.log.error( "response: " + str( self.handle.before ) )
300 response = self.handle.before
301 return response
302 except pexpect.EOF:
303 main.log.error( self.name + ": EOF exception found" )
304 main.log.error( self.name + ": " + self.handle.before )
305 main.cleanAndExit()
306 except Exception:
307 main.log.exception( self.name + ": uncaught exception!" )
Pier6a0c4de2018-03-18 16:01:30 -0700308 main.cleanAndExit()