blob: 7f0ca7c64061ba763df38d11eed1110394d858eb [file] [log] [blame]
You Wangdb927a52016-02-26 11:03:28 -08001"""
2This file contains classes for CHOTestMonkey that are related to application event
3Author: you@onlab.us
4"""
5from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
6from tests.CHOTestMonkey.dependencies.elements.ONOSElement import HostIntent, PointIntent
7
8class IntentEvent( Event ):
9 def __init__( self ):
10 Event.__init__( self )
11 # The index of the ONOS CLI that is going to run the command
12 self.CLIIndex = 0
13
14class HostIntentEvent( IntentEvent ):
15 def __init__( self ):
16 IntentEvent.__init__( self )
17 self.hostA = None
18 self.hostB = None
19
20 def startHostIntentEvent( self ):
21 return EventStates().PASS
22
23 def startEvent( self, args ):
24 with self.eventLock:
25 main.log.info( "%s - starting event" % ( self.typeString ) )
26 if self.typeIndex == EventType().APP_INTENT_HOST_ADD or self.typeIndex == EventType().APP_INTENT_HOST_DEL:
27 if len( args ) < 3:
28 main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
29 return EventStates().ABORT
30 elif len( args ) > 3:
31 main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
32 return EventStates().ABORT
33 else:
34 if args[ 0 ] == args[ 1 ]:
35 main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
36 return EventStates().ABORT
37 for host in main.hosts:
38 if host.name == args[ 0 ]:
39 self.hostA = host
40 elif host.name == args[ 1 ]:
41 self.hostB = host
42 if self.hostA != None and self.hostB != None:
43 break
44 if self.hostA == None:
45 main.log.warn( "Host %s does not exist: " % ( args[ 0 ] ) )
46 return EventStates().ABORT
47 if self.hostB == None:
48 main.log.warn( "Host %s does not exist: " % ( args[ 1 ] ) )
49 return EventStates().ABORT
50 index = int( args[ 2 ] )
51 if index < 1 or index > int( main.numCtrls ):
52 main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
53 return EventStates().ABORT
54 if not main.controllers[ index - 1 ].isUp():
55 main.log.warn( self.typeString + " - invalid argument: onos %s is down" % ( controller.index ) )
56 return EventStates().ABORT
57 self.CLIIndex = index
58 return self.startHostIntentEvent()
59
60class AddHostIntent( HostIntentEvent ):
61 """
62 Add a host-to-host intent (bidirectional)
63 """
64 def __init__( self ):
65 HostIntentEvent.__init__( self )
66 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
67 self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
68
69 def startHostIntentEvent( self ):
70 assert self.hostA != None and self.hostB != None
71 # Check whether there already exists some intent for the host pair
72 # For now we should avoid installing overlapping intents
73 for intent in main.intents:
74 if not intent.type == 'INTENT_HOST':
75 continue
76 if intent.hostA == self.hostA and intent.hostB == self.hostB or\
77 intent.hostB == self.hostA and intent.hostA == self.hostB:
78 main.log.warn( self.typeString + " - find an exiting intent for the host pair, abort installation" )
79 return EventStates().ABORT
80 controller = main.controllers[ self.CLIIndex - 1 ]
81 with controller.CLILock:
82 id = controller.CLI.addHostIntent( self.hostA.id, self.hostB.id )
83 if id == None:
84 main.log.warn( self.typeString + " - add host intent failed" )
85 return EventStates().FAIL
86 with main.variableLock:
87 newHostIntent = HostIntent( id, self.hostA, self.hostB )
88 main.intents.append( newHostIntent )
89 # Update host connectivity status
90 # TODO: should we check whether hostA and hostB are already correspondents?
91 self.hostB.correspondents.append( self.hostA )
92 self.hostA.correspondents.append( self.hostB )
93 return EventStates().PASS
94
95class DelHostIntent( HostIntentEvent ):
96 """
97 Delete a host-to-host intent (bidirectional)
98 """
99 def __init__( self ):
100 HostIntentEvent.__init__( self )
101 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
102 self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
103
104 def startHostIntentEvent( self ):
105 assert self.hostA != None and self.hostB != None
106 targetIntent = None
107 for intent in main.intents:
108 if not intent.type == 'INTENT_HOST':
109 continue
110 if intent.hostA == self.hostA and intent.hostB == self.hostB or\
111 intent.hostB == self.hostA and intent.hostA == self.hostB:
112 targetIntent = intent
113 break
114 if targetIntent == None:
115 main.log.warn( self.typeString + " - intent does not exist" )
116 return EventStates().FAIL
117 controller = main.controllers[ self.CLIIndex - 1 ]
118 with controller.CLILock:
119 result = controller.CLI.removeIntent( targetIntent.id, purge=True )
120 if result == None or result == main.FALSE:
121 main.log.warn( self.typeString + " - delete host intent failed" )
122 return EventStates().FAIL
123 with main.variableLock:
124 main.intents.remove( targetIntent )
125 # Update host connectivity status
126 self.hostB.correspondents.remove( self.hostA )
127 self.hostA.correspondents.remove( self.hostB )
128 return EventStates().PASS
129
130class PointIntentEvent( IntentEvent ):
131 def __init__( self ):
132 IntentEvent.__init__( self )
133 self.deviceA = None
134 self.deviceB = None
135
136 def startPointIntentEvent( self ):
137 return EventStates().PASS
138
139 def startEvent( self, args ):
140 with self.eventLock:
141 main.log.info( "%s - starting event" % ( self.typeString ) )
142 if self.typeIndex == EventType().APP_INTENT_POINT_ADD or self.typeIndex == EventType().APP_INTENT_POINT_DEL:
143 if len( args ) < 3:
144 main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
145 return EventStates().ABORT
146 elif len( args ) > 3:
147 main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
148 return EventStates().ABORT
149 else:
150 for device in main.devices:
151 if device.name == args[ 0 ]:
152 self.deviceA = device
153 elif device.name == args[ 1 ]:
154 self.deviceB = device
155 if self.deviceA != None and self.deviceB != None:
156 break
157 if self.deviceA == None:
158 main.log.warn( "Device %s does not exist: " % ( args[ 0 ] ) )
159 return EventStates().ABORT
160 if self.deviceB == None:
161 main.log.warn( "Device %s does not exist: " % ( args[ 1 ] ) )
162 return EventStates().ABORT
163 index = int( args[ 2 ] )
164 if index < 1 or index > int( main.numCtrls ):
165 main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
166 return EventStates().ABORT
167 if not main.controllers[ index - 1 ].isUp():
168 main.log.warn( self.typeString + " - invalid argument: onos %s is down" % ( controller.index ) )
169 return EventStates().ABORT
170 self.CLIIndex = index
171 return self.startPointIntentEvent()
172
173class AddPointIntent( PointIntentEvent ):
174 """
175 Add a point-to-point intent
176 """
177 def __init__( self ):
178 PointIntentEvent.__init__( self )
179 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
180 self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
181
182 def startPointIntentEvent( self ):
183 assert self.deviceA != None and self.deviceB != None
184 controller = main.controllers[ self.CLIIndex - 1 ]
185 # TODO: the following check only work when we use default port number for point intents
186 # Check whether there already exists some intent for the device pair
187 # For now we should avoid installing overlapping intents
188 for intent in main.intents:
189 if not intent.type == 'INTENT_POINT':
190 continue
191 if intent.deviceA == self.deviceA and intent.deviceB == self.deviceB:
192 main.log.warn( self.typeString + " - find an exiting intent for the device pair, abort installation" )
193 return EventStates().ABORT
194 controller = main.controllers[ self.CLIIndex - 1 ]
195 with controller.CLILock:
196 # TODO: handle the case that multiple hosts attach to one device
197 id = controller.CLI.addPointIntent( self.deviceA.dpid, self.deviceB.dpid,
198 1, 1, '',
199 self.deviceA.hosts[ 0 ].mac,
200 self.deviceB.hosts[ 0 ].mac )
201 if id == None:
202 main.log.warn( self.typeString + " - add point intent failed" )
203 return EventStates().FAIL
204 with main.variableLock:
205 newPointIntent = PointIntent( id, self.deviceA, self.deviceB )
206 main.intents.append( newPointIntent )
207 # Update host connectivity status
208 for hostA in self.deviceA.hosts:
209 for hostB in self.deviceB.hosts:
210 hostA.correspondents.append( hostB )
211 return EventStates().PASS
212
213class DelPointIntent( PointIntentEvent ):
214 """
215 Delete a point-to-point intent
216 """
217 def __init__( self ):
218 PointIntentEvent.__init__( self )
219 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
220 self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
221
222 def startPointIntentEvent( self ):
223 assert self.deviceA != None and self.deviceB != None
224 targetIntent = None
225 for intent in main.intents:
226 if not intent.type == 'INTENT_POINT':
227 continue
228 if intent.deviceA == self.deviceA and intent.deviceB == self.deviceB:
229 targetIntent = intent
230 break
231 if targetIntent == None:
232 main.log.warn( self.typeString + " - intent does not exist" )
233 return EventStates().FAIL
234 controller = main.controllers[ self.CLIIndex - 1 ]
235 with controller.CLILock:
236 result = controller.CLI.removeIntent( targetIntent.id, purge=True )
237 if result == None or result == main.FALSE:
238 main.log.warn( self.typeString + " - delete host intent failed" )
239 return EventStates().FAIL
240 with main.variableLock:
241 main.intents.remove( targetIntent )
242 # Update host connectivity status
243 for hostA in self.deviceA.hosts:
244 for hostB in self.deviceB.hosts:
245 hostA.correspondents.remove( hostB )
246 return EventStates().PASS