def DHCP_test(trigger_line): global num_assigned_clients num_assigned_clients += 1 print(color.INFO("<Test.py>"), "Client got IP") ip_string = vm.readline() print(color.INFO("<Test.py>"), "Assigned address: ", ip_string) print(color.INFO("<Test.py>"), "Trying to ping") time.sleep(1) try: command = [ "ping", "-c", str(ping_count), "-i", "0.2", ip_string.rstrip() ] print(color.DATA(" ".join(command))) print(subprocess.check_output(command, timeout=thread_timeout)) print(color.INFO("<Test.py>"), "Number of ping tests passed: ", str(num_assigned_clients)) if num_assigned_clients == 3: vm.exit( 0, "<Test.py> Ping test for all 3 clients passed. Process returned 0 exit status" ) except Exception as e: print(color.FAIL("<Test.py> Ping FAILED Process threw exception:")) print(e) return False
def main(): # Find leaf nodes leaves = find_test_folders() # Populate test objects all_tests = [ Test(path, args.clean) for path in leaves ] # Check if clean-only is issued if args.clean_only: for test in all_tests: test.clean_test() sys.exit(0) # get a list of all the tests that are to be run filtered_tests = filter_tests(all_tests, args) # Run the tests integration = integration_tests(filtered_tests) if args.tests: types_to_run = args.tests else: types_to_run = test_types stress = stress_test() if "stress" in types_to_run else 0 misc = misc_working() if "misc" in types_to_run else 0 status = max(integration, stress, misc) if (status == 0): print pretty.SUCCESS(str(test_count - status) + " / " + str(test_count) + " tests passed, exiting with code 0") else: print pretty.FAIL(str(status) + " / " + str(test_count) + " tests failed ") sys.exit(status)
def start_icmp_test(trigger_line): global num_successes # 1 Ping: Checking output from callback in service.cpp print(color.INFO("<Test.py>"), "Performing ping6 test") output_data = "" for x in range(0, 9): output_data += vm.readline() print(output_data) if "Received packet from gateway" in output_data and \ "Identifier: 0" in output_data and \ "Sequence number: 0" in output_data and \ "Source: fe80:0:0:0:e823:fcff:fef4:83e7" in output_data and \ "Destination: fe80:0:0:0:e823:fcff:fef4:85bd" in output_data and \ "Type: ECHO REPLY (129)" in output_data and \ "Code: DEFAULT (0)" in output_data and \ "Checksum: " in output_data and \ "Data: INCLUDEOS12345ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678" in output_data: num_successes += 1 print(color.INFO("<Test.py>"), "Ping test succeeded") else: print(color.FAIL("<Test.py>"), "Ping test FAILED") vm.exit(1, "Ping test failed") if num_successes == 1: vm.exit( 0, "<Test.py> All ICMP tests succeeded. Process returned 0 exit status" )
def main(): # Find leaf nodes leaves = find_test_folders() # Populate test objects all_tests = [ Test(path, args.clean) for path in leaves ] # Check if clean-only is issued if args.clean_only: for test in all_tests: test.clean_test() sys.exit(0) # get a list of all the tests that are to be run filtered_tests, skipped_tests = filter_tests(all_tests, args) # Run the tests integration_result = integration_tests([x for x in filtered_tests if x.type_ == "integration"]) stress_result = stress_test([x for x in filtered_tests if x.type_ == "stress"]) misc_result = misc_working([x for x in filtered_tests if x.type_ == "misc"], "misc") linux_result = misc_working([x for x in filtered_tests if x.type_ == "linux"], "linux platform") # Print status from test run status = max(integration_result, stress_result, misc_result, linux_result) if (status == 0): print pretty.SUCCESS(str(test_count - status) + " / " + str(test_count) + " tests passed, exiting with code 0") else: print pretty.FAIL(str(status) + " / " + str(test_count) + " tests failed ") # Create Junit output if args.junit: create_junit_output(filtered_tests + skipped_tests) sys.exit(status)
def run_dhclient(trigger_line): route_output = subprocess.check_output(["route"]) if "10.0.0.0" not in route_output: subprocess32.call([ "sudo", "ifconfig", "bridge43", "10.0.0.1", "netmask", "255.255.0.0", "up" ], timeout=thread_timeout) time.sleep(1) if "10.200.0.0" not in route_output: subprocess32.call([ "sudo", "route", "add", "-net", "10.200.0.0", "netmask", "255.255.0.0", "dev", "bridge43" ], timeout=thread_timeout) print color.INFO("<Test.py>"), "Route added to bridge43, 10.200.0.0" print color.INFO("<Test.py>"), "Running dhclient" try: dhclient = subprocess32.Popen( ["sudo", "dhclient", "bridge43", "-4", "-n", "-v"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, timeout=thread_timeout) # timeout on dhclient process kill_proc = lambda p: p.kill() timer = Timer(20, kill_proc, [dhclient]) timer.start() process_output, _ = dhclient.communicate() print color.INFO("<dhclient>") print process_output check_dhclient_output(process_output) except (OSError, subprocess.CalledProcessError) as exception: cleanup() print color.FAIL("<Test.py> dhclient FAILED threw exception:") print str(exception) timer.cancel() vm.exit(1, "<Test.py> dhclient test failed") finally: timer.cancel() ping_test() if ping_passed and num_messages == 4: vm.exit( 0, "<Test.py> DHCP process and ping test completed successfully. Process returned 0 exit status" ) else: vm.exit(1, "<Test.py> DHCP process or ping test failed")
def crash_test(string): print(color.INFO("Opening persistent TCP connection for diagnostics")) sock_mem.connect((HOST, PORT_MEM)) mem_before = get_mem_start() if mem_before <= 0: print(color.FAIL("Initial memory reported as " + str(mem_before))) return False if not heap_verified: print(color.FAIL("Heap behavior was not verified as expected. ")) return False print(color.HEADER("Initial crash test")) burst_size = BURST_SIZE * 10 ARP_burst(burst_size, 0) UDP_burst(burst_size, 0) ICMP_flood(burst_size, 0) httperf(burst_size, 0) time.sleep(BURST_INTERVAL) mem_after = get_mem() print(color.INFO("Crash test complete. Memory in use: "), mem_after) return mem_after >= memuse_at_start
def get_mem(): name_tag = "<" + test_name + "::get_mem>" try: # We expect this socket to allready be opened time.sleep(1) sock_mem.send("memsize\n") received = sock_mem.recv(1000).rstrip() except Exception as e: print color.FAIL(name_tag), "Python socket failed while getting memsize: ", e return False print color.INFO(name_tag),"Current VM memory usage reported as ", received return int(received)
def DHCP_test(trigger_line): print color.INFO("<Test.py>"),"Got IP" ip_string = vm.readline() print color.INFO("<Test.py>"), "Assigned address: ", ip_string print color.INFO("<Test.py>"), "Trying to ping" time.sleep(1) try: command = ["ping", ip_string.rstrip(), "-c", str(ping_count), "-i", "0.2"] print color.DATA(" ".join(command)) print subprocess32.check_output(command, timeout=thread_timeout) vm.exit(0,"<Test.py> Ping test passed. Process returned 0 exit status") except Exception as e: print color.FAIL("<Test.py> Ping FAILED Process threw exception:") print e return False
def fire_bursts(func, sub_test_name, lead_out=3): name_tag = "<" + sub_test_name + ">" print color.HEADER(test_name + " initiating " + sub_test_name) membase_start = func() mem_base = membase_start # Track heap behavior increases = 0 decreases = 0 constant = 0 for i in range(0, BURST_COUNT): print color.INFO(name_tag), " Run ", i + 1 memi = func() if memi > mem_base: memincrease = memi - mem_base increases += 1 elif memi == mem_base: memincrease = 0 constant += 1 else: memincrease = 0 decreases += 1 # We want to know how much each burst increases memory relative to the last burst mem_base = memi if memincrease > acceptable_increase: print color.WARNING( name_tag), "Memory increased by ", memincrease, "b, ", float( memincrease) / BURST_SIZE, "pr. packet \n" else: print color.OK(name_tag), "Memory increase ", memincrease, "b \n" # Memory can decrease, we don't care about that # if memincrease > 0: # mem_base += memincrease print color.INFO( name_tag ), "Heap behavior: ", "+", increases, ", -", decreases, ", ==", constant print color.INFO(name_tag), "Done. Checking for liveliness" if memory_increase(lead_out, membase_start) > acceptable_increase: print color.FAIL(sub_test_name + " failed ") return False print color.PASS(sub_test_name + " succeeded ") return True
def ping_test(): global ping_passed print color.INFO("<Test.py>"), "Assigned address: ", assigned_ip print color.INFO("<Test.py>"), "Trying to ping" time.sleep(1) try: command = ["ping", assigned_ip, "-c", str(ping_count), "-i", "0.2"] print color.DATA(" ".join(command)) print subprocess.check_output(command) ping_passed = True except Exception as e: print color.FAIL("<Test.py> Ping FAILED Process threw exception:") print e cleanup() vm.exit(1, "<Test.py> Ping test failed") finally: cleanup()
def stress_test(): """Perform stresstest""" global test_count test_count += 1 if ("stress" in args.skip): print pretty.WARNING("Stress test skipped") return 0 if (not validate_tests.validate_test("stress")): raise Exception("Stress test failed validation") print pretty.HEADER("Starting stress test") stress = Test("stress", clean = args.clean).start() if (stress and args.fail): print pretty.FAIL("Stress test failed") sys.exit(stress) return 1 if stress.wait_status() else 0
def Slaac_test(trigger_line): print(color.INFO("<Test.py>"), "Got IP") vm_string = vm.readline() wlist = vm_string.split() ip_string = wlist[-1].split("/")[0] print(color.INFO("<Test.py>"), "Assigned address: ", ip_string) print(color.INFO("<Test.py>"), "Trying to ping") time.sleep(1) try: command = [ "ping6", "-I", "bridge43", ip_string.rstrip(), "-c", str(ping_count) ] print(color.DATA(" ".join(command))) print(subprocess.check_output(command)) vm.exit(0, "<Test.py> Ping test passed. Process returned 0 exit status") except Exception as e: print(color.FAIL("<Test.py> Ping FAILED Process threw exception:")) print(e) return False
def run_dhclient(trigger_line): route_output = subprocess.check_output(["route"]).decode("utf-8") if "10.0.0.0" not in route_output: subprocess.call(["sudo", "ip", "link", "set", "dev", "bridge43", "up"], timeout=thread_timeout) time.sleep(1) if "10.200.0.0" not in route_output: subprocess.call(["sudo", "ip", "route", "add", "10.200.0.0/16", "dev", "bridge43"], timeout=thread_timeout) print(color.INFO("<Test.py>"), "Route added to bridge43, 10.200.0.0") print(color.INFO("<Test.py>"), "Running dhclient") try: dhclient = subprocess.check_output( ["sudo", "dhclient", "bridge43", "-4", "-n", "-v"], stderr=subprocess.STDOUT, timeout=thread_timeout ) print(color.INFO("<dhclient>")) print(dhclient) # gets ip of dhclient used to ping check_dhclient_output(dhclient.decode("utf-8")) except subprocess.CalledProcessError as exception: print(color.FAIL("<Test.py> dhclient FAILED threw exception:")) print(exception.output) vm.exit(1, "<Test.py> dhclient test failed") return False ping_test() if ping_passed and num_messages == 4: vm.exit(0, "<Test.py> DHCP process and ping test completed successfully. Process returned 0 exit status") else: vm.exit(1, "<Test.py> DHCP process or ping test failed")
def integration_tests(tests): """ Function that runs the tests that are passed to it. Filters out any invalid tests before running Arguments: tests: List containing test objects to be run Returns: integer: Number of tests that failed """ if len(tests) == 0: return 0 time_sensitive_tests = [ x for x in tests if x.properties_["time_sensitive"] ] tests = [x for x in tests if x not in time_sensitive_tests] # Print info before starting to run print pretty.HEADER("Starting " + str(len(tests)) + " integration test(s)") for test in tests: print pretty.INFO("Test"), "starting", test.name_ if time_sensitive_tests: print pretty.HEADER("Then starting " + str(len(time_sensitive_tests)) + " time sensitive integration test(s)") for test in time_sensitive_tests: print pretty.INFO("Test"), "starting", test.name_ processes = [] fail_count = 0 global test_count test_count += len(tests) + len(time_sensitive_tests) # Find number of cpu cores if args.parallel: num_cpus = args.parallel else: num_cpus = multiprocessing.cpu_count() # Collect test results print pretty.HEADER( "Collecting integration test results, on {0} cpu(s)".format(num_cpus)) # Run a maximum number of parallell tests equal to cpus available while tests or processes: # While there are tests or processes left try: processes.append( tests.pop(0).start()) # Remove test from list after start except IndexError: pass # All tests done while (len(processes) == num_cpus) or not tests: # While there are a maximum of num_cpus to process # Or there are no more tests left to start we wait for them for p in list(processes): # Iterate over copy of list if p.proc_.poll() is not None: fail_count += 1 if p.wait_status() else 0 processes.remove(p) time.sleep(1) if not processes and not tests: break # Exit early if any tests failed if fail_count and args.fail: print pretty.FAIL(str(fail_count) + "integration tests failed") sys.exit(fail_count) # Start running the time sensitive tests for test in time_sensitive_tests: process = test.start() fail_count += 1 if process.wait_status() else 0 if fail_count and args.fail: print pretty.FAIL(str(fail_count) + "integration tests failed") sys.exit(fail_count) return fail_count
def start_icmp_test(trigger_line): global num_successes # Installing hping3 on linux subprocess.call(["sudo", "apt-get", "update"]) subprocess.call(["sudo", "apt-get", "-y", "install", "hping3"]) # Installing hping3 on macOS # subprocess.call(["brew", "install", "hping"]) # 1 Ping: Checking output from callback in service.cpp print color.INFO("<Test.py>"), "Performing ping test" output_data = "" for x in range(0, 11): output_data += vm.readline() print output_data if "Received packet from gateway" in output_data and \ "Identifier: 0" in output_data and \ "Sequence number: 0" in output_data and \ "Source: 10.0.0.1" in output_data and \ "Destination: 10.0.0.45" in output_data and \ "Type: ECHO REPLY (0)" in output_data and \ "Code: DEFAULT (0)" in output_data and \ "Checksum: " in output_data and \ "Data: INCLUDEOS12345ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678" in output_data and \ "No reply received from 10.0.0.42" in output_data and \ "No reply received from 10.0.0.43" in output_data: num_successes += 1 print color.INFO("<Test.py>"), "Ping test succeeded" else: print color.FAIL("<Test.py>"), "Ping test FAILED" # 2 Port unreachable print color.INFO( "<Test.py>"), "Performing Destination Unreachable (port) test" # Sending 1 udp packet to 10.0.0.45 to port 8080 udp_port_output = subprocess32.check_output( ["sudo", "hping3", "10.0.0.45", "--udp", "-p", "8080", "-c", "1"], timeout=thread_timeout) print udp_port_output # Validate content in udp_port_output: if "ICMP Port Unreachable from ip=10.0.0.45" in udp_port_output: print color.INFO("<Test.py>"), "Port Unreachable test succeeded" num_successes += 1 else: print color.FAIL("<Test.py>"), "Port Unreachable test FAILED" # 3 Protocol unreachable print color.INFO( "<Test.py>"), "Performing Destination Unreachable (protocol) test" # Sending 1 raw ip packet to 10.0.0.45 with protocol 16 rawip_protocol_output = subprocess32.check_output([ "sudo", "hping3", "10.0.0.45", "-d", "20", "-0", "--ipproto", "16", "-c", "1" ], timeout=thread_timeout) print rawip_protocol_output # Validate content in rawip_protocol_output: if "ICMP Protocol Unreachable from ip=10.0.0.45" in rawip_protocol_output: print color.INFO("<Test.py>"), "Protocol Unreachable test succeeded" num_successes += 1 else: print color.FAIL("<Test.py>"), "Protocol Unreachable test FAILED" # 4 Check result of tests if num_successes == 3: vm.exit( 0, "<Test.py> All ICMP tests succeeded. Process returned 0 exit status" ) else: num_fails = 3 - num_successes res = "<Test.py> " + str(num_fails) + " ICMP test(s) failed" vm.exit(1, res)