From e9842dc6bec50adcfc5277f4425cb52e0dfb2953 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Fri, 7 Jul 2017 16:51:06 -0300 Subject: [PATCH 01/53] introduce general unpack method (comes from of_core.utils) --- pyof/utils.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 pyof/utils.py diff --git a/pyof/utils.py b/pyof/utils.py new file mode 100644 index 000000000..a71d8945d --- /dev/null +++ b/pyof/utils.py @@ -0,0 +1,37 @@ +"""General Unpack utils for python-openflow.""" +import pyof.v0x01.common.header +import pyof.v0x01.common.utils +import pyof.v0x04.common.header +import pyof.v0x04.common.utils +from pyof.foundation.exceptions import UnpackException + +pyof_version_libs = {0x01: pyof.v0x01, + 0x04: pyof.v0x04} + + +def unpack(packet): + """Unpack the OpenFlow Packet and returns a message.""" + try: + version = packet[0] + except IndexError: + raise UnpackException('null packet') + + try: + pyof_lib = pyof_version_libs[version] + except KeyError: + raise UnpackException('Version not supported') + + try: + header = pyof_lib.common.header.Header() + header.unpack(packet[:8]) + message = pyof_lib.common.utils.new_message_from_header(header) + binary_data = packet[8:] + if binary_data: + if len(binary_data) == header.length - 8: + message.unpack(binary_data) + else: + raise UnpackException( + 'packet size does not match packet length field') + return message + except (UnpackException, ValueError) as e: + raise UnpackException(e) From 883358a195216ef909c2e7b65d0ef9a8c9629343 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Fri, 7 Jul 2017 16:45:09 -0300 Subject: [PATCH 02/53] proposes more flexible TestStruct --- tests/test_struct.py | 145 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/tests/test_struct.py b/tests/test_struct.py index 057b21033..f4e9d127b 100644 --- a/tests/test_struct.py +++ b/tests/test_struct.py @@ -1,9 +1,11 @@ """Automate struct tests.""" import unittest +from pyof.utils import unpack from tests.raw_dump import RawDump +# to be removed and replace by TestMsgDumpFile class TestStruct(unittest.TestCase): """Run tests related to struct packing and unpacking. @@ -161,3 +163,146 @@ def test_raw_dump_size(self): self.assertEqual(obj.get_size(), unpacked.get_size()) except FileNotFoundError: raise self.skipTest('No raw dump file found.') + + +class TestStructDump(unittest.TestCase): + """Run message pack, unpack and get_size tests using bytes struct dump. + + Test the lib with raw dumps. We assume the raw files are valid according + to the OF specs to check whether our pack, unpack and get_size + implementations are correct. + + Also, check the minimum size of the struct by instantiating an object with + no parameters. + + To run the tests, just extends this class and set the 'dump' and 'obj' + attributes. You can also optionally set the 'min_size' attribute. + + Example: + .. code-block:: python3 + + class TestMatch(TestStructDump): + dump = b'' # needs to be filled + obj = pyof.v0x01.common.flow_match.Match(xid=0) + min_size = 8 + """ + + dump = b'' + obj = None + min_size = 0 + + def __init__(self, *args, **kwargs): + """Constructor to avoid this base class being executed as a test.""" + if self.__class__ == TestStructDump: + self.run = self.run = lambda self, *args, **kwargs: None + super().__init__(*args, **kwargs) + + def setUp(self): + """Setup the instance before testing.""" + self._msg_cls = type(self.obj) + self._unpacked_dump = self._unpack_dump() + super().setUp() + + def _unpack_dump(self): + obj = self._msg_cls() + obj.unpack(self.dump) + return obj + + def test_pack(self): + """Check whether packed objects equals to dump file.""" + self.assertEqual(self.dump, self.obj.pack()) + + def test_unpack(self): + """Check whether the unpacked dump equals to expected object.""" + self.assertEqual(self._unpacked_dump, self.obj) + + def test_get_size(self): + """Check if get_size method return the correct size.""" + self.assertEqual(self.obj.get_size(), len(self.dump)) + + def test_minimum_size(self): + """Test struct minimum size.""" + if not self.min_size: + raise self.skipTest('skipped, no minimum size set.') + obj = self._msg_cls() + self.assertEqual(obj.get_size(), self.min_size) + + def test_raw_dump_size(self): + """Check whether the unpacked dump has the expected size.""" + self.assertEqual(self.obj.get_size(), self._unpacked_dump.get_size()) + + +class TestMsgDump(TestStructDump): + r"""Run message pack, unpack and get_size tests using bytes message dump. + + Test the lib with raw dumps. We assume the raw files are valid according + to the OF specs to check whether our pack, unpack and get_size + implementations are correct. + + Also, check the minimum size of the struct by instantiating an object with + no parameters. + + To run the tests, just extends this class and set the 'dump' and 'obj' + attributes. You can also optionally set the 'min_size' attribute. + + Example: + .. code-block:: python3 + + class TestHello(TestMsgDump): + dump = b'\x01\x00\x00\x08\x00\x00\x00\x00' + obj = pyof.v0x01.symmetric.hello.Hello(xid=0) + min_size = 8 + """ + + def __init__(self, *args, **kwargs): + """Constructor to avoid this base class beeing executed as a test.""" + if self.__class__ == TestMsgDump: + self.run = self.run = lambda self, *args, **kwargs: None + super().__init__(*args, **kwargs) + + def _unpack_dump(self): + return unpack(self.dump) + + +class TestMsgDumpFile(TestMsgDump): + """Run message pack, unpack and get_size tests using message in a dumpfile. + + Test the lib with raw dumps. We assume the raw files are valid according + to the OF specs to check whether our pack, unpack and get_size + implementations are correct. + + Also, check the minimum size of the message by instantiating an object with + no parameters. + + To run the tests, just extends this class and set the 'dumpfile' and 'obj' + attributes. You can also optionally set the 'min_size' attribute. + + Example: + .. code-block:: python3 + + class TestHelloFileDump(TestMsgDumpFile): + dumpfile = 'v0x01/ofpt_hello.dat' + obj = pyof.v0x01.symmetric.hello.Hello(xid=1) + + """ + + dumpfile = None + + def __init__(self, *args, **kwargs): + """Constructor to avoid this base class beeing executed as a test.""" + if self.__class__ == TestMsgDumpFile: + self.run = self.run = lambda self, *args, **kwargs: None + super().__init__(*args, **kwargs) + + def setUp(self): + """Setup the instance before testing.""" + self._read_dump_file() + super().setUp() + + def _read_dump_file(self): + dumpfile = f'raw/{self.dumpfile}' + try: + with open(dumpfile, 'rb') as fd: + self.dump = fd.read() + except FileNotFoundError: + raise self.skipTest(f'No raw dump file found: {dumpfile}') From 5d6420ecc9d6b603498ac13313290a2ab7fc4f89 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Thu, 13 Jul 2017 15:49:28 -0300 Subject: [PATCH 03/53] remove comment as requested... --- tests/test_struct.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_struct.py b/tests/test_struct.py index f4e9d127b..cee396d7f 100644 --- a/tests/test_struct.py +++ b/tests/test_struct.py @@ -5,7 +5,6 @@ from tests.raw_dump import RawDump -# to be removed and replace by TestMsgDumpFile class TestStruct(unittest.TestCase): """Run tests related to struct packing and unpacking. From acab25045aee33cc16660ca99c57773fd1707a46 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 10:46:40 -0300 Subject: [PATCH 04/53] apply new test implementation for basic types --- tests/test_foundation/test_basic_types.py | 101 ++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/tests/test_foundation/test_basic_types.py b/tests/test_foundation/test_basic_types.py index 9cd95afa1..6ad878359 100644 --- a/tests/test_foundation/test_basic_types.py +++ b/tests/test_foundation/test_basic_types.py @@ -3,6 +3,107 @@ from pyof.foundation import basic_types from pyof.foundation.basic_types import BinaryData +from tests.test_struct import TestStructDump + + +class TestUBInt8_(unittest.TestCase): + """Test UBInt8.""" + + dump = b'\xff' + obj = basic_types.UBInt32(2**8 - 1) + min_size = 1 + + +class TestUBInt16_(unittest.TestCase): + """Test UBInt16.""" + + dump = b'\xff\xff' + obj = basic_types.UBInt32(2**16 - 1) + min_size = 2 + + +class TestUBInt32_(unittest.TestCase): + """Test UBInt32.""" + + dump = b'\xff\xff\xff\xff' + obj = basic_types.UBInt32(2**32 - 1) + min_size = 4 + + +class TestChar_3(unittest.TestCase): + """Test Char with length 3.""" + + dump = b'fo\x00' + obj = basic_types.Char('foo', length=3) + + +class TestChar_5(unittest.TestCase): + """Test Char with length 5.""" + + dump = b'foo\x00\x00' + obj = basic_types.Char('foo', length=5) + + +class TestHWAddress_default(TestStructDump): + """Test HWAddress default value.""" + + dump = b'\x00\x00\x00\x00\x00\x00' + obj = basic_types.HWAddress() + + +class TestHWAddress_mac(TestStructDump): + """Test HWAddress mac value.""" + + mac = '00:00:00:00:00:00' + dump = b'\x00\x00\x00\x00\x00\x00' + obj = basic_types.HWAddress(mac) + + def test_address_value(self): + """Test HWAddress mac value.""" + self.assertEqual(self.obj.value, self.mac) + + +class TestHWAddress_random(TestHWAddress_mac): + """Test HWAddress mac value 0a:d3:98:a5:30:47.""" + + mac = '0a:d3:98:a5:30:47' + dump = b'\x0a\xd3\x98\xa5\x30\x47' + obj = basic_types.HWAddress(mac) + + +class TestIPAddress_netmask(TestStructDump): + """Test IPAddress and its default netmask value.""" + + dump = b'\xc0\xa8\x00\x01' + obj = basic_types.IPAddress('192.168.0.1') + netmask = 32 + + def test_netmask(self): + """Test IPAddress netmask value.""" + self.assertEqual(self.obj.netmask, self.netmask) + + +class TestIPAddress_nonetmask(TestIPAddress_netmask): + """Test IPAdress and netmask value 16.""" + + dump = b'\xc0\xa8\x00\x01' + obj = basic_types.IPAddress('192.168.0.1/16') + netmask = 16 + + +class TestBinaryData_empty(TestStructDump): + """Test empty BinaryData.""" + + dump = b'' + obj = BinaryData() + min_size = 0 + + +class TestBinaryData_bytes(TestStructDump): + """Test 'bytes' BinaryData.""" + + dump = b'bytes' + obj = BinaryData(b'bytes') class TestUBInt8(unittest.TestCase): From 990c1213f629d3642bd1d25f557a853fa5644094 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 10:48:12 -0300 Subject: [PATCH 05/53] apply new test implementation for basic types - remove unused --- tests/test_foundation/test_basic_types.py | 169 +--------------------- 1 file changed, 2 insertions(+), 167 deletions(-) diff --git a/tests/test_foundation/test_basic_types.py b/tests/test_foundation/test_basic_types.py index 6ad878359..725a4af40 100644 --- a/tests/test_foundation/test_basic_types.py +++ b/tests/test_foundation/test_basic_types.py @@ -106,150 +106,8 @@ class TestBinaryData_bytes(TestStructDump): obj = BinaryData(b'bytes') -class TestUBInt8(unittest.TestCase): - """Test of UBInt8 BasicType.""" - - def setUp(self): - """Basic test setup.""" - self.ubint8 = basic_types.UBInt8() - - def test_get_size(self): - """[Foundation/BasicTypes/UBInt8] - size 1.""" - self.assertEqual(self.ubint8.get_size(), 1) - - @unittest.skip('Not yet implemented') - def test_pack(self): - """[Foundation/BasicTypes/UBInt8] - packing.""" - pass - - @unittest.skip('Not yet implemented') - def test_unpack(self): - """[Foundation/BasicTypes/UBInt8] - unpacking.""" - pass - - -class TestUBInt16(unittest.TestCase): - """Test of UBInt16 BasicType.""" - - def setUp(self): - """Basic test setup.""" - self.ubint16 = basic_types.UBInt16() - - def test_get_size(self): - """[Foundation/BasicTypes/UBInt16] - size 2.""" - self.assertEqual(self.ubint16.get_size(), 2) - - @unittest.skip('Not yet implemented') - def test_pack(self): - """[Foundation/BasicTypes/UBInt16] - packing.""" - pass - - @unittest.skip('Not yet implemented') - def test_unpack(self): - """[Foundation/BasicTypes/UBInt16] - unpacking.""" - pass - - -class TestUBInt32(unittest.TestCase): - """Test of UBInt32 BasicType.""" - - def setUp(self): - """Basic test setup.""" - self.ubint32 = basic_types.UBInt32() - - def test_get_size(self): - """[Foundation/BasicTypes/UBInt32] - size 4.""" - self.assertEqual(self.ubint32.get_size(), 4) - - @unittest.skip('Not yet implemented') - def test_pack(self): - """[Foundation/BasicTypes/UBInt32] - packing.""" - pass - - @unittest.skip('Not yet implemented') - def test_unpack(self): - """[Foundation/BasicTypes/UBInt32] - unpacking.""" - pass - - -class TestChar(unittest.TestCase): - """Test of Char BasicType.""" - - def setUp(self): - """Basic test setup.""" - self.char1 = basic_types.Char('foo', length=3) - self.char2 = basic_types.Char('foo', length=5) - - def test_get_size(self): - """[Foundation/BasicTypes/Char] - get_size.""" - self.assertEqual(self.char1.get_size(), 3) - self.assertEqual(self.char2.get_size(), 5) - - def test_pack(self): - """[Foundation/BasicTypes/Char] - packing.""" - self.assertEqual(self.char1.pack(), b'fo\x00') - self.assertEqual(self.char2.pack(), b'foo\x00\x00') - - def test_unpack(self): - """[Foundation/BasicTypes/Char] - unpacking.""" - char1 = basic_types.Char(length=3) - char2 = basic_types.Char(length=5) - char1.unpack(b'fo\x00') - char2.unpack(b'foo\x00\x00') - - self.assertEqual(char1.value, 'fo') - self.assertEqual(char2.value, 'foo') - - -class TestHWaddress(unittest.TestCase): - """Test of HWAddress BasicType.""" - - def test_unpack_packed(self): - """Testing unpack of packed HWAddress.""" - mac = '0a:d3:98:a5:30:47' - hw_addr = basic_types.HWAddress(mac) - packed = hw_addr.pack() - unpacked = basic_types.HWAddress() - unpacked.unpack(packed) - self.assertEqual(mac, unpacked.value) - - def test_default_value(self): - """Testing default_value for HWAddress.""" - mac = '00:00:00:00:00:00' - hw_addr = basic_types.HWAddress() - packed = hw_addr.pack() - unpacked = basic_types.HWAddress() - unpacked.unpack(packed) - self.assertEqual(mac, unpacked.value) - - class TestIPAddress(unittest.TestCase): - """Test of IPAddress BasicType.""" - - def test_unpack_packed(self): - """Test unpacking of packed IPAddress.""" - ip_addr = basic_types.IPAddress('192.168.0.1') - packed = ip_addr.pack() - unpacked = basic_types.IPAddress() - unpacked.unpack(packed) - self.assertEqual(ip_addr.value, unpacked.value) - - def test_unpack_packed_with_netmask(self): - """Testing unpack of packed IPAddress with netmask.""" - ip_addr = basic_types.IPAddress('192.168.0.1/16') - packed = ip_addr.pack() - unpacked = basic_types.IPAddress() - unpacked.unpack(packed) - self.assertEqual(ip_addr.value, unpacked.value) - - def test_netmask(self): - """Testing get netmask from IPAddress.""" - ip_addr = basic_types.IPAddress('192.168.0.1/24') - self.assertEqual(ip_addr.netmask, 24) - ip_addr = basic_types.IPAddress('192.168.0.1/16') - self.assertEqual(ip_addr.netmask, 16) - ip_addr = basic_types.IPAddress('192.168.0.1') - self.assertEqual(ip_addr.netmask, 32) + """Test of IPAddress BasicType max_prefix.""" def test_max_prefix(self): """Testing get max_prefix from IPAddress.""" @@ -258,32 +116,9 @@ def test_max_prefix(self): ip_addr = basic_types.IPAddress('192.168.0.35/16') self.assertEqual(ip_addr.max_prefix, 32) - def test_get_size(self): - """Testing get_size from IPAddress.""" - ip_addr = basic_types.IPAddress('192.168.0.1/24') - self.assertEqual(ip_addr.get_size(), 4) - class TestBinaryData(unittest.TestCase): - """Test Binary data type.""" - - def test_default_value(self): - """Default packed value should be an empty byte.""" - expected = b'' - actual = BinaryData().pack() - self.assertEqual(expected, actual) - - def test_pack_bytes(self): - """Test packing some bytes.""" - expected = b'forty two' - actual = BinaryData(expected).pack() - self.assertEqual(expected, actual) - - def test_pack_empty_bytes(self): - """Test packing empty bytes.""" - expected = b'' - actual = BinaryData(expected).pack() - self.assertEqual(expected, actual) + """Test Binary data type cannot accept string.""" def test_unexpected_value(self): """Should raise ValueError if constructor value is not bytes.""" From e20298ea918537f5452df2ad1bf845b2833b8287 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 10:58:45 -0300 Subject: [PATCH 06/53] apply new test implementation for network types --- tests/test_foundation/test_network_types.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_foundation/test_network_types.py b/tests/test_foundation/test_network_types.py index a72fd42a2..74378669f 100644 --- a/tests/test_foundation/test_network_types.py +++ b/tests/test_foundation/test_network_types.py @@ -3,6 +3,14 @@ from pyof.foundation.basic_types import BinaryData from pyof.foundation.network_types import GenericTLV, IPv4 +from tests.test_struct import TestStructDump + + +class TestGenericTLV(TestStructDump): + """Test the GenericTLV value data.""" + + dump = b'\xfe\x04test' + obj = GenericTLV(value=BinaryData(b'test')) class TestNetworkTypes(unittest.TestCase): @@ -17,6 +25,16 @@ def test_GenTLV_value_unpack(self): self.assertEqual(tlv.value.value, tlv_unpacked.value.value) +class TestIPV4(TestStructDump): + """Test the IPV4 class.""" + + dump = b'F(\x00 \x00\x00\x00\x00@\x11\x02' +\ + b'\xc5\xc0\xa8\x00\n\xac\x10\n\x1e1000testdata' + obj = IPv4(dscp=10, ttl=64, protocol=17, source="192.168.0.10", + destination="172.16.10.30", options=b'1000', + data=b'testdata') + + class TestIPv4(unittest.TestCase): """Test IPv4 packets.""" From 79c6d5406eb48a197fa6db19f8df45baf40a70ab Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:01:46 -0300 Subject: [PATCH 07/53] apply new test implementation for network types - remove unused --- tests/test_foundation/test_network_types.py | 54 +-------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/tests/test_foundation/test_network_types.py b/tests/test_foundation/test_network_types.py index 74378669f..a53379a9a 100644 --- a/tests/test_foundation/test_network_types.py +++ b/tests/test_foundation/test_network_types.py @@ -1,6 +1,4 @@ """Test Python-openflow network types.""" -import unittest - from pyof.foundation.basic_types import BinaryData from pyof.foundation.network_types import GenericTLV, IPv4 from tests.test_struct import TestStructDump @@ -13,18 +11,6 @@ class TestGenericTLV(TestStructDump): obj = GenericTLV(value=BinaryData(b'test')) -class TestNetworkTypes(unittest.TestCase): - """Reproduce bugs found.""" - - def test_GenTLV_value_unpack(self): - """Value attribute should be the same after unpacking.""" - value = BinaryData(b'test') - tlv = GenericTLV(value=value) - tlv_unpacked = GenericTLV() - tlv_unpacked.unpack(tlv.pack()) - self.assertEqual(tlv.value.value, tlv_unpacked.value.value) - - class TestIPV4(TestStructDump): """Test the IPV4 class.""" @@ -34,44 +20,6 @@ class TestIPV4(TestStructDump): destination="172.16.10.30", options=b'1000', data=b'testdata') - -class TestIPv4(unittest.TestCase): - """Test IPv4 packets.""" - - def test_IPv4_pack(self): - """Test pack/unpack of IPv4 class.""" - packet = IPv4(dscp=10, ttl=64, protocol=17, source="192.168.0.10", - destination="172.16.10.30", options=b'1000', - data=b'testdata') - packed = packet.pack() - expected = b'F(\x00 \x00\x00\x00\x00@\x11\x02' - expected += b'\xc5\xc0\xa8\x00\n\xac\x10\n\x1e1000testdata' - self.assertEqual(packed, expected) - - def test_IPv4_unpack(self): - """Test unpack of IPv4 binary packet.""" - raw = b'FP\x00$\x00\x00\x00\x00\x80\x06W' - raw += b'\xf4\n\x9aN\x81\xc0\xa8\xc7\xcc1000somemoredata' - expected = IPv4(dscp=20, ttl=128, protocol=6, source="10.154.78.129", - destination="192.168.199.204", options=b'1000', - data=b'somemoredata') - expected.pack() - unpacked = IPv4() - unpacked.unpack(raw) - self.assertEqual(unpacked, expected) - - def test_IPv4_size(self): - """Test Header size for IPv4 packet.""" - packet = IPv4() - packet.pack() - self.assertEqual(20, packet.get_size()) - self.assertEqual(20, packet.length) - self.assertEqual(20, packet.ihl * 4) - def test_IPv4_checksum(self): """Test if the IPv4 checksum is being calculated correclty.""" - packet = IPv4(dscp=10, ttl=64, protocol=17, source="192.168.0.10", - destination="172.16.10.30", options=b'1000', - data=b'testdata') - packet.pack() - self.assertEqual(packet.checksum, 709) + self.assertEqual(self._unpacked_dump.checksum, 709) From 6889fb6e07868567262771d2402cbefb13e1c46f Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:07:40 -0300 Subject: [PATCH 08/53] apply new test implementation for error msg --- .../v0x01/test_asynchronous/test_error_msg.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/v0x01/test_asynchronous/test_error_msg.py b/tests/v0x01/test_asynchronous/test_error_msg.py index 79bd3d4c6..1af06b9bc 100644 --- a/tests/v0x01/test_asynchronous/test_error_msg.py +++ b/tests/v0x01/test_asynchronous/test_error_msg.py @@ -2,6 +2,30 @@ from pyof.v0x01.asynchronous.error_msg import ( BadRequestCode, ErrorMsg, ErrorType, FlowModFailedCode) from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDump, TestMsgDumpFile + + +class TestErrorMessage_fromfile(TestMsgDumpFile): + """Test the ErrorMsg class.""" + + dumpfile = 'v0x01/ofpt_error_msg.dat' + obj = ErrorMsg(xid=12, + error_type=ErrorType.OFPET_BAD_REQUEST, + code=BadRequestCode.OFPBRC_BAD_STAT, + data=b'') + min_size = 12 + + +class TestErrorMessage_dump(TestMsgDump): + """Test the ErrorMsg class.""" + + # dump needs to be checked + dump = b'\x01\x01\x00\x1b\x00\x00\x00\x18\x00\x03\x00\x02FLOW' + obj = ErrorMsg(xid=24, + error_type=ErrorType.OFPET_FLOW_MOD_FAILED, + code=FlowModFailedCode.OFPFMFC_EPERM, + data=b'FLOW') + min_size = 12 class TestErrorMessage(TestStruct): From f62087dc5170b90d71a4ef57a302cf2ec6ba93c4 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 13:22:43 -0300 Subject: [PATCH 09/53] errormsg packet dump fix --- tests/v0x01/test_asynchronous/test_error_msg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/v0x01/test_asynchronous/test_error_msg.py b/tests/v0x01/test_asynchronous/test_error_msg.py index 1af06b9bc..eefd44b57 100644 --- a/tests/v0x01/test_asynchronous/test_error_msg.py +++ b/tests/v0x01/test_asynchronous/test_error_msg.py @@ -20,7 +20,7 @@ class TestErrorMessage_dump(TestMsgDump): """Test the ErrorMsg class.""" # dump needs to be checked - dump = b'\x01\x01\x00\x1b\x00\x00\x00\x18\x00\x03\x00\x02FLOW' + dump = b'\x01\x01\x00\x10\x00\x00\x00\x18\x00\x03\x00\x02FLOW' obj = ErrorMsg(xid=24, error_type=ErrorType.OFPET_FLOW_MOD_FAILED, code=FlowModFailedCode.OFPFMFC_EPERM, From 25db9a1feef927fafdc992eaa9b0084d714bea78 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:08:12 -0300 Subject: [PATCH 10/53] apply new test implementation for error msg - remove unused --- .../v0x01/test_asynchronous/test_error_msg.py | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/tests/v0x01/test_asynchronous/test_error_msg.py b/tests/v0x01/test_asynchronous/test_error_msg.py index eefd44b57..958a4770c 100644 --- a/tests/v0x01/test_asynchronous/test_error_msg.py +++ b/tests/v0x01/test_asynchronous/test_error_msg.py @@ -1,7 +1,6 @@ """Testing Error Message.""" from pyof.v0x01.asynchronous.error_msg import ( BadRequestCode, ErrorMsg, ErrorType, FlowModFailedCode) -from tests.test_struct import TestStruct from tests.test_struct import TestMsgDump, TestMsgDumpFile @@ -26,32 +25,3 @@ class TestErrorMessage_dump(TestMsgDump): code=FlowModFailedCode.OFPFMFC_EPERM, data=b'FLOW') min_size = 12 - - -class TestErrorMessage(TestStruct): - """Test the Error Message.""" - - @classmethod - def setUpClass(cls): - """Setup TestStruct.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_error_msg') - super().set_raw_dump_object(ErrorMsg, xid=12, - error_type=ErrorType.OFPET_BAD_REQUEST, - code=BadRequestCode.OFPBRC_BAD_STAT, - data=b'') - super().set_minimum_size(12) - - def test_unpack_error_msg(self): - """Test Unpack a sample ErrorMsg.""" - expected = b'\x01\x01\x00\x1b\x00\x00\x00\x18\x00\x03\x00\x02FLOW' - - error_msg = ErrorMsg(xid=24, - error_type=ErrorType.OFPET_FLOW_MOD_FAILED, - code=FlowModFailedCode.OFPFMFC_EPERM, - data=b'FLOW') - - actual = ErrorMsg(xid=24) - actual.unpack(expected[8:]) - - self.assertEqual(actual, error_msg) From 98a6d8763acc335cf370826cfb640c93fb120394 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:11:18 -0300 Subject: [PATCH 11/53] apply new test implementation for flow removed --- .../test_asynchronous/test_flow_removed.py | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/tests/v0x01/test_asynchronous/test_flow_removed.py b/tests/v0x01/test_asynchronous/test_flow_removed.py index 9037fdb45..dbab461e8 100644 --- a/tests/v0x01/test_asynchronous/test_flow_removed.py +++ b/tests/v0x01/test_asynchronous/test_flow_removed.py @@ -2,28 +2,24 @@ from pyof.foundation.basic_types import HWAddress, IPAddress from pyof.v0x01.asynchronous.flow_removed import FlowRemoved, FlowRemovedReason from pyof.v0x01.common.flow_match import Match -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestFlowRemoved(TestStruct): - """Test the FlowRemoved message.""" +class TestFlowRemoved(TestMsgDumpFile): + """Test the FlowRemoved class.""" - @classmethod - def setUpClass(cls): - """Setup TestStruct.""" - reason = FlowRemovedReason.OFPRR_IDLE_TIMEOUT - match = Match(in_port=80, dl_vlan=1, dl_vlan_pcp=1, dl_type=1, - nw_tos=1, nw_proto=1, tp_src=80, tp_dst=80, - dl_src=HWAddress('00:00:00:00:00:00'), - dl_dst=HWAddress('00:00:00:00:00:00'), - nw_src=IPAddress('192.168.0.1'), - nw_dst=IPAddress('192.168.0.2')) + dumpfile = 'v0x01/ofpt_flow_removed.dat' + reason = FlowRemovedReason.OFPRR_IDLE_TIMEOUT + match = Match(in_port=80, dl_vlan=1, dl_vlan_pcp=1, dl_type=1, + nw_tos=1, nw_proto=1, tp_src=80, tp_dst=80, + dl_src=HWAddress('00:00:00:00:00:00'), + dl_dst=HWAddress('00:00:00:00:00:00'), + nw_src=IPAddress('192.168.0.1'), + nw_dst=IPAddress('192.168.0.2')) - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_flow_removed') - super().set_raw_dump_object(FlowRemoved, xid=12, - match=match, cookie=0, priority=1, - reason=reason, duration_sec=4, - duration_nsec=23, idle_timeout=9, - packet_count=10, byte_count=4) - super().set_minimum_size(88) + obj = FlowRemoved(xid=12, + match=match, cookie=0, priority=1, + reason=reason, duration_sec=4, + duration_nsec=23, idle_timeout=9, + packet_count=10, byte_count=4) + min_size = 88 From 9267820609e3bd31ca33f9219d032765a534823b Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:13:25 -0300 Subject: [PATCH 12/53] apply new test implementation for PacketIn --- .../v0x01/test_asynchronous/test_packet_in.py | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/v0x01/test_asynchronous/test_packet_in.py b/tests/v0x01/test_asynchronous/test_packet_in.py index a223d3228..cd61157ea 100644 --- a/tests/v0x01/test_asynchronous/test_packet_in.py +++ b/tests/v0x01/test_asynchronous/test_packet_in.py @@ -1,19 +1,16 @@ """Packet in message tests.""" from pyof.v0x01.asynchronous.packet_in import PacketIn, PacketInReason -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestPacketIn(TestStruct): +class TestPacketIn(TestMsgDumpFile): """Packet in message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_packet_in') - super().set_raw_dump_object(PacketIn, xid=15, buffer_id=1, total_len=1, - in_port=1, - reason=PacketInReason.OFPR_ACTION) - # Different from the specification, the minimum size of this class is - # 18, not 20. - super().set_minimum_size(18) + dumpfile = 'v0x01/ofpt_packet_in.dat' + obj = PacketIn(xid=15, buffer_id=1, total_len=1, + in_port=1, + reason=PacketInReason.OFPR_ACTION) + + # Different from the specification, the minimum size of this class is + # 18, not 20. + min_size = 18 From 7accf0a1a3c3c388ebaafee14acfe29668be8bac Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:16:09 -0300 Subject: [PATCH 13/53] apply new test implementation for PortStatus --- .../test_asynchronous/test_port_status.py | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/tests/v0x01/test_asynchronous/test_port_status.py b/tests/v0x01/test_asynchronous/test_port_status.py index e641718e9..8cb4ce520 100644 --- a/tests/v0x01/test_asynchronous/test_port_status.py +++ b/tests/v0x01/test_asynchronous/test_port_status.py @@ -4,31 +4,37 @@ from pyof.v0x01.asynchronous.port_status import PortReason, PortStatus from pyof.v0x01.common.phy_port import ( PhyPort, PortConfig, PortFeatures, PortState) -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile, TestMsgDump -class TestPortStatus(TestStruct): - """Test the Port Status message.""" +class TestPortStatus_1(TestMsgDumpFile): + """Test the PortStatus class.""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_port_status') - super().set_raw_dump_object(_new_portstatus) - super().set_minimum_size(64) + dumpfile = 'v0x01/ofpt_port_status.dat' + + desc_name = 's1-eth1' + desc = PhyPort(port_no=1, + hw_addr=HWAddress('9a:da:11:8a:f4:0c'), + name=desc_name, + config=0, + state=0, + curr=192, + advertised=0, + supported=0, + peer=0) + obj = PortStatus(xid=0, + reason=PortReason.OFPPR_MODIFY, + desc=desc) - def test_pack(self): - """Skip pack test for now.""" - self.skipTest('Need to recover dump contents.') - def test_unpack(self): - """Skipt unpack test for now.""" - self.skipTest('Need to recover dump contents.') +class TestPortStatus_2(TestMsgDump): + """Test the PortStatus class.""" + dump = b'\x01\x0c\x00@\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00' + dump += b'\x00\x00\x02\n\n\x12\x12\x10\x10XXXXXXXXXXXXXXX\x00\x00\x00' + dump += b'\x00\x02\x00\x00\x02\x00\x00\x00\x00@\x00\x00\x04\x00\x00' + dump += b'\x00\x02\x00\x00\x00\x02\x00' # needs to be checked -def _new_portstatus(): - """Crate new PortStatus and PhyPort instances.""" desc_name = 'X' * OFP_MAX_PORT_NAME_LEN desc = PhyPort(port_no=2, hw_addr=HWAddress('0a:0a:12:12:10:10'), @@ -39,6 +45,6 @@ def _new_portstatus(): advertised=PortFeatures.OFPPF_PAUSE, supported=PortFeatures.OFPPF_AUTONEG, peer=PortFeatures.OFPPF_AUTONEG) - return PortStatus(xid=1, - reason=PortReason.OFPPR_ADD, - desc=desc) + obj = PortStatus(xid=1, + reason=PortReason.OFPPR_ADD, + desc=desc) From 6509eb1e7eb8a2260d23bb20abf7f77f76f66e4f Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:22:05 -0300 Subject: [PATCH 14/53] apply new test implementation for actions --- tests/v0x01/test_common/test_action.py | 126 +++++++++---------------- 1 file changed, 43 insertions(+), 83 deletions(-) diff --git a/tests/v0x01/test_common/test_action.py b/tests/v0x01/test_common/test_action.py index cb9937135..493335a7d 100644 --- a/tests/v0x01/test_common/test_action.py +++ b/tests/v0x01/test_common/test_action.py @@ -3,122 +3,82 @@ ActionDLAddr, ActionEnqueue, ActionNWAddr, ActionNWTos, ActionOutput, ActionTPPort, ActionType, ActionVendorHeader, ActionVlanPCP, ActionVlanVid) from pyof.v0x01.common.phy_port import Port -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestActionOutput(TestStruct): +class TestActionOutput(TestMsgDumpFile): """ActionOutput message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_output') - super().set_raw_dump_object(ActionOutput, port=Port.OFPP_CONTROLLER, - max_length=8) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_action_output.dat' + obj = ActionOutput(port=Port.OFPP_CONTROLLER, + max_length=8) + min_size = 8 -class TestActionEnqueue(TestStruct): +class TestActionEnqueue(TestMsgDumpFile): """ActionEnqueue message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_enqueue') - super().set_raw_dump_object(ActionEnqueue, port=Port.OFPP_CONTROLLER, - queue_id=4) - super().set_minimum_size(16) + dumpfile = 'v0x01/ofpt_action_enqueue.dat' + obj = ActionEnqueue(port=Port.OFPP_CONTROLLER, + queue_id=4) + min_size = 16 -class TestActionVlanVid(TestStruct): +class TestActionVlanVid(TestMsgDumpFile): """ActionVlanVid message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_vlan_vid') - super().set_raw_dump_object(ActionVlanVid, vlan_id=5) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_action_vlan_vid.dat' + obj = ActionVlanVid(vlan_id=5) + min_size = 8 -class TestActionVlanPCP(TestStruct): +class TestActionVlanPCP(TestMsgDumpFile): """ActionVlanPCP message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_vlan_pcp') - super().set_raw_dump_object(ActionVlanPCP, vlan_pcp=2) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_action_vlan_pcp.dat' + obj = ActionVlanPCP(vlan_pcp=2) + min_size = 8 -class TestActionDLAddr(TestStruct): +class TestActionDLAddr(TestMsgDumpFile): """ActionDLAddr message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_dl_addr') - super().set_raw_dump_object(ActionDLAddr, - dl_addr_type=ActionType.OFPAT_SET_DL_SRC, - dl_addr=[12, 12, 12, 12, 12, 12]) - super().set_minimum_size(16) + dumpfile = 'v0x01/ofpt_action_dl_addr.dat' + obj = ActionDLAddr(dl_addr_type=ActionType.OFPAT_SET_DL_SRC, + dl_addr=[12, 12, 12, 12, 12, 12]) + min_size = 16 -class TestActionNWAddr(TestStruct): +class TestActionNWAddr(TestMsgDumpFile): """ActionNWAddr message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_nw_addr') - super().set_raw_dump_object(ActionNWAddr, - nw_addr_type=ActionType.OFPAT_SET_NW_SRC, - nw_addr=[12, 12, 12, 12, 12, 12]) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_action_nw_addr.dat' + obj = ActionNWAddr(nw_addr_type=ActionType.OFPAT_SET_NW_SRC, + nw_addr=[12, 12, 12, 12, 12, 12]) + min_size = 8 -class TestActionNWTos(TestStruct): +class TestActionNWTos(TestMsgDumpFile): """ActionNWTos message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_nw_tos') - super().set_raw_dump_object(ActionNWTos, - nw_tos_type=ActionType.OFPAT_SET_NW_SRC, - nw_tos=123456) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_action_nw_tos.dat' + obj = ActionNWTos(nw_tos_type=ActionType.OFPAT_SET_NW_SRC, + nw_tos=123456) + min_size = 8 -class TestActionTPPort(TestStruct): +class TestActionTPPort(TestMsgDumpFile): """ActionTPPort message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_tp_port') - super().set_raw_dump_object(ActionTPPort, - tp_port_type=ActionType.OFPAT_SET_TP_SRC, - tp_port=8888) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_action_tp_port.dat' + obj = ActionTPPort(tp_port_type=ActionType.OFPAT_SET_TP_SRC, + tp_port=8888) + min_size = 8 -class TestActionVendorHeader(TestStruct): +class TestActionVendorHeader(TestMsgDumpFile): """ActionVendorHeader message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_action_vendor_header') - super().set_raw_dump_object(ActionVendorHeader, length=16, vendor=1) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_action_vendor_header.dat' + obj = ActionVendorHeader(length=16, vendor=1) + min_size = 8 From d616fe5a19ea90c3975819d3d7d24642a7f64973 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 12:14:18 -0300 Subject: [PATCH 15/53] apply new test implementation for actions --- tests/v0x01/test_common/test_action.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/v0x01/test_common/test_action.py b/tests/v0x01/test_common/test_action.py index 493335a7d..fb85a4b8b 100644 --- a/tests/v0x01/test_common/test_action.py +++ b/tests/v0x01/test_common/test_action.py @@ -44,7 +44,7 @@ class TestActionDLAddr(TestMsgDumpFile): """ActionDLAddr message tests (also those in :class:`.TestDump`).""" dumpfile = 'v0x01/ofpt_action_dl_addr.dat' - obj = ActionDLAddr(dl_addr_type=ActionType.OFPAT_SET_DL_SRC, + obj = ActionDLAddr(action_type=ActionType.OFPAT_SET_DL_SRC, dl_addr=[12, 12, 12, 12, 12, 12]) min_size = 16 @@ -53,7 +53,7 @@ class TestActionNWAddr(TestMsgDumpFile): """ActionNWAddr message tests (also those in :class:`.TestDump`).""" dumpfile = 'v0x01/ofpt_action_nw_addr.dat' - obj = ActionNWAddr(nw_addr_type=ActionType.OFPAT_SET_NW_SRC, + obj = ActionNWAddr(action_type=ActionType.OFPAT_SET_NW_SRC, nw_addr=[12, 12, 12, 12, 12, 12]) min_size = 8 @@ -62,7 +62,7 @@ class TestActionNWTos(TestMsgDumpFile): """ActionNWTos message tests (also those in :class:`.TestDump`).""" dumpfile = 'v0x01/ofpt_action_nw_tos.dat' - obj = ActionNWTos(nw_tos_type=ActionType.OFPAT_SET_NW_SRC, + obj = ActionNWTos(action_type=ActionType.OFPAT_SET_NW_SRC, nw_tos=123456) min_size = 8 @@ -71,7 +71,7 @@ class TestActionTPPort(TestMsgDumpFile): """ActionTPPort message tests (also those in :class:`.TestDump`).""" dumpfile = 'v0x01/ofpt_action_tp_port.dat' - obj = ActionTPPort(tp_port_type=ActionType.OFPAT_SET_TP_SRC, + obj = ActionTPPort(action_type=ActionType.OFPAT_SET_TP_SRC, tp_port=8888) min_size = 8 From e2209c9fb9cea4476a02cf27851723ef92d86d2b Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:35:24 -0300 Subject: [PATCH 16/53] apply new test implementation for Match class --- tests/v0x01/test_common/test_flow_match.py | 71 ++++++++++------------ 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/tests/v0x01/test_common/test_flow_match.py b/tests/v0x01/test_common/test_flow_match.py index 4c804c667..95704e706 100644 --- a/tests/v0x01/test_common/test_flow_match.py +++ b/tests/v0x01/test_common/test_flow_match.py @@ -1,45 +1,38 @@ """Testing FlowMatch structure.""" -import unittest +from pyof.foundation.basic_types import HWAddress, IPAddress +from pyof.v0x01.common.flow_match import Match +from tests.test_struct import TestStructDump -from pyof.v0x01.common import flow_match - -class TestMatch(unittest.TestCase): +class TestMatch(TestStructDump): """Test Match structure.""" - def setUp(self): - """Basic setup for test.""" - self.message = flow_match.Match() - self.message.in_port = 22 - self.message.dl_src = [1, 2, 3, 4, 5, 6] - self.message.dl_dst = [1, 2, 3, 4, 5, 6] - self.message.dl_vlan = 1 - self.message.dl_vlan_pcp = 1 - self.message.dl_type = 1 - self.message.nw_tos = 1 - self.message.nw_proto = 1 - self.message.nw_src = [192, 168, 0, 1] - self.message.nw_dst = [192, 168, 0, 2] - self.message.tp_src = 22 - self.message.tp_dst = 22 - - def test_get_size(self): - """[Common/FlowMatch] - size 40.""" - self.assertEqual(self.message.get_size(), 40) - - def test_pack_unpack(self): - """[Common/FlowMatch] - packing and unpacking.""" - pack = self.message.pack() - unpacked = flow_match.Match() - unpacked.unpack(pack) - self.assertEqual(self.message.pack(), unpacked.pack()) - - @unittest.skip('Not yet implemented') - def test_pack(self): - """[Common/FlowMatch] - packing.""" - pass + dump = b'\x00\x0f\xff\x00\x00\x16\x01\x02\x03\x04\x05\x06\x01\x02\x03\x04' + dump += b'\x05\x06\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\xc0\xa8\x00\x01' + dump += b'\xc0\xa8\x00\x02\x00\x16\x00\x16' # needs to be checked + obj = Match(in_port=22, + dl_src=[1, 2, 3, 4, 5, 6], + dl_dst=[1, 2, 3, 4, 5, 6], + dl_vlan=1, + dl_vlan_pcp=1, + dl_type=1, + nw_tos=1, + nw_proto=1, + nw_src=[192, 168, 0, 1], + nw_dst=[192, 168, 0, 2], + tp_src=22, + tp_dst=22) + + +class TestMatch_2(TestStructDump): + """Test Match structure.""" - @unittest.skip('Not yet implemented') - def test_unpack(self): - """[Common/FlowMatch] - unpacking.""" - pass + dump = b'\x00\x0f\xff\x0c\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + dump += b'\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\xc0\xa8\x00' + dump += b'\x01\xc0\xa8\x00\x02\x00P\x00P' + obj = Match(in_port=80, dl_vlan=1, dl_vlan_pcp=1, dl_type=1, + nw_tos=1, nw_proto=1, tp_src=80, tp_dst=80, + dl_src=HWAddress('00:00:00:00:00:00'), + dl_dst=HWAddress('00:00:00:00:00:00'), + nw_src=IPAddress('192.168.0.1'), + nw_dst=IPAddress('192.168.0.2')) From 40efb0a2e0c6adc712a2f414af643f8f40a00c2a Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:45:38 -0300 Subject: [PATCH 17/53] apply new test implementation for Header class --- tests/v0x01/test_common/test_header.py | 51 +++++++------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/tests/v0x01/test_common/test_header.py b/tests/v0x01/test_common/test_header.py index 3c01fd80c..22a39cdd0 100644 --- a/tests/v0x01/test_common/test_header.py +++ b/tests/v0x01/test_common/test_header.py @@ -1,52 +1,27 @@ """Testing Header structure.""" -import os import unittest -from unittest.mock import patch +from pyof.foundation.exceptions import PackException from pyof.v0x01.common.header import Header, Type +from tests.test_struct import TestStructDump -class TestHeader(unittest.TestCase): +class TestHeader(TestStructDump): """Test the message Header.""" - def setUp(self): - """Setup the TestHeader Class instantiating a HELLO header.""" - self.message = Header() - self.message.message_type = Type.OFPT_HELLO - self.message.xid = 1 - self.message.length = 0 - - def test_size(self): - """[Common/Header] - size 8.""" - self.assertEqual(self.message.get_size(), 8) + dump = b'\x01\x00\x00\x08\x00\x00\x00\x01' + obj = Header(message_type=Type.OFPT_HELLO, + xid=1, + length=8) @unittest.expectedFailure def test_pack_empty(self): """[Common/Header] - packing empty header.""" - self.assertRaises(TypeError, + self.assertRaises(PackException, Header().pack()) - def test_pack(self): - """[Common/Header] - packing Hello.""" - packed_header = b'\x01\x00\x00\x00\x00\x00\x00\x01' - self.assertEqual(self.message.pack(), packed_header) - - def test_unpack(self): - """[Common/Header] - unpacking Hello.""" - filename = os.path.join(os.path.dirname(os.path.realpath('__file__')), - 'raw/v0x01/ofpt_hello.dat') - f = open(filename, 'rb') - self.message.unpack(f.read(8)) - - self.assertEqual(self.message.length, 8) - self.assertEqual(self.message.xid, 1) - self.assertEqual(self.message.message_type, Type.OFPT_HELLO) - self.assertEqual(self.message.version, 1) - - f.close() - - @patch('pyof.v0x01.common.header.randint') - def test_random_xid(self, m): - """Each Header instantiations without xid should call randint.""" - Header(), Header() # noqa - self.assertEqual(m.call_count, 2) + # @patch('pyof.v0x01.common.header.randint') + # def test_random_xid(self, m): + # """Each Header instantiations without xid should call randint.""" + # Header(), Header() # noqa + # self.assertEqual(m.call_count, 2) From 0c7912e1954f3cbfe07be79ca27471baeb4b7426 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 11:53:09 -0300 Subject: [PATCH 18/53] apply new test implementation for PhyPort class --- tests/v0x01/test_common/test_phy_port.py | 44 ++++++++---------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/tests/v0x01/test_common/test_phy_port.py b/tests/v0x01/test_common/test_phy_port.py index 35cd83ff8..c7f8a3c12 100644 --- a/tests/v0x01/test_common/test_phy_port.py +++ b/tests/v0x01/test_common/test_phy_port.py @@ -1,37 +1,23 @@ """Testing PhyPort structure.""" -from unittest import TestCase, skip - from pyof.foundation.constants import OFP_MAX_PORT_NAME_LEN from pyof.v0x01.common.phy_port import ( PhyPort, PortConfig, PortFeatures, PortState) +from tests.test_struct import TestStructDump -class TestPhyPort(TestCase): - """Test PhyPort.""" - - def setUp(self): - """Basic setup for test.""" - self.message = PhyPort() - self.message.port_no = 2 - self.message.hw_addr = '1a:2b:3c:4d:5e:6f' - self.message.name = bytes('X' * OFP_MAX_PORT_NAME_LEN, 'utf-8') - self.message.config = PortConfig.OFPPC_NO_STP - self.message.state = PortState.OFPPS_STP_FORWARD - self.message.curr = PortFeatures.OFPPF_10GB_FD - self.message.advertised = PortFeatures.OFPPF_PAUSE - self.message.supported = PortFeatures.OFPPF_AUTONEG - self.message.peer = PortFeatures.OFPPF_AUTONEG - - def test_get_size(self): - """[Common/PhyPort] - size 48.""" - self.assertEqual(self.message.get_size(), 48) +class TestPhyPort(TestStructDump): + """Test PhyPort class.""" - @skip('Not yet implemented') - def test_pack(self): - """[Common/PhyPort] - packing.""" - pass + dump = b'\x00\x02\x1a+ Date: Tue, 11 Jul 2017 12:00:43 -0300 Subject: [PATCH 19/53] apply new test implementation for queues --- tests/v0x01/test_common/test_queue.py | 75 +++++---------------------- 1 file changed, 14 insertions(+), 61 deletions(-) diff --git a/tests/v0x01/test_common/test_queue.py b/tests/v0x01/test_common/test_queue.py index d8c184d62..018136697 100644 --- a/tests/v0x01/test_common/test_queue.py +++ b/tests/v0x01/test_common/test_queue.py @@ -1,75 +1,28 @@ """Testing Queue structure.""" -import unittest - from pyof.v0x01.common import queue +from tests.test_struct import TestStructDump -class TestQueuePropHeader(unittest.TestCase): +class TestQueuePropHeader(TestStructDump): """Test QueuePropHeader.""" - def setUp(self): - """Basic setup for test.""" - self.message = queue.QueuePropHeader() - self.message.queue_property = queue.QueueProperties.OFPQT_MIN_RATE - self.message.length = 12 - - def test_get_size(self): - """[Common/QueuePropHeader] - size 8.""" - self.assertEqual(self.message.get_size(), 8) - - @unittest.skip('Not yet implemented') - def test_pack(self): - """[Common/QueuePropHeader] - packing.""" - pass + dump = b'\x00\x01\x00\x0c\x00\x00\x00\x00' # needs to be checked + obj = queue.QueuePropHeader( + queue_property=queue.QueueProperties.OFPQT_MIN_RATE, + length=12) - @unittest.skip('Not yet implemented') - def test_unpack(self): - """[Common/QueuePropHeader] - unpacking.""" - pass - -class TestPacketQueue(unittest.TestCase): +class TestPacketQueue(TestStructDump): """TestPacketQueue.""" - def setUp(self): - """Basic setup for test.""" - self.message = queue.PacketQueue() - self.message.queue_id = 1 - self.message.length = 8 - - def test_get_size(self): - """[Common/PacketQueue] - size 8.""" - self.assertEqual(self.message.get_size(), 8) + dump = b'\x00\x00\x00\x01\x00\x08\x00\x00' # needs to be checked + obj = queue.PacketQueue(queue_id=1, + length=8) - @unittest.skip('Not yet implemented') - def test_pack(self): - """[Common/PacketQueue] - packing.""" - pass - @unittest.skip('Not yet implemented') - def test_unpack(self): - """[Common/PacketQueue] - unpacking.""" - pass - - -class TestQueuePropMinRate(unittest.TestCase): +class TestQueuePropMinRate(TestStructDump): """Test QueuePropMinRate.""" - def setUp(self): - """Basic setup for test.""" - self.message = queue.QueuePropMinRate() - self.message.rate = 1000 - - def test_get_size(self): - """[Common/PropMinRate] - size 16.""" - self.assertEqual(self.message.get_size(), 16) - - @unittest.skip('Not yet implemented') - def test_pack(self): - """[Common/PropMinRate] - packing.""" - pass - - @unittest.skip('Not yet implemented') - def test_unpack(self): - """[Common/PropMinRate] - unpacking.""" - pass + dump = b'\x00\x01\x00\x10\x00\x00\x00\x00\x03\xe8\x00\x00' + dump += b'\x00\x00\x00\x00' # needs to be checked + obj = queue.QueuePropMinRate(rate=1000) From af85d5bba0a362cccea1dfba62e3de121de43ce3 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 12:04:43 -0300 Subject: [PATCH 20/53] apply new test implementation for agg stats reply --- .../test_aggregate_stats_reply.py | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_aggregate_stats_reply.py b/tests/v0x01/test_controller2switch/test_aggregate_stats_reply.py index 53c134cdb..dd3c14809 100644 --- a/tests/v0x01/test_controller2switch/test_aggregate_stats_reply.py +++ b/tests/v0x01/test_controller2switch/test_aggregate_stats_reply.py @@ -1,20 +1,16 @@ """Test for AggregateStatsReply message.""" from pyof.v0x01.controller2switch.common import AggregateStatsReply, StatsTypes from pyof.v0x01.controller2switch.stats_reply import StatsReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestAggregateStatsReply(TestStruct): +class TestAggregateStatsReply(TestMsgDumpFile): """Test for AggregateStatsReply message.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/AggregateStatsReply] - size 24.""" - aggregate_stats_reply = AggregateStatsReply(packet_count=5, - byte_count=1, flow_count=8) - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_aggregate_stats_reply') - super().set_raw_dump_object(StatsReply, xid=17, - body_type=StatsTypes.OFPST_AGGREGATE, - flags=0, body=aggregate_stats_reply) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_aggregate_stats_reply.dat' + aggregate_stats_reply = AggregateStatsReply(packet_count=5, + byte_count=1, flow_count=8) + obj = StatsReply(xid=17, + body_type=StatsTypes.OFPST_AGGREGATE, + flags=0, body=aggregate_stats_reply) + min_size = 12 From 3fb88440fe2de2d1746a60632ec87d44e14d492e Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 12:09:10 -0300 Subject: [PATCH 21/53] apply new test implementation for agg stats request --- .../test_aggregate_stats_request.py | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_aggregate_stats_request.py b/tests/v0x01/test_controller2switch/test_aggregate_stats_request.py index e9f466651..f76dcaa2c 100644 --- a/tests/v0x01/test_controller2switch/test_aggregate_stats_request.py +++ b/tests/v0x01/test_controller2switch/test_aggregate_stats_request.py @@ -4,31 +4,23 @@ from pyof.v0x01.controller2switch.common import ( AggregateStatsRequest, StatsTypes) from pyof.v0x01.controller2switch.stats_request import StatsRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestAggregateStatsRequest(TestStruct): +class TestAggregateStatsRequest(TestMsgDumpFile): """Test class for TestAggregateStatsRequest.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/AggregateStatsRequest] - size 44.""" - request = AggregateStatsRequest(table_id=1, out_port=Port.OFPP_NONE, - match=_get_match()) + dumpfile = 'v0x01/ofpt_aggregate_request.dat' - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_aggregate_request') - super().set_raw_dump_object(StatsRequest, xid=17, - body_type=StatsTypes.OFPST_AGGREGATE, - flags=0, body=request) - super().set_minimum_size(12) - - -def _get_match(): - """Function used to built Match instance used by AggregateStatsRequest.""" - return Match(in_port=80, dl_src="01:02:03:04:05:06", - dl_dst="01:02:03:04:05:06", dl_vlan=1, - dl_vlan_pcp=1, dl_type=1, - nw_tos=1, nw_proto=1, - nw_src='192.168.0.1', nw_dst='192.168.0.1', - tp_src=80, tp_dst=80) + match = Match(in_port=80, dl_src="01:02:03:04:05:06", + dl_dst="01:02:03:04:05:06", dl_vlan=1, + dl_vlan_pcp=1, dl_type=1, + nw_tos=1, nw_proto=1, + nw_src='192.168.0.1', nw_dst='192.168.0.1', + tp_src=80, tp_dst=80) + request = AggregateStatsRequest(table_id=1, out_port=Port.OFPP_NONE, + match=match) + obj = StatsRequest(xid=17, + body_type=StatsTypes.OFPST_AGGREGATE, + flags=0, body=request) + min_size = 12 From 4190b19b8c8b22e9f626b2ee4f6fe899afb9a5a6 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 13:29:04 -0300 Subject: [PATCH 22/53] apply new test implementation for BarrierReply class --- .../test_controller2switch/test_barrier_reply.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_barrier_reply.py b/tests/v0x01/test_controller2switch/test_barrier_reply.py index 7c1972700..97e550696 100644 --- a/tests/v0x01/test_controller2switch/test_barrier_reply.py +++ b/tests/v0x01/test_controller2switch/test_barrier_reply.py @@ -1,15 +1,11 @@ """Barrier reply message tests.""" from pyof.v0x01.controller2switch.barrier_reply import BarrierReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestBarrierReply(TestStruct): - """Barrier reply message tests (also those in :class:`.TestDump`).""" +class TestBarrierReply(TestMsgDumpFile): + """Barrier reply message tests.""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_barrier_reply') - super().set_raw_dump_object(BarrierReply, xid=5) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_barrier_reply.dat' + obj = BarrierReply(xid=5) + min_size = 8 From baa5104f4bde9f286eddf6713ace489b1817559b Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 13:30:07 -0300 Subject: [PATCH 23/53] apply new test implementation for BarrierRequest class --- .../test_barrier_request.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_barrier_request.py b/tests/v0x01/test_controller2switch/test_barrier_request.py index ab8c459ee..e888d56e4 100644 --- a/tests/v0x01/test_controller2switch/test_barrier_request.py +++ b/tests/v0x01/test_controller2switch/test_barrier_request.py @@ -1,15 +1,11 @@ """Barrier request message tests.""" from pyof.v0x01.controller2switch.barrier_request import BarrierRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestBarrierRequest(TestStruct): - """Barrier reply message tests (also those in :class:`.TestDump`).""" +class TestBarrierRequest(TestMsgDumpFile): + """Barrier request message tests.""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_barrier_request') - super().set_raw_dump_object(BarrierRequest, xid=5) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_barrier_request.dat' + obj = BarrierRequest(xid=5) + min_size = 8 From 740ad265d13671ad53fbe377238baa39ff296e7f Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 13:48:35 -0300 Subject: [PATCH 24/53] apply new test implementation for DescStats class --- .../test_controller2switch/test_desc_stats.py | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_desc_stats.py b/tests/v0x01/test_controller2switch/test_desc_stats.py index 6ed2559a3..dc1f83825 100644 --- a/tests/v0x01/test_controller2switch/test_desc_stats.py +++ b/tests/v0x01/test_controller2switch/test_desc_stats.py @@ -2,26 +2,19 @@ from pyof.foundation.constants import DESC_STR_LEN from pyof.v0x01.controller2switch.common import DescStats, StatsTypes from pyof.v0x01.controller2switch.stats_reply import StatsReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestDescStats(TestStruct): +class TestDescStats(TestMsgDumpFile): """Test class for TestDescStats.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/DescStats] - size 1056.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_desc_stats_reply') - super().set_raw_dump_object(StatsReply, xid=14, - body_type=StatsTypes.OFPST_DESC, - flags=0, body=_get_desc_stats()) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_desc_stats_reply.dat' - -def _get_desc_stats(): - """Function used to return desc_stat used by StatsReply instance.""" content = 'A' * DESC_STR_LEN - return DescStats(mfr_desc=content, hw_desc=content, + desc = DescStats(mfr_desc=content, hw_desc=content, sw_desc=content, serial_num=content, dp_desc=content) + obj = StatsReply(xid=14, + body_type=StatsTypes.OFPST_DESC, + flags=0, body=desc) + min_size = 12 From 4f7db61a0685daf6ce87a3706015184c4a5c881c Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 13:52:21 -0300 Subject: [PATCH 25/53] apply new test implementation for FeaturesReply class --- .../test_features_reply.py | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_features_reply.py b/tests/v0x01/test_controller2switch/test_features_reply.py index 8d6e4ea9c..0dd40605a 100644 --- a/tests/v0x01/test_controller2switch/test_features_reply.py +++ b/tests/v0x01/test_controller2switch/test_features_reply.py @@ -8,24 +8,9 @@ class TestFeaturesReply(TestStruct): """Feature reply message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_features_reply') - kwargs = _get_kwargs() - super().set_raw_dump_object(FeaturesReply, **kwargs) - super().set_minimum_size(32) + dumpfile = 'v0x01/ofpt_features_reply.dat' - -def _get_kwargs(): - return {'xid': 2, 'datapath_id': DPID('00:00:00:00:00:00:00:01'), - 'n_buffers': 256, 'n_tables': 254, 'capabilities': 0x000000c7, - 'actions': 4095, 'ports': _get_ports()} - - -def _get_ports(): - return [ + ports = [ PhyPort(port_no=65534, hw_addr=HWAddress('0e:d3:98:a5:30:47'), name='s1', @@ -52,5 +37,11 @@ def _get_ports(): curr=0x000000c0, advertised=0, supported=0, - peer=0) - ] + peer=0)] + + obj = FeaturesReply(xid=2, + datapath_id=DPID('00:00:00:00:00:00:00:01'), + n_buffers=256, n_tables=254, + capabilities=0x000000c7, + actions=4095, ports=ports) + min_size = 32 From a09632fda4da21363f101d7ef34114534121bf99 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 13:54:40 -0300 Subject: [PATCH 26/53] apply new test implementation for FeaturesRequest class --- .../test_controller2switch/test_features_reply.py | 4 ++-- .../test_features_request.py | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_features_reply.py b/tests/v0x01/test_controller2switch/test_features_reply.py index 0dd40605a..30ae35ee1 100644 --- a/tests/v0x01/test_controller2switch/test_features_reply.py +++ b/tests/v0x01/test_controller2switch/test_features_reply.py @@ -2,10 +2,10 @@ from pyof.foundation.basic_types import DPID, HWAddress from pyof.v0x01.common.phy_port import PhyPort, PortConfig, PortState from pyof.v0x01.controller2switch.features_reply import FeaturesReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestFeaturesReply(TestStruct): +class TestFeaturesReply(TestMsgDumpFile): """Feature reply message tests (also those in :class:`.TestDump`).""" dumpfile = 'v0x01/ofpt_features_reply.dat' diff --git a/tests/v0x01/test_controller2switch/test_features_request.py b/tests/v0x01/test_controller2switch/test_features_request.py index 78cb01082..176f7d30f 100644 --- a/tests/v0x01/test_controller2switch/test_features_request.py +++ b/tests/v0x01/test_controller2switch/test_features_request.py @@ -1,15 +1,11 @@ """Feature request message tests.""" from pyof.v0x01.controller2switch.features_request import FeaturesRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestFeaturesRequest(TestStruct): +class TestFeaturesRequest(TestMsgDumpFile): """Feature request message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_features_request') - super().set_raw_dump_object(FeaturesRequest, xid=3) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_features_request.dat' + obj = FeaturesRequest(xid=3) + min_size = 8 From 16bd12f59ac18550760a93d12d1258e157a87ba4 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 13:59:44 -0300 Subject: [PATCH 27/53] apply new test implementation for FlowMod class --- .../test_controller2switch/test_flow_mod.py | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_flow_mod.py b/tests/v0x01/test_controller2switch/test_flow_mod.py index fb0385677..7c73c27cd 100644 --- a/tests/v0x01/test_controller2switch/test_flow_mod.py +++ b/tests/v0x01/test_controller2switch/test_flow_mod.py @@ -3,33 +3,7 @@ from pyof.v0x01.common.flow_match import Match from pyof.v0x01.common.phy_port import Port from pyof.v0x01.controller2switch.flow_mod import FlowMod, FlowModCommand -from tests.test_struct import TestStruct - - -class TestFlowAdd(TestStruct): - """Flow addition message tests (also those in :class:`.TestDump`).""" - - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_flow_add') - kwargs = _get_flowmod_kwargs(FlowModCommand.OFPFC_ADD) - super().set_raw_dump_object(FlowMod, **kwargs) - super().set_minimum_size(72) - - -class TestFlowDelete(TestStruct): - """Flow deletion message tests (also those in :class:`.TestDump`).""" - - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_flow_delete') - kwargs = _get_flowmod_kwargs(FlowModCommand.OFPFC_DELETE) - super().set_raw_dump_object(FlowMod, **kwargs) - # No need to test minimum size again. +from tests.test_struct import TestMsgDumpFile def _get_flowmod_kwargs(command): @@ -56,3 +30,20 @@ def _get_actions(): """Return a List of actions registered by flow object.""" action = ActionOutput(port=65533, max_length=65535) return [action] + + +class TestFlowAdd(TestMsgDumpFile): + """Flow addition message tests (also those in :class:`.TestDump`).""" + + dumpfile = 'v0x01/ofpt_flow_add.dat' + kwargs = _get_flowmod_kwargs(FlowModCommand.OFPFC_ADD) + obj = FlowMod(**kwargs) + min_size = 72 + + +class TestFlowDelete(TestMsgDumpFile): + """Flow deletion message tests (also those in :class:`.TestDump`).""" + + dumpfile = 'v0x01/ofpt_flow_delete.dat' + kwargs = _get_flowmod_kwargs(FlowModCommand.OFPFC_DELETE) + obj = FlowMod(**kwargs) From 9f846c9cf69888b20e35760de7304f1105fffb56 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:04:04 -0300 Subject: [PATCH 28/53] apply new test implementation for flow stats (StatsReply msg) --- .../test_controller2switch/test_flow_stats.py | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_flow_stats.py b/tests/v0x01/test_controller2switch/test_flow_stats.py index 873c8c28b..6f22882a5 100644 --- a/tests/v0x01/test_controller2switch/test_flow_stats.py +++ b/tests/v0x01/test_controller2switch/test_flow_stats.py @@ -2,21 +2,7 @@ from pyof.v0x01.common.flow_match import Match from pyof.v0x01.controller2switch.common import FlowStats, StatsTypes from pyof.v0x01.controller2switch.stats_reply import StatsReply -from tests.test_struct import TestStruct - - -class TestFlowStats(TestStruct): - """Test class for TestFlowStats.""" - - @classmethod - def setUpClass(cls): - """[Controller2Switch/FlowStats] - size 88.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_flow_stats_reply') - super().set_raw_dump_object(StatsReply, xid=12, - body_type=StatsTypes.OFPST_FLOW, - flags=0, body=_get_flow_stats()) - super().set_minimum_size(12) +from tests.test_struct import TestMsgDumpFile def _get_flow_stats(): @@ -36,3 +22,13 @@ def _get_match(): nw_tos=1, nw_proto=1, nw_src='192.168.0.1', nw_dst='192.168.0.1', tp_src=80, tp_dst=80) + + +class TestFlowStats(TestMsgDumpFile): + """Test class for TestFlowStats.""" + + dumpfile = 'v0x01/ofpt_flow_stats_reply.dat' + obj = StatsReply(xid=12, + body_type=StatsTypes.OFPST_FLOW, + flags=0, body=_get_flow_stats()) + min_size = 12 From d4be345c1292964388f56a0f20a2735fed950cd7 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:07:15 -0300 Subject: [PATCH 29/53] apply new test implementation for flow stats request --- .../test_flow_stats_request.py | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_flow_stats_request.py b/tests/v0x01/test_controller2switch/test_flow_stats_request.py index 1a1b73914..ea1e4748c 100644 --- a/tests/v0x01/test_controller2switch/test_flow_stats_request.py +++ b/tests/v0x01/test_controller2switch/test_flow_stats_request.py @@ -2,32 +2,23 @@ from pyof.v0x01.common.flow_match import Match from pyof.v0x01.controller2switch.common import FlowStatsRequest, StatsTypes from pyof.v0x01.controller2switch.stats_request import StatsRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestFlowStatsRequest(TestStruct): +class TestFlowStatsRequest(TestMsgDumpFile): """Test class for TestFlowStatsRequest.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/FlowStatsRequest] - size 44.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_flow_stats_request') - super().set_raw_dump_object(StatsRequest, xid=12, - body_type=StatsTypes.OFPST_FLOW, - flags=0, body=_get_flow_stats_request()) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_flow_stats_request.dat' + match = Match(in_port=80, dl_src='01:02:03:04:05:06', + dl_dst='01:02:03:04:05:06', dl_vlan=1, + dl_vlan_pcp=1, dl_type=1, + nw_tos=1, nw_proto=1, + nw_src='192.168.0.1', nw_dst='192.168.0.1', + tp_src=80, tp_dst=80) + flow_sr = FlowStatsRequest(match=match, table_id=1, out_port=80) + obj = StatsRequest(xid=12, + body_type=StatsTypes.OFPST_FLOW, + flags=0, body=flow_sr) -def _get_flow_stats_request(): - return FlowStatsRequest(match=_get_match(), table_id=1, out_port=80) - - -def _get_match(): - """Function used to return a Match instance.""" - return Match(in_port=80, dl_src='01:02:03:04:05:06', - dl_dst='01:02:03:04:05:06', dl_vlan=1, - dl_vlan_pcp=1, dl_type=1, - nw_tos=1, nw_proto=1, - nw_src='192.168.0.1', nw_dst='192.168.0.1', - tp_src=80, tp_dst=80) + min_size = 12 From db73a7d1dcad29a33425dbaba57b1badd4812047 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:08:27 -0300 Subject: [PATCH 30/53] apply new test implementation for get config reply --- .../test_get_config_reply.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_get_config_reply.py b/tests/v0x01/test_controller2switch/test_get_config_reply.py index d0ab90c5e..f4075558a 100644 --- a/tests/v0x01/test_controller2switch/test_get_config_reply.py +++ b/tests/v0x01/test_controller2switch/test_get_config_reply.py @@ -1,18 +1,14 @@ """Test GetConfigReply message.""" from pyof.v0x01.controller2switch.common import ConfigFlags from pyof.v0x01.controller2switch.get_config_reply import GetConfigReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestGetConfigReply(TestStruct): +class TestGetConfigReply(TestMsgDumpFile): """Test class for TestGetConfigReply.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/GetConfigReply] - size 12.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_get_config_reply') - super().set_raw_dump_object(GetConfigReply, xid=13, - flags=ConfigFlags.OFPC_FRAG_REASM, - miss_send_len=1024) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_get_config_reply.dat' + obj = GetConfigReply(xid=13, + flags=ConfigFlags.OFPC_FRAG_REASM, + miss_send_len=1024) + min_size = 12 From ef4f5ba9cd536eeca2e2dea1fa954adc93736715 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:09:21 -0300 Subject: [PATCH 31/53] apply new test implementation for get config request --- .../test_get_config_request.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_get_config_request.py b/tests/v0x01/test_controller2switch/test_get_config_request.py index 7b74ed4bd..42b81c63a 100644 --- a/tests/v0x01/test_controller2switch/test_get_config_request.py +++ b/tests/v0x01/test_controller2switch/test_get_config_request.py @@ -1,15 +1,11 @@ """Test GetConfigRequest message.""" from pyof.v0x01.controller2switch.get_config_request import GetConfigRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestGetConfigRequest(TestStruct): - """Test class for TestGetConfigRequest.""" +class TestGetConfigReply(TestMsgDumpFile): + """Test class for TestGetConfigReply.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/GetConfigRequest] - size 8.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_get_config_request') - super().set_raw_dump_object(GetConfigRequest, xid=1) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_get_config_request.dat' + obj = GetConfigRequest(xid=1) + min_size = 9 From 4f5e66de7fb1d59577d5c2deffa90350f1520320 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:13:38 -0300 Subject: [PATCH 32/53] apply new test implementation for packet out --- .../test_controller2switch/test_packet_out.py | 64 ++++++++----------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_packet_out.py b/tests/v0x01/test_controller2switch/test_packet_out.py index 00ea79783..aecf0a854 100644 --- a/tests/v0x01/test_controller2switch/test_packet_out.py +++ b/tests/v0x01/test_controller2switch/test_packet_out.py @@ -1,72 +1,60 @@ """Packet out message tests.""" from pyof.foundation.exceptions import ValidationError -from pyof.v0x01.common.action import ActionOutput +from pyof.v0x01.common.action import ActionOutput, ListOfActions from pyof.v0x01.common.phy_port import Port from pyof.v0x01.controller2switch.packet_out import PacketOut -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestPacketOut(TestStruct): +class TestPacketOut(TestMsgDumpFile): """Packet out message tests (also those in :class:`.TestDump`). Attributes: message (PacketOut): The message configured in :meth:`setUpClass`. """ - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_packet_out') - super().set_raw_dump_object(PacketOut, xid=8, buffer_id=4294967295, - in_port=Port.OFPP_NONE, data=_get_data(), - actions=_get_actions()) - super().set_minimum_size(16) + dumpfile = 'v0x01/ofpt_packet_out.dat' - def setUp(self): - """Run before every test.""" - self.message = self.get_raw_object() + actions = ListOfActions(items=ActionOutput(port=1, max_length=0)) + data = b'\x01# \x00\x00\x01\xd2A\xc6.*@\x88\xcc\x02\x07\x07dpi' + data += b'd:1\x04\x02\x021\x06\x02\x00x\x0c\x06dpid:1\x00\x00' + obj = PacketOut(xid=8, buffer_id=4294967295, + in_port=Port.OFPP_NONE, data=data, + actions=actions) + min_size = 16 + + def _get_new_obj(self, port): + return PacketOut(xid=8, buffer_id=4294967295, + in_port=port, data=self.data, + actions=self.actions) def test_valid_virtual_in_ports(self): """Valid virtual ports as defined in 1.0.1 spec.""" valid = (Port.OFPP_LOCAL, Port.OFPP_CONTROLLER, Port.OFPP_NONE) for in_port in valid: - self.message.in_port = in_port - self.assertTrue(self.message.is_valid()) + obj = self._get_new_obj(in_port) + self.assertTrue(obj.is_valid()) def test_invalid_virtual_in_ports(self): """Invalid virtual ports as defined in 1.0.1 spec.""" invalid = (Port.OFPP_IN_PORT, Port.OFPP_TABLE, Port.OFPP_NORMAL, Port.OFPP_FLOOD, Port.OFPP_ALL) for in_port in invalid: - self.message.in_port = in_port - self.assertFalse(self.message.is_valid()) - self.assertRaises(ValidationError, self.message.validate) + obj = self._get_new_obj(in_port) + self.assertFalse(obj.is_valid()) + self.assertRaises(ValidationError, obj.validate) def test_valid_physical_in_ports(self): """Physical port limits from 1.0.0 spec.""" max_valid = int(Port.OFPP_MAX.value) - 1 for in_port in (1, max_valid): - self.message.in_port = in_port - self.assertTrue(self.message.is_valid()) + obj = self._get_new_obj(in_port) + self.assertTrue(obj.is_valid()) def test_invalid_physical_in_port(self): """Physical port limits from 1.0.0 spec.""" max_valid = int(Port.OFPP_MAX.value) - 1 for in_port in (-1, 0, max_valid + 1, max_valid + 2): - self.message.in_port = in_port - self.assertFalse(self.message.is_valid()) - self.assertRaises(ValidationError, self.message.validate) - - -def _get_actions(): - """Function used to return a list of actions used by packetout instance.""" - action = ActionOutput(port=1, max_length=0) - return [action] - - -def _get_data(): - """Function used to return a BinaryData used by packetout instance.""" - data = b'\x01# \x00\x00\x01\xd2A\xc6.*@\x88\xcc\x02\x07\x07dpi' - data += b'd:1\x04\x02\x021\x06\x02\x00x\x0c\x06dpid:1\x00\x00' - return data + obj = self._get_new_obj(in_port) + self.assertFalse(obj.is_valid()) + self.assertRaises(ValidationError, obj.validate) From 51f77d54814685d5d48cd2a909595968eeda8cc6 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:15:22 -0300 Subject: [PATCH 33/53] apply new test implementation for port mod --- .../test_controller2switch/test_port_mod.py | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_port_mod.py b/tests/v0x01/test_controller2switch/test_port_mod.py index 62fbd8a22..2a7abbbdd 100644 --- a/tests/v0x01/test_controller2switch/test_port_mod.py +++ b/tests/v0x01/test_controller2switch/test_port_mod.py @@ -1,20 +1,16 @@ """Test PortMod message.""" from pyof.v0x01.common.phy_port import PortConfig, PortFeatures from pyof.v0x01.controller2switch.port_mod import PortMod -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestPortMod(TestStruct): +class TestPortMod(TestMsgDumpFile): """Test class for PortMod.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/PortMod] - size 32.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_port_mod') - super().set_raw_dump_object(PortMod, xid=3, port_no=80, - hw_addr='aa:bb:cc:00:33:9f', - config=PortConfig.OFPPC_PORT_DOWN, - mask=PortConfig.OFPPC_NO_FWD, - advertise=PortFeatures.OFPPF_FIBER) - super().set_minimum_size(32) + dumpfile = 'v0x01/ofpt_port_mod.dat' + obj = PortMod(xid=3, port_no=80, + hw_addr='aa:bb:cc:00:33:9f', + config=PortConfig.OFPPC_PORT_DOWN, + mask=PortConfig.OFPPC_NO_FWD, + advertise=PortFeatures.OFPPF_FIBER) + min_size = 32 From 0dcf9722cb50e88b815871b08cf9ba8ccc67ab8e Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:17:31 -0300 Subject: [PATCH 34/53] apply new test implementation for port stats --- .../test_controller2switch/test_port_stats.py | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_port_stats.py b/tests/v0x01/test_controller2switch/test_port_stats.py index 5da63d2cb..00796a308 100644 --- a/tests/v0x01/test_controller2switch/test_port_stats.py +++ b/tests/v0x01/test_controller2switch/test_port_stats.py @@ -1,27 +1,20 @@ """Test for PortStats structure.""" from pyof.v0x01.controller2switch.common import PortStats, StatsTypes from pyof.v0x01.controller2switch.stats_reply import StatsReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestPortStats(TestStruct): +class TestPortStats(TestMsgDumpFile): """Test for PortStats structure.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/PortStats] - size 104.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_port_stats') - super().set_raw_dump_object(StatsReply, xid=13, - body_type=StatsTypes.OFPST_PORT, - flags=0, body=_get_port_stats()) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_port_stats.dat' - -def _get_port_stats(): - """Function used to return a PortStats instance.""" - return PortStats(port_no=80, rx_packets=5, tx_packets=10, - rx_bytes=200, tx_bytes=400, rx_dropped=0, - tx_dropped=0, rx_errors=0, tx_errors=0, - rx_frame_err=0, rx_over_err=0, - rx_crc_err=0, collisions=0) + port_stats = PortStats(port_no=80, rx_packets=5, tx_packets=10, + rx_bytes=200, tx_bytes=400, rx_dropped=0, + tx_dropped=0, rx_errors=0, tx_errors=0, + rx_frame_err=0, rx_over_err=0, + rx_crc_err=0, collisions=0) + obj = StatsReply(xid=13, + body_type=StatsTypes.OFPST_PORT, + flags=0, body=port_stats) + min_size = 12 From fb289de1fa7128b64cda1c7e9ada5d671c29ca5d Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:18:35 -0300 Subject: [PATCH 35/53] apply new test implementation for port stats request --- .../test_port_stats_request.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_port_stats_request.py b/tests/v0x01/test_controller2switch/test_port_stats_request.py index f63b0fca8..c5b512a2f 100644 --- a/tests/v0x01/test_controller2switch/test_port_stats_request.py +++ b/tests/v0x01/test_controller2switch/test_port_stats_request.py @@ -1,18 +1,14 @@ """Test for PortStatsRequest.""" from pyof.v0x01.controller2switch.common import PortStatsRequest, StatsTypes from pyof.v0x01.controller2switch.stats_request import StatsRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestPortStatsRequest(TestStruct): +class TestPortStatsRequest(TestMsgDumpFile): """Test for PortStatsRequest.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/PortStatsRequest] - size 8.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_port_stats_request') - super().set_raw_dump_object(StatsRequest, xid=17, - body_type=StatsTypes.OFPST_PORT, - flags=0, body=PortStatsRequest(port_no=80)) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_port_stats_request.dat' + obj = StatsRequest(xid=17, + body_type=StatsTypes.OFPST_PORT, + flags=0, body=PortStatsRequest(port_no=80)) + min_size = 12 From 4d308094e9dd130ba8d216dc68cd4f419fe74035 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:21:43 -0300 Subject: [PATCH 36/53] apply new test implementation for get config reply --- .../test_queue_get_config_reply.py | 36 ++++++------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_queue_get_config_reply.py b/tests/v0x01/test_controller2switch/test_queue_get_config_reply.py index f103e1272..861685df1 100644 --- a/tests/v0x01/test_controller2switch/test_queue_get_config_reply.py +++ b/tests/v0x01/test_controller2switch/test_queue_get_config_reply.py @@ -3,34 +3,18 @@ from pyof.v0x01.common.queue import ( PacketQueue, QueueProperties, QueuePropHeader) from pyof.v0x01.controller2switch import queue_get_config_reply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestQueueGetConfigReply(TestStruct): +class TestQueueGetConfigReply(TestMsgDumpFile): """Test for QueueGetConfigReply message.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/QueueGetConfigReply] - size 16.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_queue_get_config_reply') - super().set_raw_dump_object(queue_get_config_reply.QueueGetConfigReply, - xid=1, port=Port.OFPP_ALL, - queues=_get_packet_queue()) - super().set_minimum_size(16) + dumpfile = 'v0x01/ofpt_queue_get_config_reply.dat' - -def _get_packet_queue(): - """Function used to return a PacketQueue instance.""" - packets = [] - packets.append(PacketQueue(queue_id=1, length=8, - properties=_get_queue_properties())) - return packets - - -def _get_queue_properties(): - """Function used to return a list of queue properties.""" - properties = [] - properties.append(QueuePropHeader( - queue_property=QueueProperties.OFPQT_MIN_RATE, length=12)) - return properties + properties = [QueuePropHeader( + queue_property=QueueProperties.OFPQT_MIN_RATE, length=12)] + queues = [PacketQueue(queue_id=1, length=8, + properties=properties)] + obj = queue_get_config_reply.QueueGetConfigReply(xid=1, port=Port.OFPP_ALL, + queues=queues) + min_size = 16 From 11d34b3ed35f0e13cc8633fd236b76c6b2f87d11 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:23:16 -0300 Subject: [PATCH 37/53] apply new test implementation for get config request --- .../test_get_config_request.py | 2 +- .../test_queue_get_config_request.py | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_get_config_request.py b/tests/v0x01/test_controller2switch/test_get_config_request.py index 42b81c63a..74b2fee71 100644 --- a/tests/v0x01/test_controller2switch/test_get_config_request.py +++ b/tests/v0x01/test_controller2switch/test_get_config_request.py @@ -3,7 +3,7 @@ from tests.test_struct import TestMsgDumpFile -class TestGetConfigReply(TestMsgDumpFile): +class TestGetConfigRequest(TestMsgDumpFile): """Test class for TestGetConfigReply.""" dumpfile = 'v0x01/ofpt_get_config_request.dat' diff --git a/tests/v0x01/test_controller2switch/test_queue_get_config_request.py b/tests/v0x01/test_controller2switch/test_queue_get_config_request.py index ff17319b8..b3362aad4 100644 --- a/tests/v0x01/test_controller2switch/test_queue_get_config_request.py +++ b/tests/v0x01/test_controller2switch/test_queue_get_config_request.py @@ -1,17 +1,12 @@ """Test for QueueGetConfigRequest message.""" from pyof.v0x01.common.phy_port import Port from pyof.v0x01.controller2switch import queue_get_config_request as request -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestQueueGetConfigRequest(TestStruct): +class TestQueueGetConfigRequest(TestMsgDumpFile): """Test for QueueGetConfigRequest message.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/QueueGetConfigRequest] - size 12.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_queue_get_config_request') - super().set_raw_dump_object(request.QueueGetConfigRequest, - xid=1, port=Port.OFPP_MAX) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_queue_get_config_request.dat' + obj = request.QueueGetConfigRequest(xid=1, port=Port.OFPP_MAX) + min_size = 12 From 5cddf6ec6dbfc4ba8db11acee44b7c374d067ce7 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 15:19:46 -0300 Subject: [PATCH 38/53] test get config request wrong min size --- tests/v0x01/test_controller2switch/test_get_config_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/v0x01/test_controller2switch/test_get_config_request.py b/tests/v0x01/test_controller2switch/test_get_config_request.py index 74b2fee71..c069beb67 100644 --- a/tests/v0x01/test_controller2switch/test_get_config_request.py +++ b/tests/v0x01/test_controller2switch/test_get_config_request.py @@ -8,4 +8,4 @@ class TestGetConfigRequest(TestMsgDumpFile): dumpfile = 'v0x01/ofpt_get_config_request.dat' obj = GetConfigRequest(xid=1) - min_size = 9 + min_size = 8 From 82b52a2a88b69dcf401a4824c6a51c9efed2b6e8 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:24:56 -0300 Subject: [PATCH 39/53] apply new test implementation for queue stats --- .../test_queue_stats.py | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_queue_stats.py b/tests/v0x01/test_controller2switch/test_queue_stats.py index 51fedddb0..beaa2655e 100644 --- a/tests/v0x01/test_controller2switch/test_queue_stats.py +++ b/tests/v0x01/test_controller2switch/test_queue_stats.py @@ -1,24 +1,16 @@ """Test for QueueStats.""" from pyof.v0x01.controller2switch.common import QueueStats, StatsTypes from pyof.v0x01.controller2switch.stats_reply import StatsReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestQueueStats(TestStruct): +class TestQueueStats(TestMsgDumpFile): """Test for QueueStats.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/QueueStats] - size 32.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_queue_stats_reply') - super().set_raw_dump_object(StatsReply, xid=7, - body_type=StatsTypes.OFPST_QUEUE, - flags=0, body=_get_queue_stats()) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_queue_stats_reply.dat' - -def _get_queue_stats(): - """Function used to return a QueueStats instance.""" - return QueueStats(port_no=80, queue_id=5, tx_bytes=1, - tx_packets=3, tx_errors=2) + queue = QueueStats(port_no=80, queue_id=5, tx_bytes=1, + tx_packets=3, tx_errors=2) + obj = StatsReply(xid=7, body_type=StatsTypes.OFPST_QUEUE, + flags=0, body=queue) + min_size = 12 From 5600802256f307c0da645c2cba5390bae298e284 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:26:01 -0300 Subject: [PATCH 40/53] apply new test implementation for queue stats request --- .../test_queue_stats_request.py | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_queue_stats_request.py b/tests/v0x01/test_controller2switch/test_queue_stats_request.py index b8a0bcccd..52b32810a 100644 --- a/tests/v0x01/test_controller2switch/test_queue_stats_request.py +++ b/tests/v0x01/test_controller2switch/test_queue_stats_request.py @@ -1,20 +1,15 @@ """Test for QueueStatsRequest message.""" from pyof.v0x01.controller2switch.common import QueueStatsRequest, StatsTypes from pyof.v0x01.controller2switch.stats_request import StatsRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestQueueStatsRequest(TestStruct): +class TestQueueStatsRequest(TestMsgDumpFile): """Test for QueueStatsRequest message.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/QueueStatsRequest] - size 8.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_queue_stats_request') - super().set_raw_dump_object(StatsRequest, xid=14, - body_type=StatsTypes.OFPST_QUEUE, - flags=0, - body=QueueStatsRequest(port_no=80, - queue_id=5)) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_queue_stats_request.dat' + obj = StatsRequest(xid=14, body_type=StatsTypes.OFPST_QUEUE, + flags=0, + body=QueueStatsRequest(port_no=80, + queue_id=5)) + min_size = 12 From 988d26806b6e69d60b002b29cef86bef9e37c857 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:27:02 -0300 Subject: [PATCH 41/53] apply new test implementation for set config --- .../test_controller2switch/test_set_config.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_set_config.py b/tests/v0x01/test_controller2switch/test_set_config.py index 8864e888f..8c876fb63 100644 --- a/tests/v0x01/test_controller2switch/test_set_config.py +++ b/tests/v0x01/test_controller2switch/test_set_config.py @@ -1,18 +1,13 @@ """Set Config message tests.""" from pyof.v0x01.controller2switch.common import ConfigFlags from pyof.v0x01.controller2switch.set_config import SetConfig -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestSetConfig(TestStruct): +class TestSetConfig(TestMsgDumpFile): """Test the Set Config message.""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_set_config') - super().set_raw_dump_object(SetConfig, xid=3, - flags=ConfigFlags.OFPC_FRAG_NORMAL, - miss_send_len=128) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_set_config.dat' + obj = SetConfig(xid=3, flags=ConfigFlags.OFPC_FRAG_NORMAL, + miss_send_len=128) + min_size = 12 From d1a1770e8e9b90baefa2ec20f56c498be84cab16 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:28:19 -0300 Subject: [PATCH 42/53] apply new test implementation for stats reply --- .../test_controller2switch/test_stats_reply.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_stats_reply.py b/tests/v0x01/test_controller2switch/test_stats_reply.py index ce2260a3d..616e698cf 100644 --- a/tests/v0x01/test_controller2switch/test_stats_reply.py +++ b/tests/v0x01/test_controller2switch/test_stats_reply.py @@ -1,18 +1,13 @@ """Test for StatsReply message.""" from pyof.v0x01.controller2switch.common import StatsTypes from pyof.v0x01.controller2switch.stats_reply import StatsReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestStatsReply(TestStruct): +class TestStatsReply(TestMsgDumpFile): """Test for StatsReply message.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/StatsReply] - size 12.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_stats_reply') - super().set_raw_dump_object(StatsReply, xid=1, - body_type=StatsTypes.OFPST_FLOW, - flags=0x0001, body=[]) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_stats_reply.dat' + obj = StatsReply(xid=1, body_type=StatsTypes.OFPST_FLOW, + flags=0x0001, body=[]) + min_size = 12 From 883c637436cca4b6fe8e6c80f5db18ef756577ef Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:30:31 -0300 Subject: [PATCH 43/53] apply new test implementation for stats request --- .../test_stats_request.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_stats_request.py b/tests/v0x01/test_controller2switch/test_stats_request.py index c18704c97..74ac53691 100644 --- a/tests/v0x01/test_controller2switch/test_stats_request.py +++ b/tests/v0x01/test_controller2switch/test_stats_request.py @@ -1,18 +1,13 @@ """Test for StatsRequest message.""" from pyof.v0x01.controller2switch.common import StatsTypes from pyof.v0x01.controller2switch.stats_request import StatsRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestStatsRequest(TestStruct): +class TestStatsRequest(TestMsgDumpFile): """Test for StatsRequest message.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/StatsRequest] - size 12.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_stats_request') - super().set_raw_dump_object(StatsRequest, xid=1, - body_type=StatsTypes.OFPST_FLOW, - flags=1, body=[]) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_stats_request.dat' + obj = StatsRequest(xid=1, body_type=StatsTypes.OFPST_FLOW, + flags=1, body=[]) + min_size = 12 From bc30ea410b84fa5690bb4fa224827bb4da369e4f Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:32:48 -0300 Subject: [PATCH 44/53] apply new test implementation for table stats --- .../test_table_stats.py | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/tests/v0x01/test_controller2switch/test_table_stats.py b/tests/v0x01/test_controller2switch/test_table_stats.py index 9f33d9799..a0dc2fd57 100644 --- a/tests/v0x01/test_controller2switch/test_table_stats.py +++ b/tests/v0x01/test_controller2switch/test_table_stats.py @@ -3,25 +3,19 @@ from pyof.v0x01.common.flow_match import FlowWildCards from pyof.v0x01.controller2switch.common import StatsTypes, TableStats from pyof.v0x01.controller2switch.stats_reply import StatsReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestTableStats(TestStruct): +class TestTableStats(TestMsgDumpFile): """Test class for TableStats.""" - @classmethod - def setUpClass(cls): - """[Controller2Switch/TableStats] - size 64.""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_table_stats') - super().set_raw_dump_object(StatsReply, xid=14, - body_type=StatsTypes.OFPST_TABLE, - flags=0, body=_get_table_stats()) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_table_stats.dat' - -def _get_table_stats(): - return TableStats(table_id=1, - name='X' * OFP_MAX_TABLE_NAME_LEN, - wildcards=FlowWildCards.OFPFW_TP_DST, max_entries=1, - active_count=10, count_lookup=10, count_matched=0) + table_stats = TableStats( + table_id=1, + name='X' * OFP_MAX_TABLE_NAME_LEN, + wildcards=FlowWildCards.OFPFW_TP_DST, max_entries=1, + active_count=10, count_lookup=10, count_matched=0) + obj = StatsReply(xid=14, body_type=StatsTypes.OFPST_TABLE, + flags=0, body=table_stats) + min_size = 12 From 11d7af408df7a66fe0657e9e8df9f8db47445c1d Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:34:36 -0300 Subject: [PATCH 45/53] apply new test implementation for echo reply --- tests/v0x01/test_symmetric/test_echo_reply.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/v0x01/test_symmetric/test_echo_reply.py b/tests/v0x01/test_symmetric/test_echo_reply.py index 44fde4f10..1e4db0c95 100644 --- a/tests/v0x01/test_symmetric/test_echo_reply.py +++ b/tests/v0x01/test_symmetric/test_echo_reply.py @@ -1,15 +1,11 @@ """Echo reply message tests.""" from pyof.v0x01.symmetric.echo_reply import EchoReply -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestEchoReply(TestStruct): +class TestEchoReply(TestMsgDumpFile): """Echo reply message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_echo_reply') - super().set_raw_dump_object(EchoReply, xid=0) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_echo_reply.dat' + obj = EchoReply(xid=0) + min_size = 8 From a6fe4f94f963f51f7aaac7953320e13eac37e220 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:35:35 -0300 Subject: [PATCH 46/53] apply new test implementation for echo request --- tests/v0x01/test_symmetric/test_echo_request.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/v0x01/test_symmetric/test_echo_request.py b/tests/v0x01/test_symmetric/test_echo_request.py index bea0dc204..8a5ca4601 100644 --- a/tests/v0x01/test_symmetric/test_echo_request.py +++ b/tests/v0x01/test_symmetric/test_echo_request.py @@ -1,15 +1,11 @@ """Echo request message tests.""" from pyof.v0x01.symmetric.echo_request import EchoRequest -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestEchoRequest(TestStruct): +class TestEchoRequest(TestMsgDumpFile): """Echo request message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_echo_request') - super().set_raw_dump_object(EchoRequest, xid=0) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_echo_request.dat' + obj = EchoRequest(xid=0) + min_size = 8 From 0d561527a9710c0ca3694adbfa1aef81b54f6ec3 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:36:38 -0300 Subject: [PATCH 47/53] apply new test implementation for hello --- tests/v0x01/test_symmetric/test_hello.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/v0x01/test_symmetric/test_hello.py b/tests/v0x01/test_symmetric/test_hello.py index fee44927d..60b8838be 100644 --- a/tests/v0x01/test_symmetric/test_hello.py +++ b/tests/v0x01/test_symmetric/test_hello.py @@ -1,15 +1,11 @@ """Hello message tests.""" from pyof.v0x01.symmetric.hello import Hello -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestHello(TestStruct): +class TestHello(TestMsgDumpFile): """Hello message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_hello') - super().set_raw_dump_object(Hello, xid=1) - super().set_minimum_size(8) + dumpfile = 'v0x01/ofpt_hello.dat' + obj = Hello(xid=1) + min_size = 8 From 897653b5027042bce1d8392944638b448786049d Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 14:37:56 -0300 Subject: [PATCH 48/53] apply new test implementation for vendor header --- tests/v0x01/test_symmetric/test_vendor_header.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/v0x01/test_symmetric/test_vendor_header.py b/tests/v0x01/test_symmetric/test_vendor_header.py index 6911f3e44..c1cec66b5 100644 --- a/tests/v0x01/test_symmetric/test_vendor_header.py +++ b/tests/v0x01/test_symmetric/test_vendor_header.py @@ -1,15 +1,11 @@ """Testing VendorHeader message.""" from pyof.v0x01.symmetric.vendor_header import VendorHeader -from tests.test_struct import TestStruct +from tests.test_struct import TestMsgDumpFile -class TestVendorHeader(TestStruct): +class TestVendorHeader(TestMsgDumpFile): """Vendor message tests (also those in :class:`.TestDump`).""" - @classmethod - def setUpClass(cls): - """Configure raw file and its object in parent class (TestDump).""" - super().setUpClass() - super().set_raw_dump_file('v0x01', 'ofpt_vendor_header') - super().set_raw_dump_object(VendorHeader, xid=4, vendor=128) - super().set_minimum_size(12) + dumpfile = 'v0x01/ofpt_vendor_header.dat' + obj = VendorHeader(xid=4, vendor=128) + min_size = 12 From 062e4814a9f13182757159ee462ba29f0ee07e5c Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Tue, 11 Jul 2017 17:56:50 -0300 Subject: [PATCH 49/53] test port status isort --- tests/v0x01/test_asynchronous/test_port_status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/v0x01/test_asynchronous/test_port_status.py b/tests/v0x01/test_asynchronous/test_port_status.py index 8cb4ce520..4c3ba1920 100644 --- a/tests/v0x01/test_asynchronous/test_port_status.py +++ b/tests/v0x01/test_asynchronous/test_port_status.py @@ -4,7 +4,7 @@ from pyof.v0x01.asynchronous.port_status import PortReason, PortStatus from pyof.v0x01.common.phy_port import ( PhyPort, PortConfig, PortFeatures, PortState) -from tests.test_struct import TestMsgDumpFile, TestMsgDump +from tests.test_struct import TestMsgDump, TestMsgDumpFile class TestPortStatus_1(TestMsgDumpFile): From f3c69ae33581ed671b2ec454bdc3eed467d203cb Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Thu, 13 Jul 2017 11:18:22 -0300 Subject: [PATCH 50/53] Requested changes on tests names, line breaks and such. --- tests/test_foundation/test_basic_types.py | 28 +++++++++---------- .../v0x01/test_asynchronous/test_error_msg.py | 4 +-- .../test_asynchronous/test_port_status.py | 4 +-- tests/v0x01/test_common/test_action.py | 6 ++-- tests/v0x01/test_common/test_flow_match.py | 2 +- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/tests/test_foundation/test_basic_types.py b/tests/test_foundation/test_basic_types.py index 725a4af40..462733274 100644 --- a/tests/test_foundation/test_basic_types.py +++ b/tests/test_foundation/test_basic_types.py @@ -6,23 +6,23 @@ from tests.test_struct import TestStructDump -class TestUBInt8_(unittest.TestCase): +class TestUBInt8(TestStructDump): """Test UBInt8.""" dump = b'\xff' - obj = basic_types.UBInt32(2**8 - 1) + obj = basic_types.UBInt8(2**8 - 1) min_size = 1 -class TestUBInt16_(unittest.TestCase): +class TestUBInt16(TestStructDump): """Test UBInt16.""" dump = b'\xff\xff' - obj = basic_types.UBInt32(2**16 - 1) + obj = basic_types.UBInt16(2**16 - 1) min_size = 2 -class TestUBInt32_(unittest.TestCase): +class TestUBInt32(TestStructDump): """Test UBInt32.""" dump = b'\xff\xff\xff\xff' @@ -30,28 +30,28 @@ class TestUBInt32_(unittest.TestCase): min_size = 4 -class TestChar_3(unittest.TestCase): +class TestChar3(TestStructDump): """Test Char with length 3.""" dump = b'fo\x00' obj = basic_types.Char('foo', length=3) -class TestChar_5(unittest.TestCase): +class TestChar5(TestStructDump): """Test Char with length 5.""" dump = b'foo\x00\x00' obj = basic_types.Char('foo', length=5) -class TestHWAddress_default(TestStructDump): +class TestHWAddressDefault(TestStructDump): """Test HWAddress default value.""" dump = b'\x00\x00\x00\x00\x00\x00' obj = basic_types.HWAddress() -class TestHWAddress_mac(TestStructDump): +class TestHWAddressMac(TestStructDump): """Test HWAddress mac value.""" mac = '00:00:00:00:00:00' @@ -63,7 +63,7 @@ def test_address_value(self): self.assertEqual(self.obj.value, self.mac) -class TestHWAddress_random(TestHWAddress_mac): +class TestHWAddressRandom(TestHWAddressMac): """Test HWAddress mac value 0a:d3:98:a5:30:47.""" mac = '0a:d3:98:a5:30:47' @@ -71,7 +71,7 @@ class TestHWAddress_random(TestHWAddress_mac): obj = basic_types.HWAddress(mac) -class TestIPAddress_netmask(TestStructDump): +class TestIPAddressNetmask(TestStructDump): """Test IPAddress and its default netmask value.""" dump = b'\xc0\xa8\x00\x01' @@ -83,7 +83,7 @@ def test_netmask(self): self.assertEqual(self.obj.netmask, self.netmask) -class TestIPAddress_nonetmask(TestIPAddress_netmask): +class TestIPAddressNoNetmask(TestIPAddressNetmask): """Test IPAdress and netmask value 16.""" dump = b'\xc0\xa8\x00\x01' @@ -91,7 +91,7 @@ class TestIPAddress_nonetmask(TestIPAddress_netmask): netmask = 16 -class TestBinaryData_empty(TestStructDump): +class TestBinaryDataEmpty(TestStructDump): """Test empty BinaryData.""" dump = b'' @@ -99,7 +99,7 @@ class TestBinaryData_empty(TestStructDump): min_size = 0 -class TestBinaryData_bytes(TestStructDump): +class TestBinaryDataBytes(TestStructDump): """Test 'bytes' BinaryData.""" dump = b'bytes' diff --git a/tests/v0x01/test_asynchronous/test_error_msg.py b/tests/v0x01/test_asynchronous/test_error_msg.py index 958a4770c..4906b7a24 100644 --- a/tests/v0x01/test_asynchronous/test_error_msg.py +++ b/tests/v0x01/test_asynchronous/test_error_msg.py @@ -4,7 +4,7 @@ from tests.test_struct import TestMsgDump, TestMsgDumpFile -class TestErrorMessage_fromfile(TestMsgDumpFile): +class TestErrorMessageFromFile(TestMsgDumpFile): """Test the ErrorMsg class.""" dumpfile = 'v0x01/ofpt_error_msg.dat' @@ -15,7 +15,7 @@ class TestErrorMessage_fromfile(TestMsgDumpFile): min_size = 12 -class TestErrorMessage_dump(TestMsgDump): +class TestErrorMessageDump(TestMsgDump): """Test the ErrorMsg class.""" # dump needs to be checked diff --git a/tests/v0x01/test_asynchronous/test_port_status.py b/tests/v0x01/test_asynchronous/test_port_status.py index 4c3ba1920..585de1762 100644 --- a/tests/v0x01/test_asynchronous/test_port_status.py +++ b/tests/v0x01/test_asynchronous/test_port_status.py @@ -7,7 +7,7 @@ from tests.test_struct import TestMsgDump, TestMsgDumpFile -class TestPortStatus_1(TestMsgDumpFile): +class TestPortStatus1(TestMsgDumpFile): """Test the PortStatus class.""" dumpfile = 'v0x01/ofpt_port_status.dat' @@ -27,7 +27,7 @@ class TestPortStatus_1(TestMsgDumpFile): desc=desc) -class TestPortStatus_2(TestMsgDump): +class TestPortStatus2(TestMsgDump): """Test the PortStatus class.""" dump = b'\x01\x0c\x00@\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00' diff --git a/tests/v0x01/test_common/test_action.py b/tests/v0x01/test_common/test_action.py index fb85a4b8b..a91bb9590 100644 --- a/tests/v0x01/test_common/test_action.py +++ b/tests/v0x01/test_common/test_action.py @@ -10,8 +10,7 @@ class TestActionOutput(TestMsgDumpFile): """ActionOutput message tests (also those in :class:`.TestDump`).""" dumpfile = 'v0x01/ofpt_action_output.dat' - obj = ActionOutput(port=Port.OFPP_CONTROLLER, - max_length=8) + obj = ActionOutput(port=Port.OFPP_CONTROLLER, max_length=8) min_size = 8 @@ -19,8 +18,7 @@ class TestActionEnqueue(TestMsgDumpFile): """ActionEnqueue message tests (also those in :class:`.TestDump`).""" dumpfile = 'v0x01/ofpt_action_enqueue.dat' - obj = ActionEnqueue(port=Port.OFPP_CONTROLLER, - queue_id=4) + obj = ActionEnqueue(port=Port.OFPP_CONTROLLER, queue_id=4) min_size = 16 diff --git a/tests/v0x01/test_common/test_flow_match.py b/tests/v0x01/test_common/test_flow_match.py index 95704e706..5d43dc6cf 100644 --- a/tests/v0x01/test_common/test_flow_match.py +++ b/tests/v0x01/test_common/test_flow_match.py @@ -24,7 +24,7 @@ class TestMatch(TestStructDump): tp_dst=22) -class TestMatch_2(TestStructDump): +class TestMatch2(TestStructDump): """Test Match structure.""" dump = b'\x00\x0f\xff\x0c\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' From d294d46e7b48c81ea24fd246052d0a3be134c182 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Thu, 13 Jul 2017 11:40:22 -0300 Subject: [PATCH 51/53] include dump object in TestStructDump docstring --- tests/test_struct.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_struct.py b/tests/test_struct.py index cee396d7f..d5c824c6b 100644 --- a/tests/test_struct.py +++ b/tests/test_struct.py @@ -180,10 +180,12 @@ class TestStructDump(unittest.TestCase): Example: .. code-block:: python3 - class TestMatch(TestStructDump): - dump = b'' # needs to be filled - obj = pyof.v0x01.common.flow_match.Match(xid=0) - min_size = 8 + from pyof.v0x01.foundation.basic_type import BinaryData + + class TestBinaryData(TestStructDump): + dump = b'data' + obj = BinaryData(xid=0) + min_size = 0 """ dump = b'' From f2a02e5e10bd4e69fb48282b41413fd2a5ed15b6 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Fri, 14 Jul 2017 11:44:20 -0300 Subject: [PATCH 52/53] make type(Char(length))(value) return new class but with same length --- pyof/foundation/basic_types.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/pyof/foundation/basic_types.py b/pyof/foundation/basic_types.py index 451b46f2f..fa9688e7c 100644 --- a/pyof/foundation/basic_types.py +++ b/pyof/foundation/basic_types.py @@ -171,19 +171,8 @@ def unpack(self, buff, offset=0): self._value = ':'.join(hexas) -class Char(GenericType): - """Build a double char type according to the length.""" - - def __init__(self, value=None, length=0): - """The constructor takes the optional parameters below. - - Args: - value: The character to be build. - length (int): Character size. - """ - super().__init__(value) - self.length = length - self._fmt = '!{}{}'.format(self.length, 's') +class CharStringBase(GenericType): + """A null terminated ascii char string.""" def pack(self, value=None): """Pack the value as a binary representation. @@ -231,6 +220,19 @@ def unpack(self, buff, offset=0): self._value = unpacked_data.decode('ascii').rstrip('\0') +def Char(value=None, length=0): + """Return a CharString class with given length and initial value.""" + string_length = length + + class CharString(CharStringBase): + """Class for null terminated ascii strings of fixed length.""" + + length = string_length + _fmt = '!{}{}'.format(length, 's') + + return CharString(value) + + class IPAddress(GenericType): """Defines a IP address.""" From 089b921b2b387be5a0c853c09698e49dc053949f Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Fri, 14 Jul 2017 12:43:22 -0300 Subject: [PATCH 53/53] Include min_size tests for a few basic_types --- tests/test_foundation/test_basic_types.py | 25 ++++++++--------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/tests/test_foundation/test_basic_types.py b/tests/test_foundation/test_basic_types.py index 462733274..07a877e0a 100644 --- a/tests/test_foundation/test_basic_types.py +++ b/tests/test_foundation/test_basic_types.py @@ -35,6 +35,7 @@ class TestChar3(TestStructDump): dump = b'fo\x00' obj = basic_types.Char('foo', length=3) + min_size = 3 class TestChar5(TestStructDump): @@ -42,41 +43,29 @@ class TestChar5(TestStructDump): dump = b'foo\x00\x00' obj = basic_types.Char('foo', length=5) - - -class TestHWAddressDefault(TestStructDump): - """Test HWAddress default value.""" - - dump = b'\x00\x00\x00\x00\x00\x00' - obj = basic_types.HWAddress() + min_size = 5 class TestHWAddressMac(TestStructDump): """Test HWAddress mac value.""" - mac = '00:00:00:00:00:00' - dump = b'\x00\x00\x00\x00\x00\x00' + mac = '0a:d3:98:a5:30:47' + dump = b'\x0a\xd3\x98\xa5\x30\x47' obj = basic_types.HWAddress(mac) + min_size = 6 def test_address_value(self): """Test HWAddress mac value.""" self.assertEqual(self.obj.value, self.mac) -class TestHWAddressRandom(TestHWAddressMac): - """Test HWAddress mac value 0a:d3:98:a5:30:47.""" - - mac = '0a:d3:98:a5:30:47' - dump = b'\x0a\xd3\x98\xa5\x30\x47' - obj = basic_types.HWAddress(mac) - - class TestIPAddressNetmask(TestStructDump): """Test IPAddress and its default netmask value.""" dump = b'\xc0\xa8\x00\x01' obj = basic_types.IPAddress('192.168.0.1') netmask = 32 + min_size = 4 def test_netmask(self): """Test IPAddress netmask value.""" @@ -89,6 +78,7 @@ class TestIPAddressNoNetmask(TestIPAddressNetmask): dump = b'\xc0\xa8\x00\x01' obj = basic_types.IPAddress('192.168.0.1/16') netmask = 16 + min_size = 4 class TestBinaryDataEmpty(TestStructDump): @@ -104,6 +94,7 @@ class TestBinaryDataBytes(TestStructDump): dump = b'bytes' obj = BinaryData(b'bytes') + min_size = 0 class TestIPAddress(unittest.TestCase):