blob: b658074a7cea338e6f40c9579b6afa0e1cd2d8f3 [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
53 def sig_handler(self, v1, v2):
54 cxn_logger.critical("Received interrupt signal; exiting")
55 print "Received interrupt signal; exiting"
56 self.clean_shutdown = False
57 self.tearDown()
58 sys.exit(1)
59
60 def controllerSetup(self, host, port):
61 self.controller = controller.Controller(host=host,port=port)
62
63 # clean_shutdown should be set to False to force quit app
64 self.clean_shutdown = True
65 # disable initial hello so hello is under control of test
66 self.controller.initial_hello = False
67
68 self.controller.start()
69 #@todo Add an option to wait for a pkt transaction to ensure version
70 # compatibilty?
71 self.controller.connect(timeout=10)
72 self.assertTrue(self.controller.active,
73 "Controller startup failed, not active")
74 self.assertTrue(self.controller.switch_addr is not None,
75 "Controller startup failed, no switch addr")
76
77 def setUp(self):
78 self.logger = cxn_logger
79 self.config = cxn_config
80 #@todo Test cases shouldn't monkey with signals; move SIGINT handler
81 # to top-level oft
82 try:
83 signal.signal(signal.SIGINT, self.sig_handler)
84 except ValueError, e:
85 cxn_logger.info("Could not set SIGINT handler: %s" % e)
86 cxn_logger.info("** START TEST CASE " + str(self))
87
88 self.test_timeout = test_param_get(cxn_config,
89 'handshake_timeout') or 60
90
91 def inheritSetup(self, parent):
92 """
93 Inherit the setup of a parent
94
95 This allows running at test from within another test. Do the
96 following:
97
98 sub_test = SomeTestClass() # Create an instance of the test class
99 sub_test.inheritSetup(self) # Inherit setup of parent
100 sub_test.runTest() # Run the test
101
102 Normally, only the parent's setUp and tearDown are called and
103 the state after the sub_test is run must be taken into account
104 by subsequent operations.
105 """
106 self.logger = parent.logger
107 self.config = parent.config
108 cxn_logger.info("** Setup " + str(self) +
109 " inheriting from " + str(parent))
110 self.controller = parent.controller
111
112 def tearDown(self):
113 cxn_logger.info("** END TEST CASE " + str(self))
114 self.controller.shutdown()
115 if self.clean_shutdown:
116 self.controller.join()
117
118 def runTest(self):
119 # do nothing in the base case
120 pass
121
122 def assertTrue(self, cond, msg):
123 if not cond:
124 cxn_logger.error("** FAILED ASSERTION: " + msg)
125 unittest.TestCase.assertTrue(self, cond, msg)
126
127test_prio["BaseHandshake"] = -1
128
129class HandshakeNoHello(BaseHandshake):
Ken Chiang35a74372012-10-01 15:39:25 -0700130 """
131 TCP connect to switch, but do not sent hello,
132 and wait for disconnect.
133 """
Ken Chiangd6f5f862012-09-28 15:40:33 -0700134 def runTest(self):
135 self.controllerSetup(cxn_config["controller_host"],
136 cxn_config["controller_port"])
137
138 cxn_logger.info("TCP Connected " +
139 str(self.controller.switch_addr))
140 cxn_logger.info("Hello not sent, waiting for timeout")
141
142 # wait for controller to die
143 count = 0
144 while self.controller.active and count < self.test_timeout:
145 time.sleep(1)
146 count = count + 1
147 self.assertTrue(not self.controller.active,
148 "Expected controller disconnect, but still active")
149
150class HandshakeNoFeaturesRequest(BaseHandshake):
Ken Chiang35a74372012-10-01 15:39:25 -0700151 """
152 TCP connect to switch, send hello, but do not send features request,
153 and wait for disconnect.
154 """
Ken Chiangd6f5f862012-09-28 15:40:33 -0700155 def runTest(self):
156 self.controllerSetup(cxn_config["controller_host"],
157 cxn_config["controller_port"])
158
159 cxn_logger.info("TCP Connected " +
160 str(self.controller.switch_addr))
161 cxn_logger.info("Sending hello")
162 self.controller.message_send(message.hello())
163
164 cxn_logger.info("Features request not sent, waiting for timeout")
165
166 # wait for controller to die
167 count = 0
168 while self.controller.active and count < self.test_timeout:
169 time.sleep(1)
170 count = count + 1
171 self.assertTrue(not self.controller.active,
172 "Expected controller disconnect, but still active")
173
Ken Chiang35a74372012-10-01 15:39:25 -0700174class HandshakeAndKeepalive(BaseHandshake):
175 """
176 Complete handshake and respond to echo request, but otherwise do nothing.
177 Good for manual testing.
178 """
179 def runTest(self):
180 self.controllerSetup(cxn_config["controller_host"],
181 cxn_config["controller_port"])
182
183 cxn_logger.info("TCP Connected " +
184 str(self.controller.switch_addr))
185 cxn_logger.info("Sending hello")
186 self.controller.message_send(message.hello())
187
188 request = message.features_request()
189 reply, pkt = self.controller.transact(request, timeout=20)
190 self.assertTrue(reply is not None,
191 "Did not complete features_request for handshake")
192 cxn_logger.info("Handshake complete with " +
193 str(self.controller.switch_addr))
194
195 self.controller.keep_alive = True
196
197 # keep controller up forever
198 while self.controller.active:
199 time.sleep(1)
200
201 self.assertTrue(not self.controller.active,
202 "Expected controller disconnect, but still active")
203
204test_prio["HandshakeAndKeepalive"] = -1
205