blob: 4874c025c499403621bedf82ecb7a38cfdc6317d [file] [log] [blame]
You Wangdafb6e22018-01-22 17:01:00 -08001#!/usr/bin/env python
2"""
32015-2016
4Copyright 2016 Open Networking Foundation (ONF)
5
6Please 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>
9
10TestON is free software: you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation, either version 2 of the License, or
13( at your option ) any later version.
14
15TestON is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with TestON. If not, see <http://www.gnu.org/licenses/>.
22
23MininetScapyCliDriver is for controlling scapy hosts running in Mininet
24
25TODO: Add Explanation on how to install scapy
26"""
27import pexpect
28import re
29import sys
30import types
31import os
32from drivers.common.cli.emulator.scapyclidriver import ScapyCliDriver
33
34
35class MininetScapyCliDriver( ScapyCliDriver ):
36 """
37 MininetScapyCliDriver is for controlling scapy hosts running in Mininet
38 """
39 def __init__( self ):
40 super( MininetScapyCliDriver, self ).__init__()
41 self.handle = self
42 self.name = None
43 self.home = None
44 self.wrapped = sys.modules[ __name__ ]
45 self.flag = 0
46 self.hostPrompt = "~#"
47 self.scapyPrompt = ">>>"
48
49 def connect( self, **connectargs ):
50 """
51 Here the main is the TestON instance after creating
52 all the log handles.
53 """
54 try:
55 for key in connectargs:
56 vars( self )[ key ] = connectargs[ key ]
57 self.home = self.options[ 'home' ] if 'home' in self.options.keys() else "~/mininet"
58 self.name = self.options[ 'name' ]
59 self.ifaceName = self.options[ 'ifaceName' ] if 'ifaceName' in self.options.keys() else self.name + "-eth0"
60
61 try:
62 if os.getenv( str( self.ip_address ) ) is not None:
63 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
76 self.handle = super(
77 ScapyCliDriver,
78 self ).connect(
79 user_name=self.user_name,
80 ip_address=self.ip_address,
81 port=None,
82 pwd=self.pwd )
83
84 if self.handle:
85 main.log.info( "Connection successful to the host " +
86 self.user_name +
87 "@" +
88 self.ip_address )
89 return main.TRUE
90 else:
91 main.log.error( "Connection failed to the host " +
92 self.user_name +
93 "@" +
94 self.ip_address )
95 main.log.error( "Failed to connect to the Mininet Host" )
96 return main.FALSE
97 except pexpect.EOF:
98 main.log.error( self.name + ": EOF exception found" )
99 main.log.error( self.name + ": " + self.handle.before )
100 main.cleanAndExit()
101 except Exception:
102 main.log.exception( self.name + ": Uncaught exception!" )
103 main.cleanAndExit()
104
105 def disconnect( self ):
106 """
107 Called at the end of the test to stop the scapy component and
108 disconnect the handle.
109 """
110 self.handle.sendline( '' )
111 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
112 timeout=2 )
113 response = main.TRUE
114 if i == 0:
115 response = self.stopNet()
116 elif i == 1:
117 return main.TRUE
118 # print "Disconnecting Mininet"
119 if self.handle:
120 self.handle.sendline( "exit" )
121 self.handle.expect( "exit" )
122 self.handle.expect( "(.*)" )
123 else:
124 main.log.error( "Connection failed to the host" )
125 return response
126
127 def stopNet( self, fileName="", timeout=5 ):
128 """
129 Stops mininet.
130 Returns main.TRUE if the mininet successfully stops and
131 main.FALSE if the pexpect handle does not exist.
132
133 Will cleanup and exit the test if scapy fails to stop
134 """
135 main.log.info( self.name + ": Stopping scapy..." )
136 response = ''
137 if self.handle:
138 try:
139 self.handle.sendline( "" )
140 i = self.handle.expect( [ '>>>',
141 self.prompt,
142 pexpect.EOF,
143 pexpect.TIMEOUT ],
144 timeout )
145 if i == 0:
146 main.log.info( "Exiting scapy..." )
147 response = self.execute(
148 cmd="exit",
149 prompt="(.*)",
150 timeout=120 )
151 main.log.info( self.name + ": Stopped" )
152 response = main.TRUE
153
154 if i == 1:
155 main.log.info( " Mininet trying to exit while not " +
156 "in the mininet prompt" )
157 elif i == 2:
158 main.log.error( "Something went wrong exiting mininet" )
159 elif i == 3: # timeout
160 main.log.error( "Something went wrong exiting mininet " +
161 "TIMEOUT" )
162
163 if fileName:
164 self.handle.sendline( "" )
165 self.handle.expect( self.prompt )
166 self.handle.sendline(
167 "sudo kill -9 \`ps -ef | grep \"" +
168 fileName +
169 "\" | grep -v grep | awk '{print $2}'\`" )
170 except pexpect.EOF:
171 main.log.error( self.name + ": EOF exception found" )
172 main.log.error( self.name + ": " + self.handle.before )
173 main.cleanAndExit()
174 else:
175 main.log.error( self.name + ": Connection failed to the host" )
176 response = main.FALSE
177 return response
178
179 def createHostComponent( self, name ):
180 """
181 Creates a new mininet cli component with the same parameters as self.
182 This new component is intended to be used to login to the hosts created
183 by mininet.
184
185 Arguments:
186 name - The string of the name of this component. The new component
187 will be assigned to main.<name> .
188 In addition, main.<name>.name = str( name )
189 """
190 try:
191 # look to see if this component already exists
192 getattr( main, name )
193 except AttributeError:
194 # namespace is clear, creating component
195 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
196 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
197 main.componentInit( name )
198 except Exception:
199 main.log.exception( self.name + ": Uncaught exception!" )
200 main.cleanAndExit()
201 else:
202 # namespace is not clear!
203 main.log.error( name + " component already exists!" )
204 main.cleanAndExit()
205
206 def removeHostComponent( self, name ):
207 """
208 Remove host component
209 Arguments:
210 name - The string of the name of the component to delete.
211 """
212 try:
213 # Get host component
214 component = getattr( main, name )
215 except AttributeError:
216 main.log.error( "Component " + name + " does not exist." )
217 return main.FALSE
218 try:
219 # Disconnect from component
220 component.disconnect()
221 # Delete component
222 delattr( main, name )
223 # Delete component from ComponentDictionary
224 del( main.componentDictionary[ name ] )
225 return main.TRUE
226 except Exception:
227 main.log.exception( self.name + ": Uncaught exception!" )
228 main.cleanAndExit()
229
230 def startHostCli( self, host=None ):
231 """
232 Use the mininet m utility to connect to the host's cli
233 """
234 # These are fields that can be used by scapy packets. Initialized to None
235 self.hostIp = None
236 self.hostMac = None
237 try:
238 if not host:
239 host = self.name
240 self.handle.sendline( self.home + "/util/m " + host )
241 self.handle.sendline( "cd" )
242 self.handle.expect( self.hostPrompt )
243 self.handle.sendline( "" )
244 self.handle.expect( self.hostPrompt )
245 return main.TRUE
246 except pexpect.TIMEOUT:
247 main.log.exception( self.name + ": Command timed out" )
248 return main.FALSE
249 except pexpect.EOF:
250 main.log.exception( self.name + ": connection closed." )
251 main.cleanAndExit()
252 except Exception:
253 main.log.exception( self.name + ": Uncaught exception!" )
254 main.cleanAndExit()
255
256if __name__ != "__main__":
257 sys.modules[ __name__ ] = MininetScapyCliDriver()