TCPDataValidation.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import os
  2. import random
  3. import threading
  4. import socket
  5. import time
  6. import re
  7. from TCAction import TCActionBase
  8. from TCAction import PerformanceTCBase
  9. from NativeLog import NativeLog
  10. def calc_hash(index):
  11. return (index & 0xffffffff) % 83 + (index & 0xffffffff) % 167
  12. def verify_data(data, start_index):
  13. for i, c in enumerate(data):
  14. if ord(c) != calc_hash(start_index + i):
  15. NativeLog.add_trace_critical("[Data Validation Error] target sent data index %u is error."
  16. " Sent data is %x, should be %x"
  17. % (start_index + i, ord(c), calc_hash(start_index + i)))
  18. return False
  19. return True
  20. def make_validation_data(length, start_index):
  21. return bytes().join([chr(calc_hash(start_index + i)) for i in range(length)])
  22. class SendThread(threading.Thread):
  23. def __init__(self, sock, send_len):
  24. threading.Thread.__init__(self)
  25. self.setDaemon(True)
  26. self.sock = sock
  27. self.send_len = send_len
  28. self.exit_event = threading.Event()
  29. pass
  30. def exit(self):
  31. self.exit_event.set()
  32. def run(self):
  33. index = 0
  34. while self.exit_event.isSet() is False:
  35. data = make_validation_data(self.send_len, index)
  36. try:
  37. self.sock.send(data)
  38. index += self.send_len
  39. except StandardError:
  40. # pass but not exit thread
  41. time.sleep(1)
  42. continue
  43. pass
  44. class RecvThread(threading.Thread):
  45. def __init__(self, sock):
  46. threading.Thread.__init__(self)
  47. self.setDaemon(True)
  48. self.sock = sock
  49. self.exit_event = threading.Event()
  50. def exit(self):
  51. self.exit_event.set()
  52. def run(self):
  53. index = 0
  54. while self.exit_event.isSet() is False:
  55. if self.sock is not None:
  56. try:
  57. data = self.sock.recv(8*1024)
  58. except StandardError, e:
  59. NativeLog.add_exception_log(e)
  60. NativeLog.add_trace_critical("recv error, connection closed")
  61. break
  62. if verify_data(data, index) is not True:
  63. break
  64. index += len(data)
  65. else:
  66. time.sleep(1)
  67. pass
  68. class ValidationThread(threading.Thread):
  69. def __init__(self, tc_action):
  70. threading.Thread.__init__(self)
  71. self.setDaemon(True)
  72. self.tc_action = tc_action
  73. self.exit_event = threading.Event()
  74. def exit(self):
  75. self.exit_event.set()
  76. def run(self):
  77. while self.exit_event.isSet() is False:
  78. if self.tc_action.check_response("SSC1", "DATA_ERROR", 5) is True:
  79. NativeLog.add_trace_critical("[Data Validation Error] target recv data error")
  80. break
  81. pass
  82. class TestCase(PerformanceTCBase.PerformanceTCBase):
  83. def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH):
  84. PerformanceTCBase.PerformanceTCBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path)
  85. self.send_len = 0
  86. self.tx_enable = None
  87. self.rx_enable = None
  88. self.conn_num = 0
  89. self.test_time = 0
  90. # load param from excel
  91. cmd_set = test_case["cmd set"]
  92. for i in range(1, len(cmd_set)):
  93. if cmd_set[i][0] != "dummy":
  94. cmd_string = "self." + cmd_set[i][0]
  95. exec cmd_string
  96. pass
  97. def execute(self):
  98. TCActionBase.TCActionBase.execute(self)
  99. try:
  100. # configurable params
  101. send_len = self.send_len
  102. tx_enable = self.tx_enable
  103. rx_enable = self.rx_enable
  104. conn_num = self.conn_num
  105. test_time = self.test_time * 60 # convert minutes to seconds
  106. # configurable params
  107. except StandardError, e:
  108. NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e)
  109. raise StandardError("Error configuration")
  110. # init throughput result data
  111. test_item = ""
  112. if tx_enable is True:
  113. test_item += "Tx"
  114. if rx_enable is True:
  115. test_item += "Rx"
  116. if test_item == "":
  117. raise StandardError("no throughput test item")
  118. pc_ip = self.get_parameter("pc_ip")
  119. tcp_port = random.randint(10000, 50000)
  120. # disable recv print during throughput test
  121. self.serial_write_line("SSC1", "soc -R -o 0")
  122. if self.check_response("SSC1", "+RECVPRINT", 2) is False:
  123. NativeLog.add_trace_critical("Fail, Fail to disable recv print")
  124. # create server
  125. server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
  126. server_sock.bind((pc_ip, tcp_port))
  127. server_sock.settimeout(5)
  128. server_sock.listen(5)
  129. sock_id_list = []
  130. send_thread_list = []
  131. recv_thread_list = []
  132. # step 4 create tcp connection
  133. for i in range(conn_num):
  134. self.serial_write_line("SSC1", "soc -B -t TCP")
  135. match = self.check_regular_expression("SSC1", re.compile("\+BIND:(\d+),OK"), 2)
  136. if match is None:
  137. NativeLog.add_trace_critical("Fail, Fail to bind")
  138. return
  139. else:
  140. sock_id_list.append(int(match.group(1)))
  141. self.serial_write_line("SSC1", "soc -V -s %s -o 3" % sock_id_list[-1])
  142. if self.check_regular_expression("SSC1", re.compile("\+DATA_VALIDATION:\d+,OK"), 2) is None:
  143. NativeLog.add_trace_critical("Fail, Failed to enable validation")
  144. return
  145. self.serial_write_line("SSC1", "soc -C -s %s -i %s -p %s" % (sock_id_list[-1], pc_ip, tcp_port))
  146. try:
  147. sock, addr = server_sock.accept()
  148. except socket.error, e:
  149. NativeLog.add_trace_critical("%s" % e)
  150. raise e
  151. if self.check_regular_expression("SSC1", re.compile("\+CONNECT:\d+,OK"), 5) is None:
  152. NativeLog.add_trace_critical("Fail, Failed to connect")
  153. return
  154. sock.settimeout(10)
  155. send_thread_list.append(SendThread(sock if rx_enable is True else None, send_len))
  156. recv_thread_list.append(RecvThread(sock if tx_enable is True else None))
  157. recv_thread_list[-1].start()
  158. # step 5 do test
  159. validation_thread = ValidationThread(self)
  160. validation_thread.start()
  161. for send_thread in send_thread_list:
  162. send_thread.start()
  163. if tx_enable is True:
  164. # do send from target
  165. for sock_id in sock_id_list:
  166. self.serial_write_line("SSC1", "soc -S -s %s -l %s -n 10000000" % (sock_id, send_len))
  167. time1 = time.time()
  168. exit_flag = False
  169. while time.time() - time1 < test_time and exit_flag is False:
  170. for i in sock_id_list:
  171. send_thread_list[i].join(0.5)
  172. recv_thread_list[i].join(0.5)
  173. validation_thread.join(0.5)
  174. if send_thread_list[i].isAlive() is False \
  175. or recv_thread_list[i].isAlive() is False \
  176. or validation_thread.isAlive() is False:
  177. NativeLog.add_trace_critical("validation error found")
  178. exit_flag = True
  179. break
  180. NativeLog.add_prompt_trace("time escape: %s" % (time.time() - time1))
  181. if time.time() - time1 >= test_time:
  182. self.set_result("Succeed")
  183. else:
  184. self.set_result("Failed")
  185. # exit all thread
  186. for i in sock_id_list:
  187. send_thread_list[i].exit()
  188. recv_thread_list[i].exit()
  189. send_thread_list[i].join()
  190. send_thread_list[i].join()
  191. validation_thread.exit()
  192. validation_thread.join()
  193. def main():
  194. pass
  195. if __name__ == '__main__':
  196. main()