| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- import os
- import random
- import threading
- import socket
- import time
- import re
- from TCAction import TCActionBase
- from TCAction import PerformanceTCBase
- from NativeLog import NativeLog
- def calc_hash(index):
- return (index & 0xffffffff) % 83 + (index & 0xffffffff) % 167
- def verify_data(data, start_index):
- for i, c in enumerate(data):
- if ord(c) != calc_hash(start_index + i):
- NativeLog.add_trace_critical("[Data Validation Error] target sent data index %u is error."
- " Sent data is %x, should be %x"
- % (start_index + i, ord(c), calc_hash(start_index + i)))
- return False
- return True
- def make_validation_data(length, start_index):
- return bytes().join([chr(calc_hash(start_index + i)) for i in range(length)])
- class SendThread(threading.Thread):
- def __init__(self, sock, send_len):
- threading.Thread.__init__(self)
- self.setDaemon(True)
- self.sock = sock
- self.send_len = send_len
- self.exit_event = threading.Event()
- pass
- def exit(self):
- self.exit_event.set()
- def run(self):
- index = 0
- while self.exit_event.isSet() is False:
- data = make_validation_data(self.send_len, index)
- try:
- self.sock.send(data)
- index += self.send_len
- except StandardError:
- # pass but not exit thread
- time.sleep(1)
- continue
- pass
- class RecvThread(threading.Thread):
- def __init__(self, sock):
- threading.Thread.__init__(self)
- self.setDaemon(True)
- self.sock = sock
- self.exit_event = threading.Event()
- def exit(self):
- self.exit_event.set()
- def run(self):
- index = 0
- while self.exit_event.isSet() is False:
- if self.sock is not None:
- try:
- data = self.sock.recv(8*1024)
- except StandardError, e:
- NativeLog.add_exception_log(e)
- NativeLog.add_trace_critical("recv error, connection closed")
- break
- if verify_data(data, index) is not True:
- break
- index += len(data)
- else:
- time.sleep(1)
- pass
- class ValidationThread(threading.Thread):
- def __init__(self, tc_action):
- threading.Thread.__init__(self)
- self.setDaemon(True)
- self.tc_action = tc_action
- self.exit_event = threading.Event()
- def exit(self):
- self.exit_event.set()
- def run(self):
- while self.exit_event.isSet() is False:
- if self.tc_action.check_response("SSC1", "DATA_ERROR", 5) is True:
- NativeLog.add_trace_critical("[Data Validation Error] target recv data error")
- break
- pass
- class TestCase(PerformanceTCBase.PerformanceTCBase):
- def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH):
- PerformanceTCBase.PerformanceTCBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path)
- self.send_len = 0
- self.tx_enable = None
- self.rx_enable = None
- self.conn_num = 0
- self.test_time = 0
- # load param from excel
- cmd_set = test_case["cmd set"]
- for i in range(1, len(cmd_set)):
- if cmd_set[i][0] != "dummy":
- cmd_string = "self." + cmd_set[i][0]
- exec cmd_string
- pass
- def execute(self):
- TCActionBase.TCActionBase.execute(self)
- try:
- # configurable params
- send_len = self.send_len
- tx_enable = self.tx_enable
- rx_enable = self.rx_enable
- conn_num = self.conn_num
- test_time = self.test_time * 60 # convert minutes to seconds
- # configurable params
- except StandardError, e:
- NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e)
- raise StandardError("Error configuration")
- # init throughput result data
- test_item = ""
- if tx_enable is True:
- test_item += "Tx"
- if rx_enable is True:
- test_item += "Rx"
- if test_item == "":
- raise StandardError("no throughput test item")
- pc_ip = self.get_parameter("pc_ip")
- tcp_port = random.randint(10000, 50000)
- # disable recv print during throughput test
- self.serial_write_line("SSC1", "soc -R -o 0")
- if self.check_response("SSC1", "+RECVPRINT", 2) is False:
- NativeLog.add_trace_critical("Fail, Fail to disable recv print")
- # create server
- server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
- server_sock.bind((pc_ip, tcp_port))
- server_sock.settimeout(5)
- server_sock.listen(5)
- sock_id_list = []
- send_thread_list = []
- recv_thread_list = []
- # step 4 create tcp connection
- for i in range(conn_num):
- self.serial_write_line("SSC1", "soc -B -t TCP")
- match = self.check_regular_expression("SSC1", re.compile("\+BIND:(\d+),OK"), 2)
- if match is None:
- NativeLog.add_trace_critical("Fail, Fail to bind")
- return
- else:
- sock_id_list.append(int(match.group(1)))
- self.serial_write_line("SSC1", "soc -V -s %s -o 3" % sock_id_list[-1])
- if self.check_regular_expression("SSC1", re.compile("\+DATA_VALIDATION:\d+,OK"), 2) is None:
- NativeLog.add_trace_critical("Fail, Failed to enable validation")
- return
- self.serial_write_line("SSC1", "soc -C -s %s -i %s -p %s" % (sock_id_list[-1], pc_ip, tcp_port))
- try:
- sock, addr = server_sock.accept()
- except socket.error, e:
- NativeLog.add_trace_critical("%s" % e)
- raise e
- if self.check_regular_expression("SSC1", re.compile("\+CONNECT:\d+,OK"), 5) is None:
- NativeLog.add_trace_critical("Fail, Failed to connect")
- return
- sock.settimeout(10)
- send_thread_list.append(SendThread(sock if rx_enable is True else None, send_len))
- recv_thread_list.append(RecvThread(sock if tx_enable is True else None))
- recv_thread_list[-1].start()
- # step 5 do test
- validation_thread = ValidationThread(self)
- validation_thread.start()
- for send_thread in send_thread_list:
- send_thread.start()
- if tx_enable is True:
- # do send from target
- for sock_id in sock_id_list:
- self.serial_write_line("SSC1", "soc -S -s %s -l %s -n 10000000" % (sock_id, send_len))
- time1 = time.time()
- exit_flag = False
- while time.time() - time1 < test_time and exit_flag is False:
- for i in sock_id_list:
- send_thread_list[i].join(0.5)
- recv_thread_list[i].join(0.5)
- validation_thread.join(0.5)
- if send_thread_list[i].isAlive() is False \
- or recv_thread_list[i].isAlive() is False \
- or validation_thread.isAlive() is False:
- NativeLog.add_trace_critical("validation error found")
- exit_flag = True
- break
- NativeLog.add_prompt_trace("time escape: %s" % (time.time() - time1))
- if time.time() - time1 >= test_time:
- self.set_result("Succeed")
- else:
- self.set_result("Failed")
- # exit all thread
- for i in sock_id_list:
- send_thread_list[i].exit()
- recv_thread_list[i].exit()
- send_thread_list[i].join()
- send_thread_list[i].join()
- validation_thread.exit()
- validation_thread.join()
- def main():
- pass
- if __name__ == '__main__':
- main()
|