blob: fa7b28d57f2ebe3fbfe9ed09e70d1857cd6ad5d5 [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
Rich Lane232d2ab2014-01-07 12:23:16 -08008import math
Rich Lane14e4c142014-01-09 10:31:08 -08009import random
Rich Lane284dc4d2014-01-06 15:24:07 -080010
11from oftest import config
12import oftest.base_tests as base_tests
13import ofp
14
15from oftest.testutils import *
16
17# Hardcoded in the switch to ease testing
18TABLE_ID = 0
19
Rich Laneb2c5bf62014-01-06 17:18:40 -080020def tlv_dict(tlvs):
21 d = {}
22 for tlv in tlvs:
23 d[tlv.__class__] = tlv.value
24 return d
25
Rich Lane64c4e602014-01-07 11:27:06 -080026def make_checksum(hi, lo):
27 """
28 Place 'hi' in the upper 8 bits and 'lo' in the lower bits.
29 """
30 return ((hi & 0xff) << 120) | lo
31
32assert make_checksum(0xab, 0xcd) == 0xab0000000000000000000000000000cd
33
Rich Lane284dc4d2014-01-06 15:24:07 -080034class BaseGenTableTest(base_tests.SimpleProtocol):
35 def setUp(self):
36 base_tests.SimpleProtocol.setUp(self)
Rich Laneb2c5bf62014-01-06 17:18:40 -080037 self.do_clear()
Rich Lane284dc4d2014-01-06 15:24:07 -080038
39 def tearDown(self):
Rich Laneb2c5bf62014-01-06 17:18:40 -080040 self.do_clear()
Rich Lane284dc4d2014-01-06 15:24:07 -080041 base_tests.SimpleProtocol.tearDown(self)
42
Rich Laneb2c5bf62014-01-06 17:18:40 -080043 def do_clear(self, checksum=0, checksum_mask=0):
44 request = ofp.message.bsn_gentable_clear_request(
45 table_id=TABLE_ID,
Rich Lane20f6b592014-01-08 15:17:50 -080046 checksum=checksum,
47 checksum_mask=checksum_mask)
Rich Lane284dc4d2014-01-06 15:24:07 -080048 response, _ = self.controller.transact(request)
49 self.assertIsInstance(response, ofp.message.bsn_gentable_clear_reply)
Rich Lane20f6b592014-01-08 15:17:50 -080050 return response.deleted_count, response.error_count
Rich Lane284dc4d2014-01-06 15:24:07 -080051
Rich Laneb2c5bf62014-01-06 17:18:40 -080052 def do_add(self, vlan_vid, ipv4, mac, idle_notification=False, checksum=0):
Rich Lane284dc4d2014-01-06 15:24:07 -080053 msg = ofp.message.bsn_gentable_entry_add(
54 table_id=TABLE_ID,
55 key=[
56 ofp.bsn_tlv.vlan_vid(vlan_vid),
57 ofp.bsn_tlv.ipv4(ipv4)],
58 value=[
59 ofp.bsn_tlv.mac(mac)],
Rich Laneb2c5bf62014-01-06 17:18:40 -080060 checksum=checksum)
Rich Lane284dc4d2014-01-06 15:24:07 -080061 if idle_notification:
62 msg.value.append(ofp.bsn_tlv.idle_notification())
63 self.controller.message_send(msg)
64
65 def do_delete(self, vlan_vid, ipv4):
66 msg = ofp.message.bsn_gentable_entry_delete(
67 table_id=TABLE_ID,
68 key=[
69 ofp.bsn_tlv.vlan_vid(vlan_vid),
70 ofp.bsn_tlv.ipv4(ipv4)])
71 self.controller.message_send(msg)
72
Rich Laneb2c5bf62014-01-06 17:18:40 -080073 def do_entry_stats(self, checksum=0, checksum_mask=0):
74 request = ofp.message.bsn_gentable_entry_stats_request(
75 table_id=TABLE_ID,
76 checksum=checksum,
77 checksum_mask=checksum_mask)
78 return get_stats(self, request)
79
80 def do_entry_desc_stats(self, checksum=0, checksum_mask=0):
81 request = ofp.message.bsn_gentable_entry_desc_stats_request(
82 table_id=TABLE_ID,
83 checksum=checksum,
84 checksum_mask=checksum_mask)
85 return get_stats(self, request)
86
Rich Lane4e691ad2014-01-06 17:45:20 -080087 def do_table_desc_stats(self):
88 request = ofp.message.bsn_gentable_desc_stats_request()
89 return get_stats(self, request)
90
Rich Lanea8f56672014-01-06 17:50:39 -080091 def do_table_stats(self):
92 request = ofp.message.bsn_gentable_stats_request()
93 return get_stats(self, request)
94
Rich Lane64c4e602014-01-07 11:27:06 -080095 def do_test_table_stats(self):
96 entries = self.do_table_stats()
97 for entry in entries:
98 if entry.table_id == TABLE_ID:
99 return entry
100 raise AssertionError("did not find test table")
101
Rich Lane232d2ab2014-01-07 12:23:16 -0800102 def do_bucket_stats(self):
103 request = ofp.message.bsn_gentable_bucket_stats_request(table_id=TABLE_ID)
104 return get_stats(self, request)
105
Rich Lane78bd3772014-01-08 11:51:13 -0800106 def do_set_buckets_size(self, buckets_size):
107 msg = ofp.message.bsn_gentable_set_buckets_size(
108 table_id=TABLE_ID,
109 buckets_size=buckets_size)
110 self.controller.message_send(msg)
111
Rich Lane284dc4d2014-01-06 15:24:07 -0800112class ClearAll(BaseGenTableTest):
113 """
114 Test clearing entire table
115 """
116 def runTest(self):
117 # Add a few entries
118 for i in range(0, 3):
119 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i))
120
121 do_barrier(self.controller)
122 verify_no_errors(self.controller)
123
124 # Delete all entries
Rich Lane20f6b592014-01-08 15:17:50 -0800125 deleted, errors = self.do_clear(checksum=0, checksum_mask=0)
126 self.assertEquals(deleted, 3)
127 self.assertEquals(errors, 0)
128
129class ClearMasked(BaseGenTableTest):
130 """
131 Test clearing with a checksum mask
132 """
133 def runTest(self):
134 # Add 4 entries to each checksum bucket
135 for i in range(0, 256):
136 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
137 checksum=make_checksum(i, i*31))
138
139 do_barrier(self.controller)
140 verify_no_errors(self.controller)
141
142 # Delete bucket 0
143 deleted, errors = self.do_clear(make_checksum(0, 0), make_checksum(0xFC, 0))
144 self.assertEquals(deleted, 4)
145 self.assertEquals(errors, 0)
146
147 # Delete buckets 0 (already cleared), 1, 2, 3
148 deleted, errors = self.do_clear(make_checksum(0, 0), make_checksum(0xF0, 0))
149 self.assertEquals(deleted, 12)
150 self.assertEquals(errors, 0)
151
152 # Delete second half of bucket 4
153 deleted, errors = self.do_clear(make_checksum(0x10, 0), make_checksum(0xFE, 0))
154 self.assertEquals(deleted, 2)
155 self.assertEquals(errors, 0)
Rich Lane284dc4d2014-01-06 15:24:07 -0800156
157class AddDelete(BaseGenTableTest):
158 """
159 Test adding and deleting entries
160 """
161 def runTest(self):
162 # Add a few entries
163 for i in range(0, 3):
164 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i))
165
166 do_barrier(self.controller)
167 verify_no_errors(self.controller)
168
169 # Delete each entry
170 for i in range(0, 3):
171 self.do_delete(vlan_vid=i, ipv4=0x12345678)
172
173 do_barrier(self.controller)
174 verify_no_errors(self.controller)
175
176 # Clear table, but expect it to have already been empty
177 request = ofp.message.bsn_gentable_clear_request(table_id=TABLE_ID)
178 response, _ = self.controller.transact(request)
179 self.assertIsInstance(response, ofp.message.bsn_gentable_clear_reply)
180 self.assertEquals(response.error_count, 0)
181 self.assertEquals(response.deleted_count, 0)
Rich Laneb2c5bf62014-01-06 17:18:40 -0800182
183class EntryStats(BaseGenTableTest):
184 """
185 Test retrieving entry stats
186 """
187 def runTest(self):
188 # Add a few entries
189 for i in range(0, 3):
190 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i))
191
192 do_barrier(self.controller)
193 verify_no_errors(self.controller)
194
195 entries = self.do_entry_stats()
196 seen = set()
197 for entry in entries:
198 logging.debug(entry.show())
199 key = tlv_dict(entry.key)
200 stats = tlv_dict(entry.stats)
201 self.assertIn(ofp.bsn_tlv.vlan_vid, key)
202 self.assertIn(ofp.bsn_tlv.ipv4, key)
203 self.assertIn(ofp.bsn_tlv.rx_packets, stats)
204 self.assertIn(ofp.bsn_tlv.tx_packets, stats)
205 vlan_vid = key[ofp.bsn_tlv.vlan_vid]
206 seen.add(vlan_vid)
207 self.assertEqual(key[ofp.bsn_tlv.ipv4], 0x12345678)
208 self.assertEqual(stats[ofp.bsn_tlv.rx_packets], 100 * vlan_vid)
209 self.assertEqual(stats[ofp.bsn_tlv.tx_packets], 101 * vlan_vid)
210
211 self.assertEquals(seen, set([0, 1, 2]))
212
Rich Lane790cc202014-01-08 14:54:25 -0800213class EntryStatsMasked(BaseGenTableTest):
214 """
215 Test retrieving entry stats with a checksum mask
216 """
217 def runTest(self):
218 def get_range(checksum, checksum_mask):
219 entries = self.do_entry_stats(checksum, checksum_mask)
220 vlan_vids = []
221 for entry in entries:
222 key = tlv_dict(entry.key)
223 vlan_vids.append(key[ofp.bsn_tlv.vlan_vid])
224 return sorted(vlan_vids)
225
226 # Add 4 entries to each checksum bucket
227 for i in range(0, 256):
228 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
229 checksum=make_checksum(i, i))
230
231 do_barrier(self.controller)
232 verify_no_errors(self.controller)
233
234 # Check first bucket
235 self.assertEquals(get_range(make_checksum(0, 0), make_checksum(0xFC, 0)),
236 [0, 1, 2, 3])
237
238 # Check last bucket
239 self.assertEquals(get_range(make_checksum(0xFC, 0), make_checksum(0xFC, 0)),
240 [252, 253, 254, 255])
241
242 # Check first half of first bucket
243 self.assertEquals(get_range(make_checksum(0x00, 0), make_checksum(0xFE, 0)),
244 [0, 1])
245
246 # Check second half of first bucket
247 self.assertEquals(get_range(make_checksum(0x02, 0), make_checksum(0xFE, 0)),
248 [2, 3])
249
250 # Check first half of last bucket
251 self.assertEquals(get_range(make_checksum(0xFC, 0), make_checksum(0xFE, 0)),
252 [252, 253])
253
254 # Check second half of last bucket
255 self.assertEquals(get_range(make_checksum(0xFE, 0), make_checksum(0xFE, 0)),
256 [254, 255])
257
258 # Check first two buckets
259 self.assertEquals(get_range(make_checksum(0, 0), make_checksum(0xF8, 0)),
260 [0, 1, 2, 3, 4, 5, 6, 7])
261
262 # Check last two buckets
263 self.assertEquals(get_range(make_checksum(0xF8, 0), make_checksum(0xF8, 0)),
264 [248, 249, 250, 251, 252, 253, 254, 255])
265
266 # Check matching on low bits
267 self.assertEquals(get_range(make_checksum(0x00, 0x00), ~1), [0])
268 self.assertEquals(get_range(make_checksum(0x01, 0x00), ~1), [1])
269 self.assertEquals(get_range(make_checksum(0x01, 0x02), ~1), [])
270
Rich Lane464960b2014-01-08 17:30:07 -0800271class EntryStatsFragmented(BaseGenTableTest):
272 """
273 Test retrieving entry stats in mutiple replies
274 """
275 def runTest(self):
276 # Add a bunch of entries
277 # Enough for 3 stats replies
Rich Lane87f54bd2014-01-08 17:53:14 -0800278 for i in range(0, 4095):
Rich Lane464960b2014-01-08 17:30:07 -0800279 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, 5))
280
281 do_barrier(self.controller)
282 verify_no_errors(self.controller)
283
284 entries = self.do_entry_stats()
285 seen = set()
286 for entry in entries:
287 key = tlv_dict(entry.key)
288 vlan_vid = key[ofp.bsn_tlv.vlan_vid]
289 self.assertNotIn(vlan_vid, seen)
290 seen.add(vlan_vid)
291
Rich Lane87f54bd2014-01-08 17:53:14 -0800292 self.assertEquals(seen, set(range(0, 4095)))
Rich Lane790cc202014-01-08 14:54:25 -0800293
Rich Laneb2c5bf62014-01-06 17:18:40 -0800294class EntryDescStats(BaseGenTableTest):
295 """
296 Test retrieving entry desc stats
297 """
298 def runTest(self):
299 # Add a few entries
300 for i in range(0, 3):
301 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
302 checksum=0xfedcba9876543210fedcba9876543210 + i)
303
304 do_barrier(self.controller)
305 verify_no_errors(self.controller)
306
307 entries = self.do_entry_desc_stats()
308 seen = set()
309 for entry in entries:
310 logging.debug(entry.show())
311 key = tlv_dict(entry.key)
312 value = tlv_dict(entry.value)
313 self.assertIn(ofp.bsn_tlv.vlan_vid, key)
314 self.assertIn(ofp.bsn_tlv.ipv4, key)
315 self.assertIn(ofp.bsn_tlv.mac, value)
316 vlan_vid = key[ofp.bsn_tlv.vlan_vid]
317 seen.add(vlan_vid)
318 self.assertEqual(key[ofp.bsn_tlv.ipv4], 0x12345678)
319 self.assertEqual(value[ofp.bsn_tlv.mac], [0, 1, 2, 3, 4, vlan_vid])
320 self.assertEqual(entry.checksum, 0xfedcba9876543210fedcba9876543210 + vlan_vid)
321
322 self.assertEquals(seen, set([0, 1, 2]))
Rich Lane4e691ad2014-01-06 17:45:20 -0800323
Rich Lane790cc202014-01-08 14:54:25 -0800324class EntryDescStatsMasked(BaseGenTableTest):
325 """
326 Test retrieving entry desc stats with a checksum mask
327 """
328 def runTest(self):
329 def get_range(checksum, checksum_mask):
330 entries = self.do_entry_desc_stats(checksum, checksum_mask)
331 vlan_vids = []
332 for entry in entries:
333 key = tlv_dict(entry.key)
334 vlan_vids.append(key[ofp.bsn_tlv.vlan_vid])
335 return sorted(vlan_vids)
336
337 # Add 4 entries to each checksum bucket
338 for i in range(0, 256):
339 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
Rich Lane8d867ee2014-01-08 17:29:55 -0800340 checksum=make_checksum(i, i))
Rich Lane790cc202014-01-08 14:54:25 -0800341
342 do_barrier(self.controller)
343 verify_no_errors(self.controller)
344
345 # Check first bucket
346 self.assertEquals(get_range(make_checksum(0, 0), make_checksum(0xFC, 0)),
347 [0, 1, 2, 3])
348
349 # Check last bucket
350 self.assertEquals(get_range(make_checksum(0xFC, 0), make_checksum(0xFC, 0)),
351 [252, 253, 254, 255])
352
353 # Check first half of first bucket
354 self.assertEquals(get_range(make_checksum(0x00, 0), make_checksum(0xFE, 0)),
355 [0, 1])
356
357 # Check second half of first bucket
358 self.assertEquals(get_range(make_checksum(0x02, 0), make_checksum(0xFE, 0)),
359 [2, 3])
360
361 # Check first half of last bucket
362 self.assertEquals(get_range(make_checksum(0xFC, 0), make_checksum(0xFE, 0)),
363 [252, 253])
364
365 # Check second half of last bucket
366 self.assertEquals(get_range(make_checksum(0xFE, 0), make_checksum(0xFE, 0)),
367 [254, 255])
368
369 # Check first two buckets
370 self.assertEquals(get_range(make_checksum(0, 0), make_checksum(0xF8, 0)),
371 [0, 1, 2, 3, 4, 5, 6, 7])
372
373 # Check last two buckets
374 self.assertEquals(get_range(make_checksum(0xF8, 0), make_checksum(0xF8, 0)),
375 [248, 249, 250, 251, 252, 253, 254, 255])
376
377 # Check matching on low bits
378 self.assertEquals(get_range(make_checksum(0x00, 0x00), ~1), [0])
379 self.assertEquals(get_range(make_checksum(0x01, 0x00), ~1), [1])
380 self.assertEquals(get_range(make_checksum(0x01, 0x02), ~1), [])
381
Rich Lane5003c292014-01-08 17:34:45 -0800382class EntryDescStatsFragmented(BaseGenTableTest):
383 """
384 Test retrieving entry stats in mutiple replies
385 """
386 def runTest(self):
387 # Add a bunch of entries
388 # Enough for 3 stats replies
Rich Lane87f54bd2014-01-08 17:53:14 -0800389 for i in range(0, 4095):
Rich Lane5003c292014-01-08 17:34:45 -0800390 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, 5))
391
392 do_barrier(self.controller)
393 verify_no_errors(self.controller)
394
395 entries = self.do_entry_desc_stats()
396 seen = set()
397 for entry in entries:
398 key = tlv_dict(entry.key)
399 vlan_vid = key[ofp.bsn_tlv.vlan_vid]
400 self.assertNotIn(vlan_vid, seen)
401 seen.add(vlan_vid)
402
Rich Lane87f54bd2014-01-08 17:53:14 -0800403 self.assertEquals(seen, set(range(0, 4095)))
Rich Lane5003c292014-01-08 17:34:45 -0800404
Rich Lane4e691ad2014-01-06 17:45:20 -0800405class TableDescStats(BaseGenTableTest):
406 """
407 Test retrieving table desc stats
408 """
409 def runTest(self):
410 entries = self.do_table_desc_stats()
411 seen = set()
412 for entry in entries:
413 logging.debug(entry.show())
414 self.assertNotIn(entry.table_id, seen)
415 self.assertNotIn(entry.name, seen)
416 seen.add(entry.table_id)
417 seen.add(entry.name)
418 if entry.table_id == TABLE_ID:
419 self.assertEqual(entry.name, "test")
420 self.assertEqual(entry.buckets_size, 64)
421 self.assertEqual(entry.max_entries, 1000)
422
423 self.assertIn(TABLE_ID, seen)
Rich Lanea8f56672014-01-06 17:50:39 -0800424
425class TableStats(BaseGenTableTest):
426 """
427 Test retrieving table stats
428 """
429 def runTest(self):
Rich Lane64c4e602014-01-07 11:27:06 -0800430 # Verify we have the test table and no duplicates
Rich Lanea8f56672014-01-06 17:50:39 -0800431 entries = self.do_table_stats()
432 seen = set()
433 for entry in entries:
434 logging.debug(entry.show())
435 self.assertNotIn(entry.table_id, seen)
436 seen.add(entry.table_id)
437 if entry.table_id == TABLE_ID:
438 self.assertEqual(entry.entry_count, 0)
439 self.assertEqual(entry.checksum, 0)
Rich Lanea8f56672014-01-06 17:50:39 -0800440 self.assertIn(TABLE_ID, seen)
Rich Lane64c4e602014-01-07 11:27:06 -0800441
442 table_checksum = 0
443
444 # Add a bunch of entries, spread among the checksum buckets
445 for i in range(0, 256):
446 table_checksum ^= make_checksum(i, i*31)
447 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
448 checksum=make_checksum(i, i*31))
449
450 do_barrier(self.controller)
451 verify_no_errors(self.controller)
452
453 table_stats = self.do_test_table_stats()
454 self.assertEqual(table_stats.entry_count, 256)
455 self.assertEqual(table_stats.checksum, table_checksum)
456
457 # Modify an entry, changing its checksum
458 i = 30
459 table_checksum ^= make_checksum(i, i*31) # subtract old checksum
460 table_checksum ^= make_checksum(i, i*37) # add new checksum
461 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 4, 3, 2, 1, i),
462 checksum=make_checksum(i, i*37))
463
464 do_barrier(self.controller)
465 verify_no_errors(self.controller)
466
467 table_stats = self.do_test_table_stats()
468 self.assertEqual(table_stats.entry_count, 256)
469 self.assertEqual(table_stats.checksum, table_checksum)
470
471 # Delete an entry
472 i = 87
473 table_checksum ^= make_checksum(i, i*31)
474 self.do_delete(vlan_vid=i, ipv4=0x12345678)
475
476 do_barrier(self.controller)
477 verify_no_errors(self.controller)
478
479 table_stats = self.do_test_table_stats()
480 self.assertEqual(table_stats.entry_count, 255)
481 self.assertEqual(table_stats.checksum, table_checksum)
Rich Lane232d2ab2014-01-07 12:23:16 -0800482
483class BucketStats(BaseGenTableTest):
484 """
485 Test retrieving checksum bucket stats
486 """
487 def runTest(self):
488 # Verify initial state
489 entries = self.do_bucket_stats()
490 self.assertEquals(len(entries), 64)
491 for entry in entries:
492 self.assertEquals(entry.checksum, 0)
493
494 buckets = [0] * len(entries)
495 checksum_bits = int(math.log(len(buckets), 2))
496
497 def update_bucket(checksum):
498 index = checksum >> (128 - checksum_bits)
499 buckets[index] ^= checksum
500
501 # Add a bunch of entries, spread among the checksum buckets
502 for i in range(0, 256):
503 update_bucket(make_checksum(i, i*31))
504 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
505 checksum=make_checksum(i, i*31))
506
507 entries = self.do_bucket_stats()
508 self.assertEquals(len(entries), 64)
509 for i, entry in enumerate(entries):
510 self.assertEquals(entry.checksum, buckets[i])
511
512 # Modify an entry, changing its checksum
513 i = 30
514 update_bucket(make_checksum(i, i*31)) # subtract old checksum
515 update_bucket(make_checksum(i, i*37)) # add new checksum
516 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 4, 3, 2, 1, i),
517 checksum=make_checksum(i, i*37))
518
519 do_barrier(self.controller)
520 verify_no_errors(self.controller)
521
522 entries = self.do_bucket_stats()
523 self.assertEquals(len(entries), 64)
524 for i, entry in enumerate(entries):
525 self.assertEquals(entry.checksum, buckets[i])
526
527 # Delete an entry
528 i = 87
529 update_bucket(make_checksum(i, i*31))
530 self.do_delete(vlan_vid=i, ipv4=0x12345678)
531
532 do_barrier(self.controller)
533 verify_no_errors(self.controller)
534
535 entries = self.do_bucket_stats()
536 self.assertEquals(len(entries), 64)
537 for i, entry in enumerate(entries):
538 self.assertEquals(entry.checksum, buckets[i])
Rich Lane78bd3772014-01-08 11:51:13 -0800539
540class SetBucketsSize(BaseGenTableTest):
541 """
542 Test setting the checksum buckets size
543 """
544 def setUp(self):
545 BaseGenTableTest.setUp(self)
546 self.do_set_buckets_size(64)
547 do_barrier(self.controller)
548
549 def tearDown(self):
550 self.do_set_buckets_size(64)
551 do_barrier(self.controller)
552 BaseGenTableTest.tearDown(self)
553
554 def runTest(self):
555 # Verify initial state
556 entries = self.do_bucket_stats()
557 self.assertEquals(len(entries), 64)
558 for entry in entries:
559 self.assertEquals(entry.checksum, 0)
560
561 buckets32 = [0] * 32
562 buckets64 = [0] * 64
563
564 def update_bucket(checksum):
565 buckets32[checksum >> (128 - int(math.log(32, 2)))] ^= checksum
566 buckets64[checksum >> (128 - int(math.log(64, 2)))] ^= checksum
567
568 # Add a bunch of entries, spread among the checksum buckets
569 for i in range(0, 256):
570 update_bucket(make_checksum(i, i*31))
571 self.do_add(vlan_vid=i, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, i),
572 checksum=make_checksum(i, i*31))
573
574 entries = self.do_bucket_stats()
575 self.assertEquals(len(entries), 64)
576 for i, entry in enumerate(entries):
577 self.assertEquals(entry.checksum, buckets64[i])
578
579 self.do_set_buckets_size(32)
580 do_barrier(self.controller)
581
582 entries = self.do_bucket_stats()
583 self.assertEquals(len(entries), 32)
584 for i, entry in enumerate(entries):
585 self.assertEquals(entry.checksum, buckets32[i])
586
587 self.do_set_buckets_size(64)
588 do_barrier(self.controller)
589
590 entries = self.do_bucket_stats()
591 self.assertEquals(len(entries), 64)
592 for i, entry in enumerate(entries):
593 self.assertEquals(entry.checksum, buckets64[i])
Rich Lane55408072014-01-09 10:12:36 -0800594
595class AddError(BaseGenTableTest):
596 """
597 Test failure adding entries
598 """
599 def runTest(self):
600 # Invalid key
601 self.do_add(vlan_vid=10000, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, 5))
602 do_barrier(self.controller)
603
604 error, _ = self.controller.poll(ofp.OFPT_ERROR, 0)
605 self.assertIsInstance(error, ofp.message.bad_request_error_msg)
606 self.assertEquals(error.code, ofp.OFPBRC_EPERM)
607
608 self.assertEquals(len(self.do_entry_desc_stats()), 0)
609
610 # Invalid value
611 self.do_add(vlan_vid=100, ipv4=0x12345678, mac=(1, 1, 2, 3, 4, 5))
612 do_barrier(self.controller)
613
614 error, _ = self.controller.poll(ofp.OFPT_ERROR, 0)
615 self.assertIsInstance(error, ofp.message.bad_request_error_msg)
616 self.assertEquals(error.code, ofp.OFPBRC_EPERM)
617
618 self.assertEquals(len(self.do_entry_desc_stats()), 0)
619
620class ModifyError(BaseGenTableTest):
621 """
622 Test failure modifying entries
623 """
624 def runTest(self):
625 # Add a valid entry we'll try to modify
626 self.do_add(vlan_vid=100, ipv4=0x12345678, mac=(0, 1, 2, 3, 4, 5))
627 do_barrier(self.controller)
628 verify_no_errors(self.controller)
629
630 orig_entries = self.do_entry_desc_stats()
631 self.assertEquals(len(orig_entries), 1)
632
633 # Invalid value
634 self.do_add(vlan_vid=100, ipv4=0x12345678, mac=(1, 1, 2, 3, 4, 5))
635 do_barrier(self.controller)
636
637 error, _ = self.controller.poll(ofp.OFPT_ERROR, 0)
638 self.assertIsInstance(error, ofp.message.bad_request_error_msg)
639 self.assertEquals(error.code, ofp.OFPBRC_EPERM)
640
641 # Check that the table wasn't modified
642 new_entries = self.do_entry_desc_stats()
643 self.assertEquals(len(new_entries), 1)
644 self.assertEquals(new_entries, orig_entries)
Rich Lane14e4c142014-01-09 10:31:08 -0800645
Rich Laneb1186cc2014-01-09 11:20:26 -0800646class DeleteNonexistentError(BaseGenTableTest):
647 """
648 Test failure deleting a nonexistent entry
649 """
650 def runTest(self):
651 self.do_delete(vlan_vid=1000, ipv4=0x12345678)
652 do_barrier(self.controller)
653
654 error, _ = self.controller.poll(ofp.OFPT_ERROR, 0)
655 self.assertIsInstance(error, ofp.message.bad_request_error_msg)
656 self.assertEquals(error.code, ofp.OFPBRC_EPERM)
657
Rich Lane14e4c142014-01-09 10:31:08 -0800658class BadTableIdError(BaseGenTableTest):
659 """
660 Test failure of each message when specifying a nonexistent table id
661 """
662 def runTest(self):
663 def check_error(msg):
664 reply, _ = self.controller.transact(msg)
665 self.assertIsInstance(reply, ofp.message.bad_request_error_msg)
666 self.assertEquals(reply.code, ofp.OFPBRC_BAD_TABLE_ID)
667
668 valid_table_ids = set([x.table_id for x in self.do_table_desc_stats()])
669 invalid_table_id = TABLE_ID
670 while invalid_table_id in valid_table_ids:
671 invalid_table_id = random.randrange(65536)
672
673 logging.debug("Using invalid table id %d", invalid_table_id)
674
675 check_error(ofp.message.bsn_gentable_clear_request(
676 table_id=invalid_table_id))
677
678 check_error(ofp.message.bsn_gentable_entry_add(
679 table_id=invalid_table_id))
680
681 check_error(ofp.message.bsn_gentable_entry_delete(
682 table_id=invalid_table_id))
683
684 check_error(ofp.message.bsn_gentable_entry_stats_request(
685 table_id=invalid_table_id))
686
687 check_error(ofp.message.bsn_gentable_entry_desc_stats_request(
688 table_id=invalid_table_id))
689
690 check_error(ofp.message.bsn_gentable_bucket_stats_request(
691 table_id=invalid_table_id))
692
693 check_error(ofp.message.bsn_gentable_set_buckets_size(
694 table_id=invalid_table_id))