1#!/usr/bin/env python 2 3# Copyright (c) Barefoot Networks, Inc. 4# Licensed under the Apache License, Version 2.0 (the "License") 5 6# Runs the compiler on all files in the 'testprograms' folder 7# Writes outputs in the 'testoutputs' folder 8 9from __future__ import print_function 10from bcc import BPF 11import os, sys 12sys.path.append("../compiler") # To get hold of p4toEbpf 13 # We want to run it without installing it 14import p4toEbpf 15import os 16 17def drop_extension(filename): 18 return os.path.splitext(os.path.basename(filename))[0] 19 20filesFailed = {} # map error kind -> list[ (file, error) ] 21 22def set_error(kind, file, error): 23 if kind in filesFailed: 24 filesFailed[kind].append((file, error)) 25 else: 26 filesFailed[kind] = [(file, error)] 27 28def is_root(): 29 # Is this code portable? 30 return os.getuid() == 0 31 32def main(): 33 testpath = "testprograms" 34 destFolder = "testoutputs" 35 files = os.listdir(testpath) 36 files.sort() 37 filesDone = 0 38 errors = 0 39 40 if not is_root(): 41 print("Loading EBPF programs requires root privilege.") 42 print("Will only test compilation, not loading.") 43 print("(Run with sudo to test program loading.)") 44 45 for f in files: 46 path = os.path.join(testpath, f) 47 48 if not os.path.isfile(path): 49 continue 50 if not path.endswith(".p4"): 51 continue 52 53 destname = drop_extension(path) + ".c" 54 destname = os.path.join(destFolder, destname) 55 56 args = [path, "-o", destname] 57 58 result = p4toEbpf.process(args) 59 if result.kind != "OK": 60 errors += 1 61 print(path, result.error) 62 set_error(result.kind, path, result.error) 63 else: 64 # Try to load the compiled function 65 if is_root(): 66 try: 67 print("Compiling and loading BPF program") 68 b = BPF(src_file=destname, debug=0) 69 fn = b.load_func("ebpf_filter", BPF.SCHED_CLS) 70 except Exception as e: 71 print(e) 72 set_error("BPF error", path, str(e)) 73 74 filesDone += 1 75 76 print("Compiled", filesDone, "files", errors, "errors") 77 for key in sorted(filesFailed): 78 print(key, ":", len(filesFailed[key]), "programs") 79 for v in filesFailed[key]: 80 print("\t", v) 81 exit(len(filesFailed) != 0) 82 83 84if __name__ == "__main__": 85 main() 86