blob: a4b3d8a1d410f45c8f2347920ce587dd0dca40fb [file] [log] [blame]
Ken Chiangd6f5f862012-09-28 15:40:33 -07001"""
2Connection test cases
3
4"""
5
6import time
7import signal
8import sys
9import logging
10
11import unittest
12import random
13
14import oftest.controller as controller
15import oftest.cstruct as ofp
16import oftest.message as message
17import oftest.dataplane as dataplane
18import oftest.action as action
19
Rich Laneda3b5ad2012-10-03 09:05:32 -070020from oftest.testutils import *
Ken Chiangd6f5f862012-09-28 15:40:33 -070021
22#@var cxn_port_map Local copy of the configuration map from OF port
23# numbers to OS interfaces
24cxn_port_map = None
25#@var cxn_logger Local logger object
26cxn_logger = None
27#@var cxn_config Local copy of global configuration data
28cxn_config = None
29
30test_prio = {}
31
32def test_set_init(config):
33 """
34 Set up function for connection test classes
35
36 @param config The configuration dictionary; see oft
37 """
38
39 global cxn_port_map
40 global cxn_logger
41 global cxn_config
42
43 cxn_logger = logging.getLogger("cxn")
44 cxn_logger.info("Initializing test set")
45 cxn_port_map = config["port_map"]
46 cxn_config = config
47
48class BaseHandshake(unittest.TestCase):
49 """
50 Base handshake case to set up controller, but do not send hello.
51 """
52
Ken Chiangadc950f2012-10-05 13:50:03 -070053 controllers = []
54 default_timeout = 2
55
Ken Chiangd6f5f862012-09-28 15:40:33 -070056 def sig_handler(self, v1, v2):
57 cxn_logger.critical("Received interrupt signal; exiting")
58 print "Received interrupt signal; exiting"
59 self.clean_shutdown = False
60 self.tearDown()
61 sys.exit(1)
62
63 def controllerSetup(self, host, port):
Ken Chiangadc950f2012-10-05 13:50:03 -070064 con = controller.Controller(host=host,port=port)
Ken Chiangd6f5f862012-09-28 15:40:33 -070065
66 # clean_shutdown should be set to False to force quit app
67 self.clean_shutdown = True
68 # disable initial hello so hello is under control of test
Ken Chiangadc950f2012-10-05 13:50:03 -070069 con.initial_hello = False
Ken Chiangd6f5f862012-09-28 15:40:33 -070070
Ken Chiangadc950f2012-10-05 13:50:03 -070071 con.start()
72 self.controllers.append(con)
Ken Chiangd6f5f862012-09-28 15:40:33 -070073
74 def setUp(self):
75 self.logger = cxn_logger
76 self.config = cxn_config
77 #@todo Test cases shouldn't monkey with signals; move SIGINT handler
78 # to top-level oft
79 try:
80 signal.signal(signal.SIGINT, self.sig_handler)
81 except ValueError, e:
82 cxn_logger.info("Could not set SIGINT handler: %s" % e)
83 cxn_logger.info("** START TEST CASE " + str(self))
84
Ken Chiangadc950f2012-10-05 13:50:03 -070085 self.default_timeout = test_param_get(cxn_config,
86 'default_timeout') or 2
Ken Chiangd6f5f862012-09-28 15:40:33 -070087
Ken Chiangd6f5f862012-09-28 15:40:33 -070088 def tearDown(self):
89 cxn_logger.info("** END TEST CASE " + str(self))
Ken Chiangadc950f2012-10-05 13:50:03 -070090 for con in self.controllers:
91 con.shutdown()
92 if self.clean_shutdown:
93 con.join()
Ken Chiangd6f5f862012-09-28 15:40:33 -070094
95 def runTest(self):
96 # do nothing in the base case
97 pass
98
99 def assertTrue(self, cond, msg):
100 if not cond:
101 cxn_logger.error("** FAILED ASSERTION: " + msg)
102 unittest.TestCase.assertTrue(self, cond, msg)
103
104test_prio["BaseHandshake"] = -1
105
106class HandshakeNoHello(BaseHandshake):
Ken Chiang35a74372012-10-01 15:39:25 -0700107 """
108 TCP connect to switch, but do not sent hello,
109 and wait for disconnect.
110 """
Ken Chiangd6f5f862012-09-28 15:40:33 -0700111 def runTest(self):
112 self.controllerSetup(cxn_config["controller_host"],
113 cxn_config["controller_port"])
Ken Chiangadc950f2012-10-05 13:50:03 -0700114 self.controllers[0].connect(self.default_timeout)
Ken Chiangd6f5f862012-09-28 15:40:33 -0700115 cxn_logger.info("TCP Connected " +
Ken Chiangadc950f2012-10-05 13:50:03 -0700116 str(self.controllers[0].switch_addr))
Ken Chiangd6f5f862012-09-28 15:40:33 -0700117 cxn_logger.info("Hello not sent, waiting for timeout")
118
119 # wait for controller to die
120 count = 0
Ken Chiangadc950f2012-10-05 13:50:03 -0700121 self.assertTrue(self.controllers[0].wait_disconnected(timeout=10),
122 "Not notified of controller disconnect")
Ken Chiangd6f5f862012-09-28 15:40:33 -0700123
124class HandshakeNoFeaturesRequest(BaseHandshake):
Ken Chiang35a74372012-10-01 15:39:25 -0700125 """
126 TCP connect to switch, send hello, but do not send features request,
127 and wait for disconnect.
128 """
Ken Chiangd6f5f862012-09-28 15:40:33 -0700129 def runTest(self):
130 self.controllerSetup(cxn_config["controller_host"],
131 cxn_config["controller_port"])
Ken Chiangadc950f2012-10-05 13:50:03 -0700132 self.controllers[0].connect(self.default_timeout)
Ken Chiangd6f5f862012-09-28 15:40:33 -0700133 cxn_logger.info("TCP Connected " +
Ken Chiangadc950f2012-10-05 13:50:03 -0700134 str(self.controllers[0].switch_addr))
Ken Chiangd6f5f862012-09-28 15:40:33 -0700135 cxn_logger.info("Sending hello")
Ken Chiangadc950f2012-10-05 13:50:03 -0700136 self.controllers[0].message_send(message.hello())
Ken Chiangd6f5f862012-09-28 15:40:33 -0700137
138 cxn_logger.info("Features request not sent, waiting for timeout")
139
140 # wait for controller to die
141 count = 0
Ken Chiangadc950f2012-10-05 13:50:03 -0700142 self.assertTrue(self.controllers[0].wait_disconnected(timeout=10),
143 "Not notified of controller disconnect")
Ken Chiangd6f5f862012-09-28 15:40:33 -0700144
Ken Chiang35a74372012-10-01 15:39:25 -0700145class HandshakeAndKeepalive(BaseHandshake):
146 """
147 Complete handshake and respond to echo request, but otherwise do nothing.
148 Good for manual testing.
149 """
150 def runTest(self):
Ken Chiangadc950f2012-10-05 13:50:03 -0700151 self.num_controllers = test_param_get(cxn_config,
152 'num_controllers') or 1
Ken Chiang35a74372012-10-01 15:39:25 -0700153
Ken Chiangadc950f2012-10-05 13:50:03 -0700154 for i in range(self.num_controllers):
155 self.controllerSetup(cxn_config["controller_host"],
156 cxn_config["controller_port"]+i)
157 for i in range(self.num_controllers):
158 self.controllers[i].handshake_done = False
Ken Chiang35a74372012-10-01 15:39:25 -0700159
Ken Chiangadc950f2012-10-05 13:50:03 -0700160 # try to maintain switch connections forever
161 count = 0
162 while True:
163 for con in self.controllers:
164 if con.switch_socket and con.handshake_done:
165 if count < 7:
166 cxn_logger.info(con.host + ":" + str(con.port) +
167 ": maintaining connection to " +
168 str(con.switch_addr))
169 count = count + 1
170 else:
171 cxn_logger.info(con.host + ":" + str(con.port) +
172 ": disconnecting from " +
173 str(con.switch_addr))
174 con.disconnect()
175 con.handshake_done = False
176 count = 0
177 time.sleep(1)
178 else:
179 #@todo Add an option to wait for a pkt transaction to
180 # ensure version compatibilty?
181 con.connect(self.default_timeout)
182 if not con.switch_socket:
183 cxn_logger.info("Did not connect to switch")
184 continue
185 cxn_logger.info("TCP Connected " + str(con.switch_addr))
186 cxn_logger.info("Sending hello")
187 con.message_send(message.hello())
188 request = message.features_request()
189 reply, pkt = con.transact(request,
190 timeout=self.default_timeout)
191 if reply:
192 cxn_logger.info("Handshake complete with " +
193 str(con.switch_addr))
194 con.handshake_done = True
195 con.keep_alive = True
196 else:
197 cxn_logger.info("Did not complete features_request for handshake")
198 con.disconnect()
199 con.handshake_done = False
Ken Chiang35a74372012-10-01 15:39:25 -0700200
201test_prio["HandshakeAndKeepalive"] = -1
202