Regression: test for Scapy offsets:
authorYaroslav Brustinov <[email protected]>
Thu, 16 Mar 2017 11:59:27 +0000 (13:59 +0200)
committerYaroslav Brustinov <[email protected]>
Thu, 16 Mar 2017 11:59:27 +0000 (13:59 +0200)
* build / no build
* pcap buffer / native Scapy

Change-Id: Ifa0bc8bf51bced71ea320d3f75ba456242be4451
Signed-off-by: Yaroslav Brustinov <[email protected]>
scripts/automation/regression/functional_tests/scapy_isolated_test.py [new file with mode: 0755]
scripts/external_libs/scapy-2.3.1/python3/scapy/packet.py

diff --git a/scripts/automation/regression/functional_tests/scapy_isolated_test.py b/scripts/automation/regression/functional_tests/scapy_isolated_test.py
new file mode 100755 (executable)
index 0000000..5114f65
--- /dev/null
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+import sys, os
+from multiprocessing import Process
+import tempfile
+
+def check_offsets(build, stdout, scapy_str = None, pcap = None):
+    import sys
+    sys.stdout = stdout
+    sys.stderr = stdout
+
+    # clean this env
+    for key in sys.modules.copy().keys():
+        if key.startswith('scapy.'):
+            del sys.modules[key]
+    globals().clear()
+
+    import os
+    import outer_packages
+    from scapy.all import Ether, IP, UDP
+
+    if scapy_str:
+        pkt = eval(scapy_str)
+    elif pcap:
+        from scapy.utils import rdpcap
+        pkt = rdpcap(pcap)[0]
+    else:
+        raise Exception('Please specify scapy_str or pcap.')
+
+    if build:
+        pkt.build()
+
+    assert pkt
+    assert pkt.payload
+
+    lay = pkt
+    while lay:
+        print('  ### %s (offset %s)' % (lay.name, lay._offset))
+        lay.dump_fields_offsets()
+        if lay == pkt:
+            assert lay._offset == 0, 'Offset of first layer should be zero.'
+        else:
+            if build:
+                assert lay._offset != 0, 'Offset of second and further layers should not be zero if packets is built.'
+            else:
+                assert lay._offset == 0, 'Offset of second and further layers should be zero if packets is not built.'
+        for index, field in enumerate(lay.fields_desc):
+            if index == 0:
+                assert field._offset == 0, 'Offset of first field should be zero.'
+            else:
+                if build:
+                    if field.get_size_bytes() == 0:
+                        continue
+                    assert field._offset != 0, 'Offset of second and further fields should not be zero if packets is built.'
+                else:
+                    assert field._offset == 0, 'Offset of second and further fields should be zero if packets is not built.'
+
+        lay = lay.payload
+
+
+def isolate_env(f, *a, **k):
+    with tempfile.TemporaryFile(mode = 'w+') as tmpfile:
+        k.update({'stdout': tmpfile})
+        p = Process(target = f, args = a, kwargs = k)
+        p.start()
+        p.join()
+        print('')
+        tmpfile.seek(0)
+        print(tmpfile.read())
+    if p.exitcode:
+        raise Exception('Return status not zero, check the output')
+
+class CScapyOffsets_Test():
+    def setUp(self):
+        self.dir = os.path.abspath(os.path.dirname(__file__)) + '/'
+
+    def test_offsets_udp_build(self):
+        isolate_env(check_offsets, scapy_str = "Ether()/IP()/UDP()/('x'*9)", build = True)
+
+    def test_offsets_udp_nobuild(self):
+        isolate_env(check_offsets, scapy_str = "Ether()/IP()/UDP()/('x'*9)", build = False)
+
+    def test_offsets_pcap_build(self):
+        isolate_env(check_offsets, pcap = self.dir + 'golden/bp_sim_dns_vlans.pcap', build = True)
+
+    def test_offsets_pcap_nobuild(self):
+        isolate_env(check_offsets, pcap = self.dir + 'golden/bp_sim_dns_vlans.pcap', build = False)
+
index 8401e0c..036e0ef 100644 (file)
@@ -327,7 +327,7 @@ class Packet(BasePacket, metaclass = Packet_metaclass):
     def __rmul__(self,other):
         return self.__mul__(other)
     
-    def __nonzero__(self):
+    def __bool__(self):
         return True
 
     def __len__(self):
@@ -1149,7 +1149,7 @@ class NoPayload(Packet):
         return ""
     def __str__(self):
         return ""
-    def __nonzero__(self):
+    def __bool__(self):
         return False
     def do_build(self,result):
         return b""