1#!/usr/bin/python3 2# 3# Copyright (c) 2016 Intel Corporation 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import random 18import select 19import socket 20import sys 21import time 22 23if not hasattr(socket, 'if_nametoindex'): 24 print("Please Python3, this is incompatible with Python 2") 25 sys.exit(1) 26 27if len(sys.argv) != 3: 28 print("Usage: %s interface echo-server-ipv6-address" % sys.argv[0]) 29 sys.exit(1) 30 31def log(msg): 32 print("%s: %s" % (time.asctime(), msg)) 33 34iface = sys.argv[1] 35addr = sys.argv[2] 36scope_id = socket.if_nametoindex(iface) 37 38log("Connecting to [%s]:4242 (through interface %s, scope_id %d)" % ( 39 addr, iface, scope_id 40)) 41 42sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP) 43sock.connect((addr, 4242, 0, scope_id)) 44 45# Use non-blocking I/O so we can use select() to check for timeouts 46sock.setblocking(False) 47 48log("Connection established. Will begin sending data") 49 50delta_avg = 0 51delta_avg_len = 0 52timeouts = 0 53tx_errors = 0 54rx_errors = 0 55for current_n in range(0, 2**32, 10): 56 # Wait up to 1 second between each packet transmitted 57 time.sleep(random.random()) 58 59 log("Will try sending %d and read it back" % current_n) 60 61 while True: 62 _, wlist, _ = select.select([], [sock], [], 1) 63 if wlist: 64 break 65 66 timeouts += 1 67 log("Timeout while sending data to Zephyr, will try again") 68 69 time_before_send = time.time() 70 current_n_bytes = bytes(str(current_n), "ascii") 71 sent_bytes = sock.send(current_n_bytes) 72 if sent_bytes != len(current_n_bytes): 73 tx_errors +=1 74 log("Were not able to transmit %d (%d bytes), will try again" % ( 75 current_n, len(current_n_bytes) 76 )) 77 continue 78 79 while True: 80 rlist, _, _ = select.select([sock], [], [], 1) 81 if rlist: 82 break 83 84 timeouts += 1 85 log("Timeout while reading data from Zephyr, will try again") 86 87 rcvd_bytes = sock.recv(len(current_n_bytes)) 88 if len(rcvd_bytes) != len(current_n_bytes): 89 rx_errors += 1 90 log("Got back %d bytes instead of %d. Will send again" % ( 91 len(rcvd_bytes), len(current_n_bytes) 92 )) 93 continue 94 95 if rcvd_bytes != current_n_bytes: 96 rx_errors += 1 97 log("Got back '%s' but sent '%s'. Will try again" % ( 98 rcvd_bytes, current_n_bytes 99 )) 100 continue 101 102 delta = time.time() - time_before_send 103 log("Got %d back in %f seconds" % (current_n, delta)) 104 105 delta_avg += delta 106 delta_avg_len += 1 107 if delta_avg_len > 10: 108 log("Roundtrip takes %f seconds on average" % (delta_avg / 10)) 109 110 delta_avg = 0 111 delta_avg_len = 0 112 113 if timeouts > 0 or rx_errors > 0 or tx_errors > 0: 114 log("So far: %d timeouts, %d rx errors, %d tx errors" % ( 115 timeouts, rx_errors, tx_errors 116 )) 117 else: 118 log("So far, so good: no timeouts or errors") 119