blob: a2b25acb8860a2b41a09376ff1f9200472e37f24 [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
Rich Lane472aaea2013-08-27 09:27:38 -070010import os
Rich Laneb90a1c42012-10-05 09:16:05 -070011
Rich Lane2c7812c2012-12-27 17:52:23 -080012import oftest
Rich Laneb90a1c42012-10-05 09:16:05 -070013from oftest import config
14import oftest.controller as controller
Rich Laneb90a1c42012-10-05 09:16:05 -070015import oftest.dataplane as dataplane
Rich Lane9fd05682013-01-10 15:30:38 -080016import ofp
Rich Laneb90a1c42012-10-05 09:16:05 -070017
Rich Lane69fd8e02013-08-23 16:23:42 -070018class BaseTest(unittest.TestCase):
19 def __str__(self):
20 return self.id().replace('.runTest', '')
21
22 def setUp(self):
23 oftest.open_logfile(str(self))
24 logging.info("** START TEST CASE " + str(self))
25
26 def tearDown(self):
27 logging.info("** END TEST CASE " + str(self))
28
29class SimpleProtocol(BaseTest):
Rich Laneb90a1c42012-10-05 09:16:05 -070030 """
31 Root class for setting up the controller
32 """
33
34 def setUp(self):
Rich Lane69fd8e02013-08-23 16:23:42 -070035 BaseTest.setUp(self)
36
Rich Laneb90a1c42012-10-05 09:16:05 -070037 self.controller = controller.Controller(
Dan Talayco69ca4d62012-11-15 11:50:22 -080038 switch=config["switch_ip"],
Rich Laneb90a1c42012-10-05 09:16:05 -070039 host=config["controller_host"],
40 port=config["controller_port"])
Rich Laneb90a1c42012-10-05 09:16:05 -070041 self.controller.start()
Rich Laneb90a1c42012-10-05 09:16:05 -070042
Rich Laned5915042012-12-31 14:58:35 -080043 try:
44 #@todo Add an option to wait for a pkt transaction to ensure version
45 # compatibilty?
46 self.controller.connect(timeout=20)
47
48 # By default, respond to echo requests
49 self.controller.keep_alive = True
50
51 if not self.controller.active:
52 raise Exception("Controller startup failed")
53 if self.controller.switch_addr is None:
54 raise Exception("Controller startup failed (no switch addr)")
55 logging.info("Connected " + str(self.controller.switch_addr))
Rich Lane78ef8b92013-01-10 12:19:23 -080056 request = ofp.message.features_request()
Rich Laned5915042012-12-31 14:58:35 -080057 reply, pkt = self.controller.transact(request)
58 self.assertTrue(reply is not None,
59 "Did not complete features_request for handshake")
Rich Laneb73808c2013-03-11 15:22:23 -070060 if reply.version == 1:
Rich Laneaf428152013-01-10 12:24:44 -080061 self.supported_actions = reply.actions
62 logging.info("Supported actions: " + hex(self.supported_actions))
Rich Laned5915042012-12-31 14:58:35 -080063 except:
64 self.controller.kill()
65 del self.controller
66 raise
Rich Laneb90a1c42012-10-05 09:16:05 -070067
68 def inheritSetup(self, parent):
69 """
70 Inherit the setup of a parent
71
72 This allows running at test from within another test. Do the
73 following:
74
75 sub_test = SomeTestClass() # Create an instance of the test class
76 sub_test.inheritSetup(self) # Inherit setup of parent
77 sub_test.runTest() # Run the test
78
79 Normally, only the parent's setUp and tearDown are called and
80 the state after the sub_test is run must be taken into account
81 by subsequent operations.
82 """
83 logging.info("** Setup " + str(self) + " inheriting from "
84 + str(parent))
85 self.controller = parent.controller
86 self.supported_actions = parent.supported_actions
87
88 def tearDown(self):
Rich Laneb90a1c42012-10-05 09:16:05 -070089 self.controller.shutdown()
Rich Lane7c64a422012-12-31 13:46:34 -080090 self.controller.join()
Rich Lanee7b0ecb2012-12-26 10:01:01 -080091 del self.controller
Rich Lane69fd8e02013-08-23 16:23:42 -070092 BaseTest.tearDown(self)
Rich Laneb90a1c42012-10-05 09:16:05 -070093
Rich Laneb90a1c42012-10-05 09:16:05 -070094 def assertTrue(self, cond, msg):
95 if not cond:
96 logging.error("** FAILED ASSERTION: " + msg)
97 unittest.TestCase.assertTrue(self, cond, msg)
98
99class SimpleDataPlane(SimpleProtocol):
100 """
101 Root class that sets up the controller and dataplane
102 """
103 def setUp(self):
104 SimpleProtocol.setUp(self)
Rich Lane2c7812c2012-12-27 17:52:23 -0800105 self.dataplane = oftest.dataplane_instance
106 self.dataplane.flush()
Rich Lane472aaea2013-08-27 09:27:38 -0700107 if config["log_dir"] != None:
108 filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
109 self.dataplane.start_pcap(filename)
Rich Laneb90a1c42012-10-05 09:16:05 -0700110
111 def inheritSetup(self, parent):
112 """
113 Inherit the setup of a parent
114
115 See SimpleProtocol.inheritSetup
116 """
117 SimpleProtocol.inheritSetup(self, parent)
118 self.dataplane = parent.dataplane
119
120 def tearDown(self):
Rich Lane472aaea2013-08-27 09:27:38 -0700121 if config["log_dir"] != None:
122 self.dataplane.stop_pcap()
Rich Laneb90a1c42012-10-05 09:16:05 -0700123 SimpleProtocol.tearDown(self)
Rich Laneb90a1c42012-10-05 09:16:05 -0700124
Rich Lane69fd8e02013-08-23 16:23:42 -0700125class DataPlaneOnly(BaseTest):
Rich Laneb90a1c42012-10-05 09:16:05 -0700126 """
127 Root class that sets up only the dataplane
128 """
129
130 def setUp(self):
Rich Lane69fd8e02013-08-23 16:23:42 -0700131 BaseTest.setUp(self)
Rich Lane2c7812c2012-12-27 17:52:23 -0800132 self.dataplane = oftest.dataplane_instance
133 self.dataplane.flush()
Rich Lane472aaea2013-08-27 09:27:38 -0700134 if config["log_dir"] != None:
135 filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
136 self.dataplane.start_pcap(filename)
Rich Laneb90a1c42012-10-05 09:16:05 -0700137
138 def tearDown(self):
Rich Lane472aaea2013-08-27 09:27:38 -0700139 if config["log_dir"] != None:
140 self.dataplane.stop_pcap()
Rich Lane69fd8e02013-08-23 16:23:42 -0700141 BaseTest.tearDown(self)