Skip to content

Commit

Permalink
Use verifier for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jpsamaroo committed Oct 28, 2020
1 parent c5170aa commit eed1861
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 0 deletions.
67 changes: 67 additions & 0 deletions test_framework/test_verifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import os
import tempfile
import struct
from subprocess import Popen, PIPE
from nose.plugins.skip import Skip, SkipTest
import ubpf.assembler
import testdata
VM = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "vm", "test")

def check_datafile(filename):
"""
Given assembly source code and an expected result, run the eBPF program and
verify that the result matches.
"""
data = testdata.read(filename)
if 'asm' not in data and 'raw' not in data:
raise SkipTest("no asm or raw section in datafile")
if 'result' not in data and 'verifier error' not in data:
raise SkipTest("no result or verifier error section in datafile")
if 'error' in data or 'error pattern' in data:
raise SkipTest("non-verifier error section in datafile")
if not os.path.exists(VM):
raise SkipTest("VM not found")

if 'raw' in data:
code = b''.join(struct.pack("=Q", x) for x in data['raw'])
else:
code = ubpf.assembler.assemble(data['asm'])

memfile = None

cmd = [VM]
if 'mem' in data:
memfile = tempfile.NamedTemporaryFile()
memfile.write(data['mem'])
memfile.flush()
cmd.extend(['-m', memfile.name])

cmd.extend(['-V', '-'])

vm = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)

stdout, stderr = vm.communicate(code)
stdout = stdout.decode("utf-8")
stderr = stderr.decode("utf-8")
stderr = stderr.strip()

if memfile:
memfile.close()

if 'verifier error' in data:
if data['verifier error'] + '\nFailed verification' != stderr:
raise AssertionError("Expected error %r, got %r" % (data['verifier error'] + '\nFailed verification', stderr))
if vm.returncode == 0:
raise AssertionError("Expected VM to exit with an error code")
elif 'error' in data or 'error-pattern' in data:
if vm.returncode == 0:
raise AssertionError("Expected VM to exit with an error code")
else:
if vm.returncode != 0:
raise AssertionError("VM exited with status %d, stderr=%r" % (vm.returncode, stderr))

def test_datafiles():
# Nose test generator
# Creates a testcase for each datafile
for filename in testdata.list_files():
yield check_datafile, filename
3 changes: 3 additions & 0 deletions tests/early-exit.data
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ mov r0, 4
exit
-- result
0x3
-- verifier error
Dead instruction at offset 2
Dead instruction at offset 3
2 changes: 2 additions & 0 deletions tests/mul-loop.data
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ jne r1, 0x0, -3
exit
-- result
0x75db9c97
-- verifier error
Loop detected at offset 8
2 changes: 2 additions & 0 deletions tests/prime.data
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ jne r4, 0x0, -10
exit
-- result
0x1
-- verifier error
Loop detected at offset 14
2 changes: 2 additions & 0 deletions tests/tcp-sack/match.data
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
-- mem @ pkt-sack.hex
-- result
0x1
-- verifier error
Loop detected at offset 40
2 changes: 2 additions & 0 deletions tests/tcp-sack/nomatch.data
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
-- mem @ pkt-nosack.hex
-- result
0x0
-- verifier error
Loop detected at offset 40

0 comments on commit eed1861

Please sign in to comment.