1#!/usr/bin/env python3 2# encoding: utf-8 3 4import os 5import sys 6import shlex 7import argparse 8from subprocess import Popen, PIPE 9 10keywords = ("iptables-translate", "ip6tables-translate", "ebtables-translate") 11xtables_nft_multi = 'xtables-nft-multi' 12 13if sys.stdout.isatty(): 14 colors = {"magenta": "\033[95m", "green": "\033[92m", "yellow": "\033[93m", 15 "red": "\033[91m", "end": "\033[0m"} 16else: 17 colors = {"magenta": "", "green": "", "yellow": "", "red": "", "end": ""} 18 19 20def magenta(string): 21 return colors["magenta"] + string + colors["end"] 22 23 24def red(string): 25 return colors["red"] + string + colors["end"] 26 27 28def yellow(string): 29 return colors["yellow"] + string + colors["end"] 30 31 32def green(string): 33 return colors["green"] + string + colors["end"] 34 35 36def run_test(name, payload): 37 global xtables_nft_multi 38 test_passed = True 39 tests = passed = failed = errors = 0 40 result = [] 41 42 for line in payload: 43 if line.startswith(keywords): 44 tests += 1 45 process = Popen([ xtables_nft_multi ] + shlex.split(line), stdout=PIPE, stderr=PIPE) 46 (output, error) = process.communicate() 47 if process.returncode == 0: 48 translation = output.decode("utf-8").rstrip(" \n") 49 expected = next(payload).rstrip(" \n") 50 if translation != expected: 51 test_passed = False 52 failed += 1 53 result.append(name + ": " + red("Fail")) 54 result.append(magenta("src: ") + line.rstrip(" \n")) 55 result.append(magenta("exp: ") + expected) 56 result.append(magenta("res: ") + translation + "\n") 57 test_passed = False 58 else: 59 passed += 1 60 else: 61 test_passed = False 62 errors += 1 63 result.append(name + ": " + red("Error: ") + "iptables-translate failure") 64 result.append(error.decode("utf-8")) 65 if (passed == tests) and not args.test: 66 print(name + ": " + green("OK")) 67 if not test_passed: 68 print("\n".join(result)) 69 if args.test: 70 print("1 test file, %d tests, %d tests passed, %d tests failed, %d errors" % (tests, passed, failed, errors)) 71 else: 72 return tests, passed, failed, errors 73 74 75def load_test_files(): 76 test_files = total_tests = total_passed = total_error = total_failed = 0 77 for test in sorted(os.listdir("extensions")): 78 if test.endswith(".txlate"): 79 with open("extensions/" + test, "r") as payload: 80 tests, passed, failed, errors = run_test(test, payload) 81 test_files += 1 82 total_tests += tests 83 total_passed += passed 84 total_failed += failed 85 total_error += errors 86 87 88 print("%d test files, %d tests, %d tests passed, %d tests failed, %d errors" % (test_files, total_tests, total_passed, total_failed, total_error)) 89 90def main(): 91 global xtables_nft_multi 92 if not args.host: 93 os.putenv("XTABLES_LIBDIR", os.path.abspath("extensions")) 94 xtables_nft_multi = os.path.abspath(os.path.curdir) \ 95 + '/iptables/' + xtables_nft_multi 96 97 if args.test: 98 if not args.test.endswith(".txlate"): 99 args.test += ".txlate" 100 try: 101 with open(args.test, "r") as payload: 102 run_test(args.test, payload) 103 except IOError: 104 print(red("Error: ") + "test file does not exist") 105 else: 106 load_test_files() 107 108 109parser = argparse.ArgumentParser() 110parser.add_argument('-H', '--host', action='store_true', 111 help='Run tests against installed binaries') 112parser.add_argument("test", nargs="?", help="run only the specified test file") 113args = parser.parse_args() 114main() 115