blob: 7f29db5123bbd1086bc05b71d9f2c763c4569e12 [file] [log] [blame]
Rich Laneb90a1c42012-10-05 09:16:05 -07001"""
2Base classes for test cases
3
4Tests will usually inherit from one of these classes to have the controller
5and/or dataplane automatically set up.
6"""
7
8import logging
9import unittest
10
11from oftest import config
12import oftest.controller as controller
13import oftest.cstruct as ofp
14import oftest.message as message
15import oftest.dataplane as dataplane
16import oftest.action as action
17
18from oftest.testutils import *
19
20class SimpleProtocol(unittest.TestCase):
21 """
22 Root class for setting up the controller
23 """
24
25 def setUp(self):
26 logging.info("** START TEST CASE " + str(self))
27 self.controller = controller.Controller(
Dan Talayco69ca4d62012-11-15 11:50:22 -080028 switch=config["switch_ip"],
Rich Laneb90a1c42012-10-05 09:16:05 -070029 host=config["controller_host"],
30 port=config["controller_port"])
31 # clean_shutdown should be set to False to force quit app
32 self.clean_shutdown = True
33 self.controller.start()
34 #@todo Add an option to wait for a pkt transaction to ensure version
35 # compatibilty?
36 self.controller.connect(timeout=20)
37
38 # By default, respond to echo requests
39 self.controller.keep_alive = True
40
41 if not self.controller.active:
42 raise Exception("Controller startup failed")
43 if self.controller.switch_addr is None:
44 raise Exception("Controller startup failed (no switch addr)")
45 logging.info("Connected " + str(self.controller.switch_addr))
46 request = message.features_request()
47 reply, pkt = self.controller.transact(request)
48 self.assertTrue(reply is not None,
49 "Did not complete features_request for handshake")
50 self.supported_actions = reply.actions
51 logging.info("Supported actions: " + hex(self.supported_actions))
52
53 def inheritSetup(self, parent):
54 """
55 Inherit the setup of a parent
56
57 This allows running at test from within another test. Do the
58 following:
59
60 sub_test = SomeTestClass() # Create an instance of the test class
61 sub_test.inheritSetup(self) # Inherit setup of parent
62 sub_test.runTest() # Run the test
63
64 Normally, only the parent's setUp and tearDown are called and
65 the state after the sub_test is run must be taken into account
66 by subsequent operations.
67 """
68 logging.info("** Setup " + str(self) + " inheriting from "
69 + str(parent))
70 self.controller = parent.controller
71 self.supported_actions = parent.supported_actions
72
73 def tearDown(self):
74 logging.info("** END TEST CASE " + str(self))
75 self.controller.shutdown()
76 #@todo Review if join should be done on clean_shutdown
77 if self.clean_shutdown:
78 self.controller.join()
Rich Lanee7b0ecb2012-12-26 10:01:01 -080079 del self.controller
Rich Laneb90a1c42012-10-05 09:16:05 -070080
81 def runTest(self):
82 # Just a simple sanity check as illustration
83 logging.info("Running simple proto test")
84 self.assertTrue(self.controller.switch_socket is not None,
85 str(self) + 'No connection to switch')
86
87 def assertTrue(self, cond, msg):
88 if not cond:
89 logging.error("** FAILED ASSERTION: " + msg)
90 unittest.TestCase.assertTrue(self, cond, msg)
91
92class SimpleDataPlane(SimpleProtocol):
93 """
94 Root class that sets up the controller and dataplane
95 """
96 def setUp(self):
97 SimpleProtocol.setUp(self)
98 self.dataplane = dataplane.DataPlane(config)
99 for of_port, ifname in config["port_map"].items():
100 self.dataplane.port_add(ifname, of_port)
101
102 def inheritSetup(self, parent):
103 """
104 Inherit the setup of a parent
105
106 See SimpleProtocol.inheritSetup
107 """
108 SimpleProtocol.inheritSetup(self, parent)
109 self.dataplane = parent.dataplane
110
111 def tearDown(self):
112 logging.info("Teardown for simple dataplane test")
113 SimpleProtocol.tearDown(self)
114 if hasattr(self, 'dataplane'):
115 self.dataplane.kill(join_threads=self.clean_shutdown)
Rich Lanee7b0ecb2012-12-26 10:01:01 -0800116 del self.dataplane
Rich Laneb90a1c42012-10-05 09:16:05 -0700117 logging.info("Teardown done")
118
119 def runTest(self):
120 self.assertTrue(self.controller.switch_socket is not None,
121 str(self) + 'No connection to switch')
122 # self.dataplane.show()
123 # Would like an assert that checks the data plane
124
125class DataPlaneOnly(unittest.TestCase):
126 """
127 Root class that sets up only the dataplane
128 """
129
130 def setUp(self):
131 self.clean_shutdown = True
132 logging.info("** START DataPlaneOnly CASE " + str(self))
133 self.dataplane = dataplane.DataPlane(config)
134 for of_port, ifname in config["port_map"].items():
135 self.dataplane.port_add(ifname, of_port)
136
137 def tearDown(self):
138 logging.info("Teardown for simple dataplane test")
139 self.dataplane.kill(join_threads=self.clean_shutdown)
Rich Lanee7b0ecb2012-12-26 10:01:01 -0800140 del self.dataplane
Rich Laneb90a1c42012-10-05 09:16:05 -0700141 logging.info("Teardown done")
142
143 def runTest(self):
144 logging.info("DataPlaneOnly")
145 # self.dataplane.show()
146 # Would like an assert that checks the data plane