blob: 0dd15eeaf657484be9172fa42be56582574c1cce [file] [log] [blame]
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001#/usr/bin/env python
kelvin8ec71442015-01-15 16:57:00 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Nov-2012
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004Copyright 2012 Open Networking Foundation (ONF)
Jeremy Songsterae01bba2016-07-11 15:39:17 -07005
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>
kelvin8ec71442015-01-15 16:57:00 -08009
10author:: Raghav Kashyap( raghavkashyap@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -070011
12
13 TestON is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 2 of the License, or
kelvin8ec71442015-01-15 16:57:00 -080016 ( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070017
18 TestON is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
kelvin8ec71442015-01-15 16:57:00 -080024 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070025
26
27
28DPCTL driver class provides the basic functions of DPCTL controller
kelvin8ec71442015-01-15 16:57:00 -080029"""
adminbae64d82013-08-01 10:50:15 -070030import sys
31from drivers.common.cli.toolsdriver import Tools
adminbae64d82013-08-01 10:50:15 -070032
kelvin8ec71442015-01-15 16:57:00 -080033
34class DpctlCliDriver( Tools ):
35
36 """
adminbae64d82013-08-01 10:50:15 -070037 DpctlCliDriver driver class provides the basic functions of DPCTL controller
kelvin8ec71442015-01-15 16:57:00 -080038 """
39 def __init__( self ):
40 super( DpctlCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070041 self.handle = self
kelvin8ec71442015-01-15 16:57:00 -080042 self.wrapped = sys.modules[ __name__ ]
43
44 def connect( self, **connectargs ):
45
adminbae64d82013-08-01 10:50:15 -070046 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080047 vars( self )[ key ] = connectargs[ key ]
adminbae64d82013-08-01 10:50:15 -070048
kelvin8ec71442015-01-15 16:57:00 -080049 self.name = self.options[ 'name' ]
50
Jon Hallfd8ce432015-07-21 13:07:53 -070051 self.handle = super(
Jon Hall4ba53f02015-07-29 13:07:41 -070052 DpctlCliDriver, self ).connect( user_name=self.user_name,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000053 ip_address=self.ip_address,
54 port=None,
55 pwd=self.pwd )
kelvin8ec71442015-01-15 16:57:00 -080056 if self.handle:
57 main.log.info( "Connected to the host" )
58 return main.TRUE
59 else:
60 main.log.error(
61 "Connection failed to the host " +
62 self.user_name +
63 "@" +
64 self.ip_address )
65 return main.FALSE
66
67 def addFlow( self, **flowParameters ):
68 """
adminbae64d82013-08-01 10:50:15 -070069 addFlow create a new flow entry into flow table using "dpctl"
kelvin8ec71442015-01-15 16:57:00 -080070 """
71 args = utilities.parse_args( [
Jon Hall4ba53f02015-07-29 13:07:41 -070072 "TCPIP",
kelvin8ec71442015-01-15 16:57:00 -080073 "TCPPORT",
74 "INPORT",
75 "ACTION",
76 "TIMEOUT" ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000077 **flowParameters )
kelvin8ec71442015-01-15 16:57:00 -080078
adminbae64d82013-08-01 10:50:15 -070079 cmd = "dpctl add-flow tcp:"
kelvin8ec71442015-01-15 16:57:00 -080080 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
81 tcpPort = args[ "TCPPORT" ] if args[
82 "TCPPORT" ] is not None else "6634"
83 timeOut = args[ "TIMEOUT" ] if args[ "TIMEOUT" ] is not None else 120
84 cmd = cmd + tcpIP + ":" + tcpPort + " in_port=" + \
85 str( args[ "INPORT" ] ) + ",idle_timeout=" + str(
86 args[ "TIMEOUT" ] ) + ",actions=" + args[ "ACTION" ]
Devin Limdc78e202017-06-09 18:30:07 -070087 response = self.execute( cmd=cmd, prompt="\~" + self.prompt, timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -080088 if utilities.assert_matches( expect="openflow", actual=response, onpass="Flow Added Successfully", onfail="Adding Flow Failed!!!" ):
adminbae64d82013-08-01 10:50:15 -070089 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -080090 else:
adminbae64d82013-08-01 10:50:15 -070091 return main.FALSE
92
kelvin8ec71442015-01-15 16:57:00 -080093 def showFlow( self, **flowParameters ):
94 """
adminbae64d82013-08-01 10:50:15 -070095 showFlow dumps the flow entries of flow table using "dpctl"
kelvin8ec71442015-01-15 16:57:00 -080096 """
97 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
98 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
99 tcpPort = args[ "TCPPORT" ] if args[
100 "TCPPORT" ] is not None else "6634"
101 command = "dpctl show tcp:" + str( tcpIP ) + ":" + str( tcpPort )
102 response = self.execute(
103 cmd=command,
104 prompt="get_config_reply",
105 timeout=240 )
106 if utilities.assert_matches( expect='features_reply', actual=response, onpass="Show flow executed", onfail="Show flow execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700107 main.last_result = main.TRUE
108 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800109 else:
adminbae64d82013-08-01 10:50:15 -0700110 main.last_result = main.FALSE
111 return main.FALSE
112
kelvin8ec71442015-01-15 16:57:00 -0800113 def dumpFlow( self, **flowParameters ):
114 """
adminbae64d82013-08-01 10:50:15 -0700115 dumpFlow gives installed flow information
kelvin8ec71442015-01-15 16:57:00 -0800116 """
117 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
118 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
119 tcpPort = args[ "TCPPORT" ] if args[
120 "TCPPORT" ] is not None else "6634"
121 command = "dpctl dump-flows tcp:" + str( tcpIP ) + ":" + str( tcpPort )
122 response = self.execute( cmd=command, prompt="type=", timeout=240 )
123 if utilities.assert_matches( expect='stats_reply', actual=response, onpass="Dump flow executed", onfail="Dump flow execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700124 main.last_result = main.TRUE
125 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800126 else:
adminbae64d82013-08-01 10:50:15 -0700127 main.last_result = main.FALSE
128 return main.FALSE
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def dumpTables( self, **flowParameters ):
131 """
adminbae64d82013-08-01 10:50:15 -0700132 dumpTables gives statistics for each of the flow tables used by datapath switch.
kelvin8ec71442015-01-15 16:57:00 -0800133 """
134 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
135 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
136 tcpPort = args[ "TCPPORT" ] if args[
137 "TCPPORT" ] is not None else "6634"
138 command = "dpctl dump-tables tcp:" + \
139 str( tcpIP ) + ":" + str( tcpPort )
140 response = self.execute( cmd=command, prompt="matched", timeout=240 )
141 if utilities.assert_matches( expect='lookup=3', actual=response, onpass="Dump Tables executed", onfail="Dump Tables execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700142 main.last_result = main.TRUE
143 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800144 else:
adminbae64d82013-08-01 10:50:15 -0700145 main.last_result = main.FALSE
146 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800147
148 def dumpPorts( self, **flowParameters ):
149 """
adminbae64d82013-08-01 10:50:15 -0700150 dumpPorts gives ports information
kelvin8ec71442015-01-15 16:57:00 -0800151 """
152 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
153 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
154 tcpPort = args[ "TCPPORT" ] if args[
155 "TCPPORT" ] is not None else "6634"
156 command = "dpctl dump-ports tcp:" + str( tcpIP ) + ":" + str( tcpPort )
157 response = self.execute( cmd=command, prompt="rx pkts", timeout=240 )
158 if utilities.assert_matches( expect='ports', actual=response, onpass="Dump Ports executed", onfail="Dump Ports execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700159 main.last_result = main.TRUE
160 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800161 else:
adminbae64d82013-08-01 10:50:15 -0700162 main.last_result = main.FALSE
163 return main.FALSE
164
kelvin8ec71442015-01-15 16:57:00 -0800165 def dumpAggregate( self, **flowParameters ):
166 """
adminbae64d82013-08-01 10:50:15 -0700167 dumpAggregate gives installed flow information.ggregate statistics for flows in datapath WITCH's tables that match flows.
168 If flows is omitted, the statistics are aggregated across all flows in the datapath's flow tables
kelvin8ec71442015-01-15 16:57:00 -0800169 """
170 args = utilities.parse_args(
171 [ "TCPIP", "TCPPORT", "FLOW" ], **flowParameters )
172 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
173 tcpPort = args[ "TCPPORT" ] if args[
174 "TCPPORT" ] is not None else "6634"
175 flow = args[ "FLOW" ] if args[ "FLOW" ] is not None else ""
176 command = "dpctl dump-aggregate tcp:" + \
177 str( tcpIP ) + ":" + str( tcpPort ) + " " + str( flow )
178 response = self.execute(
179 cmd=command,
180 prompt="flow_count=",
181 timeout=240 )
182 if utilities.assert_matches( expect='stats_reply', actual=response, onpass="Dump Aggregate executed", onfail="Dump Aggregate execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700183 main.last_result = main.TRUE
184 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800185 else:
adminbae64d82013-08-01 10:50:15 -0700186 main.last_result = main.FALSE
187 return main.FALSE
188
kelvin8ec71442015-01-15 16:57:00 -0800189 def delFlow( self, **flowParameters ):
190 """
adminbae64d82013-08-01 10:50:15 -0700191 delFlow Deletes entries from the datapath switch's tables that match flow
kelvin8ec71442015-01-15 16:57:00 -0800192 """
193 args = utilities.parse_args(
194 [ "TCPIP", "TCPPORT", "FLOW" ], **flowParameters )
195 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
196 tcpPort = args[ "TCPPORT" ] if args[
197 "TCPPORT" ] is not None else "6634"
198 flow = args[ "FLOW" ] if args[ "FLOW" ] is not None else ""
199 command = "dpctl del-flows tcp:" + \
200 str( tcpIP ) + ":" + str( tcpPort ) + " " + str( flow )
201 response = self.execute(
202 cmd=command,
203 prompt="ETH-Tutorial",
204 timeout=240 )
205 if utilities.assert_matches( expect='@', actual=response, onpass="Delete flow executed", onfail="Delete flow execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700206 main.last_result = main.TRUE
207 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800208 else:
adminbae64d82013-08-01 10:50:15 -0700209 main.last_result = main.FALSE
210 return main.FALSE
211
kelvin8ec71442015-01-15 16:57:00 -0800212 def show( self, **flowParameters ):
213 """
adminbae64d82013-08-01 10:50:15 -0700214 show gives information on datapath switch including information on its flow tables and ports.
kelvin8ec71442015-01-15 16:57:00 -0800215 """
216 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
217 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
218 tcpPort = args[ "TCPPORT" ] if args[
219 "TCPPORT" ] is not None else "6634"
220 command = "dpctl show tcp:" + str( tcpIP ) + ":" + str( tcpPort )
221 response = self.execute(
222 cmd=command,
223 prompt="miss_send_len=",
224 timeout=240 )
225 if utilities.assert_matches( expect='get_config_reply', actual=response, onpass="show command executed", onfail="show command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700226 main.last_result = main.TRUE
227 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800228 else:
adminbae64d82013-08-01 10:50:15 -0700229 main.last_result = main.FALSE
230 return main.FALSE
231
kelvin8ec71442015-01-15 16:57:00 -0800232 def showStatus( self, **flowParameters ):
233 """
234 showStatus gives a series of key-value pairs that report the status of switch.
235 If key is specified, only the key-value pairs whose key names begin with key are printed.
236 """
237 args = utilities.parse_args(
238 [ "TCPIP", "TCPPORT", "KEY" ], **flowParameters )
239 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
240 tcpPort = args[ "TCPPORT" ] if args[
241 "TCPPORT" ] is not None else "6634"
242 key = args[ "KEY" ] if args[ "KEY" ] is not None else ""
243 command = "dpctl status tcp:" + \
244 str( tcpIP ) + ":" + str( tcpPort ) + " " + key
245 response = self.execute( cmd=command, prompt="(.*)", timeout=240 )
246 if utilities.assert_matches( expect='(.*)', actual=response, onpass="show command executed", onfail="show command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700247 main.last_result = main.TRUE
248 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800249 else:
adminbae64d82013-08-01 10:50:15 -0700250 main.last_result = main.FALSE
251 return main.FALSE
252
kelvin8ec71442015-01-15 16:57:00 -0800253 def desc_set( self, **flowParameters ):
254 """
255 desc_set Sets the switch description ( as returned in ofp_desc_stats ) to string ( max length is DESC_STR_LEN )
256 """
257 args = utilities.parse_args( [
Jon Hall4ba53f02015-07-29 13:07:41 -0700258 "TCPIP",
kelvin8ec71442015-01-15 16:57:00 -0800259 "TCPPORT",
260 "STRING" ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000261 **flowParameters )
kelvin8ec71442015-01-15 16:57:00 -0800262
263 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
264 tcpPort = args[ "TCPPORT" ] if args[
265 "TCPPORT" ] is not None else "6634"
266 string = " " + args[ "STRING" ] if args[
267 "STRING" ] is not None else " DESC_STR_LEN"
268 command = "dpctl desc tcp:" + \
269 str( tcpIP ) + ":" + str( tcpPort ) + str( string )
270 response = self.execute(
271 cmd=command,
272 prompt="ETH-Tutorial",
273 timeout=240 )
274 if utilities.assert_matches( expect='@', actual=response, onpass="desc command executed", onfail="desc command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700275 main.last_result = main.TRUE
276 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800277 else:
adminbae64d82013-08-01 10:50:15 -0700278 main.last_result = main.FALSE
279 return main.FALSE
280
kelvin8ec71442015-01-15 16:57:00 -0800281 def dumpDesc( self, **flowParameters ):
282 """
283 dumpDesc Sets the switch description ( as returned in ofp_desc_stats ) to string ( max length is DESC_STR_LEN )
284 """
285 args = utilities.parse_args( [
Jon Hall4ba53f02015-07-29 13:07:41 -0700286 "TCPIP",
kelvin8ec71442015-01-15 16:57:00 -0800287 "TCPPORT",
288 "STRING" ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000289 **flowParameters )
kelvin8ec71442015-01-15 16:57:00 -0800290
291 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
292 tcpPort = args[ "TCPPORT" ] if args[
293 "TCPPORT" ] is not None else "6634"
294 command = "dpctl dump-desc tcp:" + str( tcpIP ) + ":" + str( tcpPort )
295 response = self.execute(
296 cmd=command,
297 prompt="Serial Num:",
298 timeout=240 )
299 if utilities.assert_matches( expect='stats_reply', actual=response, onpass="desc command executed", onfail="desc command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700300 main.last_result = main.TRUE
301 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800302 else:
adminbae64d82013-08-01 10:50:15 -0700303 main.last_result = main.FALSE
304 return main.FALSE
305
306if __name__ != "__main__":
307 import sys
kelvin8ec71442015-01-15 16:57:00 -0800308 sys.modules[ __name__ ] = DpctlCliDriver()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000309