blob: 8e4d932b874bb85c14130a181c8240b349c86d62 [file] [log] [blame]
Rich Lane284dc4d2014-01-06 15:24:07 -08001# Distributed under the OpenFlow Software License (see LICENSE)
2# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
3"""
4BSN gentable extension test cases
5"""
6
7import logging
8
9from oftest import config
10import oftest.base_tests as base_tests
11import ofp
12
13from oftest.testutils import *
14
15# Hardcoded in the switch to ease testing
16TABLE_ID = 0
17
Rich Laneb2c5bf62014-01-06 17:18:40 -080018def tlv_dict(tlvs):
19 d = {}
20 for tlv in tlvs:
21 d[tlv.__class__] = tlv.value
22 return d
23
Rich Lane64c4e602014-01-07 11:27:06 -080024def make_checksum(hi, lo):
25 """
26 Place 'hi' in the upper 8 bits and 'lo' in the lower bits.
27 """
28 return ((hi & 0xff) << 120) | lo
29
30assert make_checksum(0xab, 0xcd) == 0xab0000000000000000000000000000cd
31
Rich Lane284dc4d2014-01-06 15:24:07 -080032class BaseGenTableTest(base_tests.SimpleProtocol):
33 def setUp(self):
34 base_tests.SimpleProtocol.setUp(self)
Rich Laneb2c5bf62014-01-06 17:18:40 -080035 self.do_clear()
Rich Lane284dc4d2014-01-06 15:24:07 -080036
37 def tearDown(self):
Rich Laneb2c5bf62014-01-06 17:18:40 -080038 self.do_clear()
Rich Lane284dc4d2014-01-06 15:24:07 -080039 base_tests.SimpleProtocol.tearDown(self)
40
Rich Laneb2c5bf62014-01-06 17:18:40 -080041 def do_clear(self, checksum=0, checksum_mask=0):
42 request = ofp.message.bsn_gentable_clear_request(
43 table_id=TABLE_ID,
44 checksum=0,
45 checksum_mask=0)
Rich Lane284dc4d2014-01-06 15:24:07 -080046 response, _ = self.controller.transact(request)
47 self.assertIsInstance(response, ofp.message.bsn_gentable_clear_reply)
48 self.assertEquals(response.error_count, 0)
49
Rich Laneb2c5bf62014-01-06 17:18:40 -080050 def do_add(self, vlan_vid, ipv4, mac, idle_notification=False, checksum=0):
Rich Lane284dc4d2014-01-06 15:24:07 -080051 msg = ofp.message.bsn_gentable_entry_add(
52 table_id=TABLE_ID,
53 key=[
54 ofp.bsn_tlv.vlan_vid(vlan_vid),
55 ofp.bsn_tlv.ipv4(ipv4)],
56 value=[
57 ofp.bsn_tlv.mac(mac)],
Rich Laneb2c5bf62014-01-06 17:18:40 -080058 checksum=checksum)
Rich Lane284dc4d2014-01-06 15:24:07 -080059 if idle_notification:
60 msg.value.append(ofp.bsn_tlv.idle_notification())
61 self.controller.message_send(msg)
62
63 def do_delete(self, vlan_vid, ipv4):
64 msg = ofp.message.bsn_gentable_entry_delete(
65 table_id=TABLE_ID,
66 key=[
67 ofp.bsn_tlv.vlan_vid(vlan_vid),
68 ofp.bsn_tlv.ipv4(ipv4)])
69 self.controller.message_send(msg)
70
Rich Laneb2c5bf62014-01-06 17:18:40 -080071 def do_entry_stats(self, checksum=0, checksum_mask=0):
72 request = ofp.message.bsn_gentable_entry_stats_request(
73 table_id=TABLE_ID,
74 checksum=checksum,
75 checksum_mask=checksum_mask)
76 return get_stats(self, request)
77
78 def do_entry_desc_stats(self, checksum=0, checksum_mask=0):
79 request = ofp.message.bsn_gentable_entry_desc_stats_request(
80 table_id=TABLE_ID,
81 checksum=checksum,
82 checksum_mask=checksum_mask)
83 return get_stats(self, request)
84
Rich Lane4e691ad2014-01-06 17:45:20 -080085 def do_table_desc_stats(self):
86 request = ofp.message.bsn_gentable_desc_stats_request()
87 return get_stats(self, request)
88
Rich Lanea8f56672014-01-06 17:50:39 -080089 def do_table_stats(self):
90 request = ofp.message.bsn_gentable_stats_request()
91 return get_stats(self, request)
92
Rich Lane64c4e602014-01-07 11:27:06 -080093 def do_test_table_stats(self):
94 entries = self.do_table_stats()
95 for entry in entries:
96 if entry.table_id == TABLE_ID:
97 return entry
98 raise AssertionError("did not find test table")
99
Rich Lane284dc4d2014-01-06 15:24:07 -0800100class ClearAll(BaseGenTableTest):
101 """
102 Test clearing entire table
103 """
104 def runTest(self):
105 # Add a few entries
106 for i in range(0, 3):
107 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i))
108
109 do_barrier(self.controller)
110 verify_no_errors(self.controller)
111
112 # Delete all entries
113 request = ofp.message.bsn_gentable_clear_request(table_id=TABLE_ID)
114 response, _ = self.controller.transact(request)
115 self.assertIsInstance(response, ofp.message.bsn_gentable_clear_reply)
116 self.assertEquals(response.error_count, 0)
117 self.assertEquals(response.deleted_count, 3)
118
119class AddDelete(BaseGenTableTest):
120 """
121 Test adding and deleting entries
122 """
123 def runTest(self):
124 # Add a few entries
125 for i in range(0, 3):
126 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i))
127
128 do_barrier(self.controller)
129 verify_no_errors(self.controller)
130
131 # Delete each entry
132 for i in range(0, 3):
133 self.do_delete(vlan_vid=i, ipv4=0x12345678)
134
135 do_barrier(self.controller)
136 verify_no_errors(self.controller)
137
138 # Clear table, but expect it to have already been empty
139 request = ofp.message.bsn_gentable_clear_request(table_id=TABLE_ID)
140 response, _ = self.controller.transact(request)
141 self.assertIsInstance(response, ofp.message.bsn_gentable_clear_reply)
142 self.assertEquals(response.error_count, 0)
143 self.assertEquals(response.deleted_count, 0)
Rich Laneb2c5bf62014-01-06 17:18:40 -0800144
145class EntryStats(BaseGenTableTest):
146 """
147 Test retrieving entry stats
148 """
149 def runTest(self):
150 # Add a few entries
151 for i in range(0, 3):
152 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i))
153
154 do_barrier(self.controller)
155 verify_no_errors(self.controller)
156
157 entries = self.do_entry_stats()
158 seen = set()
159 for entry in entries:
160 logging.debug(entry.show())
161 key = tlv_dict(entry.key)
162 stats = tlv_dict(entry.stats)
163 self.assertIn(ofp.bsn_tlv.vlan_vid, key)
164 self.assertIn(ofp.bsn_tlv.ipv4, key)
165 self.assertIn(ofp.bsn_tlv.rx_packets, stats)
166 self.assertIn(ofp.bsn_tlv.tx_packets, stats)
167 vlan_vid = key[ofp.bsn_tlv.vlan_vid]
168 seen.add(vlan_vid)
169 self.assertEqual(key[ofp.bsn_tlv.ipv4], 0x12345678)
170 self.assertEqual(stats[ofp.bsn_tlv.rx_packets], 100 * vlan_vid)
171 self.assertEqual(stats[ofp.bsn_tlv.tx_packets], 101 * vlan_vid)
172
173 self.assertEquals(seen, set([0, 1, 2]))
174
175class EntryDescStats(BaseGenTableTest):
176 """
177 Test retrieving entry desc stats
178 """
179 def runTest(self):
180 # Add a few entries
181 for i in range(0, 3):
182 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
183 checksum=0xfedcba9876543210fedcba9876543210 + i)
184
185 do_barrier(self.controller)
186 verify_no_errors(self.controller)
187
188 entries = self.do_entry_desc_stats()
189 seen = set()
190 for entry in entries:
191 logging.debug(entry.show())
192 key = tlv_dict(entry.key)
193 value = tlv_dict(entry.value)
194 self.assertIn(ofp.bsn_tlv.vlan_vid, key)
195 self.assertIn(ofp.bsn_tlv.ipv4, key)
196 self.assertIn(ofp.bsn_tlv.mac, value)
197 vlan_vid = key[ofp.bsn_tlv.vlan_vid]
198 seen.add(vlan_vid)
199 self.assertEqual(key[ofp.bsn_tlv.ipv4], 0x12345678)
200 self.assertEqual(value[ofp.bsn_tlv.mac], [0, 1, 2, 3, 4, vlan_vid])
201 self.assertEqual(entry.checksum, 0xfedcba9876543210fedcba9876543210 + vlan_vid)
202
203 self.assertEquals(seen, set([0, 1, 2]))
Rich Lane4e691ad2014-01-06 17:45:20 -0800204
205class TableDescStats(BaseGenTableTest):
206 """
207 Test retrieving table desc stats
208 """
209 def runTest(self):
210 entries = self.do_table_desc_stats()
211 seen = set()
212 for entry in entries:
213 logging.debug(entry.show())
214 self.assertNotIn(entry.table_id, seen)
215 self.assertNotIn(entry.name, seen)
216 seen.add(entry.table_id)
217 seen.add(entry.name)
218 if entry.table_id == TABLE_ID:
219 self.assertEqual(entry.name, "test")
220 self.assertEqual(entry.buckets_size, 64)
221 self.assertEqual(entry.max_entries, 1000)
222
223 self.assertIn(TABLE_ID, seen)
Rich Lanea8f56672014-01-06 17:50:39 -0800224
225class TableStats(BaseGenTableTest):
226 """
227 Test retrieving table stats
228 """
229 def runTest(self):
Rich Lane64c4e602014-01-07 11:27:06 -0800230 # Verify we have the test table and no duplicates
Rich Lanea8f56672014-01-06 17:50:39 -0800231 entries = self.do_table_stats()
232 seen = set()
233 for entry in entries:
234 logging.debug(entry.show())
235 self.assertNotIn(entry.table_id, seen)
236 seen.add(entry.table_id)
237 if entry.table_id == TABLE_ID:
238 self.assertEqual(entry.entry_count, 0)
239 self.assertEqual(entry.checksum, 0)
Rich Lanea8f56672014-01-06 17:50:39 -0800240 self.assertIn(TABLE_ID, seen)
Rich Lane64c4e602014-01-07 11:27:06 -0800241
242 table_checksum = 0
243
244 # Add a bunch of entries, spread among the checksum buckets
245 for i in range(0, 256):
246 table_checksum ^= make_checksum(i, i*31)
247 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
248 checksum=make_checksum(i, i*31))
249
250 do_barrier(self.controller)
251 verify_no_errors(self.controller)
252
253 table_stats = self.do_test_table_stats()
254 self.assertEqual(table_stats.entry_count, 256)
255 self.assertEqual(table_stats.checksum, table_checksum)
256
257 # Modify an entry, changing its checksum
258 i = 30
259 table_checksum ^= make_checksum(i, i*31) # subtract old checksum
260 table_checksum ^= make_checksum(i, i*37) # add new checksum
261 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 4, 3, 2, 1, i),
262 checksum=make_checksum(i, i*37))
263
264 do_barrier(self.controller)
265 verify_no_errors(self.controller)
266
267 table_stats = self.do_test_table_stats()
268 self.assertEqual(table_stats.entry_count, 256)
269 self.assertEqual(table_stats.checksum, table_checksum)
270
271 # Delete an entry
272 i = 87
273 table_checksum ^= make_checksum(i, i*31)
274 self.do_delete(vlan_vid=i, ipv4=0x12345678)
275
276 do_barrier(self.controller)
277 verify_no_errors(self.controller)
278
279 table_stats = self.do_test_table_stats()
280 self.assertEqual(table_stats.entry_count, 255)
281 self.assertEqual(table_stats.checksum, table_checksum)