blob: 01aa7340291b379bf40ea4f895376160a457c81e [file] [log] [blame]
You Wangdb927a52016-02-26 11:03:28 -08001"""
2This file contains classes for CHOTestMonkey that are related to check event
3Author: you@onlab.us
4"""
5from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
6
7class CheckEvent( Event ):
8 def __init__( self ):
9 Event.__init__( self )
10
11 def startCheckEvent( self ):
12 return EventStates().PASS
13
14 def startEvent( self, args ):
15 with self.eventLock:
16 main.log.info( "%s - starting event" % ( self.typeString ) )
17 result = self.startCheckEvent()
18 return result
19
20class IntentCheck( CheckEvent ):
21 def __init__( self ):
22 CheckEvent.__init__( self )
23 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
24 self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
25
26 def startCheckEvent( self, args=None ):
27 checkResult = EventStates().PASS
You Wang2b687c02016-05-13 17:01:31 -070028 # TODO: check intents that are expected in "FAILED" state?
29 installedIntentIDs = []
You Wangdb927a52016-02-26 11:03:28 -080030 for intent in main.intents:
You Wang2b687c02016-05-13 17:01:31 -070031 if intent.isInstalled():
32 installedIntentIDs.append( intent.id )
You Wangdb927a52016-02-26 11:03:28 -080033 for controller in main.controllers:
34 if controller.isUp():
35 with controller.CLILock:
You Wang2b687c02016-05-13 17:01:31 -070036 intentState = controller.CLI.checkIntentState( intentsId=installedIntentIDs )
You Wangdb927a52016-02-26 11:03:28 -080037 if not intentState:
38 main.log.warn( "Intent Check - Not all intents are in INSTALLED state on ONOS%s" % ( controller.index ) )
39 checkResult = EventStates().FAIL
40 #TODO: check flows?
41 return checkResult
42
43class TopoCheck( CheckEvent ):
44 def __init__( self ):
45 CheckEvent.__init__( self )
46 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
47 self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
48
49 def startCheckEvent( self, args=None ):
50 import json
51 checkResult = EventStates().PASS
52 upLinkNum = 0
53 upDeviceNum = 0
54 upHostNum = 0
55 with main.variableLock:
56 for link in main.links:
57 if not link.isDown() and not link.isRemoved():
58 upLinkNum += 1
59 for device in main.devices:
60 if not device.isDown() and not device.isRemoved():
61 upDeviceNum += 1
62 for host in main.hosts:
63 if not host.isDown() and not host.isRemoved():
64 upHostNum += 1
65 clusterNum = 1
66 for controller in main.controllers:
67 if controller.isUp():
68 with controller.CLILock:
69 topologyOutput = controller.CLI.topology()
70 topoState = controller.CLI.checkStatus( topologyOutput, upDeviceNum, upLinkNum )
71 #if not topoState:
72 # main.log.warn( "Topo Check - link or device number discoverd by ONOS%s is incorrect" % ( controller.index ) )
73 # checkResult = EventStates().FAIL
74 # Check links
75 links = controller.CLI.links()
76 links = json.loads( links )
77 if not len( links ) == upLinkNum:
78 checkResult = EventStates().FAIL
79 main.log.warn( "Topo Check - link number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, upLinkNum, len( links ) ) )
80 # Check devices
81 devices = controller.CLI.devices()
82 devices = json.loads( devices )
83 availableDeviceNum = 0
84 for device in devices:
85 if device[ 'available' ] == True:
86 availableDeviceNum += 1
87 if not availableDeviceNum == upDeviceNum:
88 checkResult = EventStates().FAIL
89 main.log.warn( "Topo Check - device number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, upDeviceNum, availableDeviceNum ) )
90 # Check hosts
91 hosts = controller.CLI.hosts()
92 hosts = json.loads( hosts )
93 if not len( hosts ) == upHostNum:
94 checkResult = EventStates().FAIL
95 main.log.warn( "Topo Check - host number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, upHostNum, len( hosts ) ) )
96 # Check clusters
97 clusters = controller.CLI.clusters()
98 clusters = json.loads( clusters )
99 if not len( clusters ) == clusterNum:
100 checkResult = EventStates().FAIL
101 main.log.warn( "Topo Check - cluster number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, clusterNum, len( clusters ) ) )
102 return checkResult
103
104class ONOSCheck( CheckEvent ):
105 def __init__( self ):
106 CheckEvent.__init__( self )
107 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
108 self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
109
110 def startCheckEvent( self, args=None ):
111 import json
112 checkResult = EventStates().PASS
113 topics = []
114 # TODO: Other topics?
115 for i in range( 14 ):
116 topics.append( "intent-partition-" + str( i ) )
117 dpidToAvailability = {}
118 dpidToMaster = {}
119 for device in main.devices:
120 if device.isDown() or device.isRemoved():
121 dpidToAvailability[ device.dpid ] = False
122 else:
123 dpidToAvailability[ device.dpid ] = True
124 dpidToMaster[ device.dpid ] = 'unknown'
125 # Check mastership, leaders and node states on each controller node
126 for controller in main.controllers:
127 if controller.isUp():
128 # Check mastership
129 with controller.CLILock:
130 roles = controller.CLI.roles()
131 roles = json.loads( roles )
132 for device in roles:
133 dpid = device[ 'id' ]
134 if dpidToMaster[ dpid ] == 'unknown':
135 dpidToMaster[ dpid ] = device[ 'master' ]
136 elif dpidToMaster[ dpid ] != device[ 'master' ]:
137 checkResult = EventStates().FAIL
You Wang82e04e12016-05-12 17:10:27 -0700138 main.log.warn( "ONOS Check - Mastership of %s on ONOS%s is inconsistent with that on ONOS1" % ( dpid, controller.index ) )
You Wangdb927a52016-02-26 11:03:28 -0800139 if dpidToAvailability[ dpid ] and device[ 'master' ] == "none":
140 checkResult = EventStates().FAIL
You Wang82e04e12016-05-12 17:10:27 -0700141 main.log.warn( "ONOS Check - Device %s has no master on ONOS%s" % ( dpid, controller.index ) )
You Wangdb927a52016-02-26 11:03:28 -0800142 # Check leaders
143 with controller.CLILock:
144 leaders = controller.CLI.leaders()
145 leaders = json.loads( leaders )
146 ONOSTopics = [ j['topic'] for j in leaders ]
147 for topic in topics:
148 if topic not in ONOSTopics:
149 checkResult = EventStates().FAIL
150 main.log.warn( "ONOS Check - Topic %s not in leaders on ONOS%s" % ( topic, controller.index ) )
151 # Check node state
152 with controller.CLILock:
153 nodes = controller.CLI.nodes()
154 nodes = json.loads( nodes )
155 ipToState = {}
156 for node in nodes:
157 ipToState[ node[ 'ip' ] ] = node[ 'state' ]
158 for c in main.controllers:
159 if c.isUp() and ipToState[ c.ip ] == 'READY':
160 pass
161 elif not c.isUp() and ipToState[ c.ip ] == 'INACTIVE':
162 pass
163 else:
164 checkResult = EventStates().FAIL
165 main.log.warn( "ONOS Check - ONOS%s shows wrong node state: ONOS%s is %s but state is %s" % ( controller.index, c.index, c.status, ipToState[ c.ip ] ) )
166 # TODO: check partitions?
167 return checkResult
168
169class TrafficCheck( CheckEvent ):
170 def __init__( self ):
171 CheckEvent.__init__( self )
172 self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
173 self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
174
175 def startCheckEvent( self, args=None ):
176 checkResult = EventStates().PASS
177 pool = []
178 wait = int( main.params[ 'EVENT' ][ 'TrafficCheck' ][ 'pingWait' ] )
179 timeout = int( main.params[ 'EVENT' ][ 'TrafficCheck' ][ 'pingTimeout' ] )
180 dstIPv4List = {}
181 dstIPv6List = {}
182 upHosts = []
183 for host in main.hosts:
184 if host.isUp():
185 upHosts.append( host )
186 for host in upHosts:
187 dstIPv4List[ host.index ] = []
188 dstIPv6List[ host.index ] = []
189 for correspondent in host.correspondents:
190 if not correspondent in upHosts:
191 continue
192 for ipAddress in correspondent.ipAddresses:
193 if ipAddress.startswith( str( main.params[ 'TEST' ][ 'ipv6Prefix' ] ) ):
194 dstIPv6List[ host.index ].append( ipAddress )
195 elif ipAddress.startswith( str( main.params[ 'TEST' ][ 'ipv4Prefix' ] ) ):
196 dstIPv4List[ host.index ].append( ipAddress )
197 thread = main.Thread( target=host.handle.pingHostSetAlternative,
198 threadID=main.threadID,
199 name="pingHostSetAlternative",
200 args=[ dstIPv4List[ host.index ], 1 ] )
201 pool.append( thread )
202 thread.start()
203 with main.variableLock:
204 main.threadID += 1
205 for thread in pool:
206 thread.join( 10 )
207 if not thread.result:
208 checkResult = EventStates().FAIL
209 main.log.warn( "Traffic Check - ping failed" )
210
211 if not main.enableIPv6:
212 return checkResult
213 # Check ipv6 ping
214 for host in upHosts:
215 thread = main.Thread( target=host.handle.pingHostSetAlternative,
216 threadID=main.threadID,
217 name="pingHostSetAlternative",
218 args=[ dstIPv6List[ host.index ], 1, True ] )
219 pool.append( thread )
220 thread.start()
221 with main.variableLock:
222 main.threadID += 1
223 for thread in pool:
224 thread.join( 10 )
225 if not thread.result:
226 checkResult = EventStates().FAIL
227 main.log.warn( "Traffic Check - ping6 failed" )
228 return checkResult
229