TCPThroughput.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. import os
  2. import time
  3. import random
  4. import threading
  5. import socket
  6. from TCAction import TCActionBase
  7. from NativeLog import NativeLog
  8. from NativeLog import ThroughputResult
  9. from Utility import RSSICalibrator
  10. LOG_FOLDER = os.path.join("Performance", "Throughput")
  11. AP_PROP_KEY = ("ssid", "password", "apc")
  12. class SendThread(threading.Thread):
  13. def __init__(self, sock, send_len):
  14. threading.Thread.__init__(self)
  15. self.setDaemon(True)
  16. self.sock = sock
  17. self.send_len = send_len
  18. self.exit_event = threading.Event()
  19. self.calc_event = threading.Event()
  20. self.bytes_sent = 0
  21. pass
  22. def start_calc(self):
  23. self.calc_event.set()
  24. def stop_calc(self):
  25. self.calc_event.clear()
  26. self.exit_event.set()
  27. def run(self):
  28. data = "A" * self.send_len
  29. if self.sock is None:
  30. return
  31. while True:
  32. if self.exit_event.isSet() is True:
  33. break
  34. try:
  35. self.sock.send(data)
  36. except StandardError:
  37. break
  38. if self.calc_event.isSet() is True:
  39. self.bytes_sent += self.send_len
  40. def get_bytes_sent(self):
  41. return self.bytes_sent
  42. pass
  43. class RecvThread(threading.Thread):
  44. def __init__(self, sock):
  45. threading.Thread.__init__(self)
  46. self.setDaemon(True)
  47. self.sock = sock
  48. self.exit_event = threading.Event()
  49. self.calc_event = threading.Event()
  50. self.bytes_recv = 0
  51. def start_calc(self):
  52. self.calc_event.set()
  53. def stop_calc(self):
  54. self.calc_event.clear()
  55. self.exit_event.set()
  56. def run(self):
  57. if self.sock is None:
  58. return
  59. while True:
  60. if self.exit_event.isSet() is True:
  61. break
  62. try:
  63. data = self.sock.recv(8 * 1024)
  64. except StandardError:
  65. break
  66. if self.calc_event.isSet() is True:
  67. self.bytes_recv += len(data)
  68. def get_bytes_recv(self):
  69. return self.bytes_recv
  70. pass
  71. class TestCase(TCActionBase.CommonTCActionBase):
  72. def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH):
  73. TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path)
  74. self.performance_folder_path = log_path
  75. self.att_test_list = range(60)
  76. cmd_set = test_case["cmd set"]
  77. # load param from excel
  78. for i in range(1, len(cmd_set)):
  79. if cmd_set[i][0] != "dummy":
  80. cmd_string = "self." + cmd_set[i][0]
  81. exec cmd_string
  82. self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name)
  83. pass
  84. def execute(self):
  85. TCActionBase.TCActionBase.execute(self)
  86. self.result_cntx.start()
  87. try:
  88. # configurable params
  89. ap_list = self.get_parameter("shield_box_ap_list")
  90. pc_ip = self.get_parameter("pc_ip")
  91. send_len = self.send_len
  92. att_test_list = self.att_test_list
  93. tx_enable = self.tx_enable
  94. rx_enable = self.rx_enable
  95. measure_period = self.measure_period
  96. # configurable params
  97. except StandardError, e:
  98. NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e)
  99. raise StandardError("Error configuration")
  100. tcp_port = random.randint(40000, 50000)
  101. # init throughput result data
  102. test_item = ""
  103. if tx_enable is True:
  104. test_item += "Tx"
  105. if rx_enable is True:
  106. test_item += "Rx"
  107. if test_item == "":
  108. raise StandardError("no throughput test item")
  109. folder_path = os.path.join(self.performance_folder_path, LOG_FOLDER)
  110. file_name = os.path.join(folder_path,
  111. "TCPThroughput_%s_%s" % (test_item, time.strftime("%d%H%M%S", time.localtime())))
  112. result = ThroughputResult.ThroughputResult(file_name, standard_required=True)
  113. # restart before executing throughput
  114. checker_stings = ["R SSC1 C !!!ready!!!"]
  115. test_action_string = ["SSC SSC1 reboot"]
  116. fail_string = "Fail, Fail to reboot"
  117. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
  118. self.result_cntx.set_result("Fail")
  119. return
  120. # disable recv print during throughput test
  121. checker_stings = ["R SSC1 C +RECVPRINT"]
  122. test_action_string = ["SSC SSC1 soc -R -o 0"]
  123. fail_string = "Fail, Fail to disable recv print"
  124. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
  125. self.result_cntx.set_result("Fail")
  126. return
  127. ret = True
  128. for ap_prop in ap_list:
  129. ssid = ap_prop[0]
  130. password = ap_prop[1]
  131. apc = ap_prop[2]
  132. if ap_prop[1] == "":
  133. # set a default string for open ap
  134. password = "1"
  135. # switch off all outlet, switch on AP outlet
  136. outlet_config_dict = dict.fromkeys(range(1, 9), "OFF")
  137. outlet_config_dict[apc] = "ON"
  138. apc_cmd = "APC <APC1>"
  139. for outlet in outlet_config_dict:
  140. apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet)
  141. checker_stings = ["P PC_COM L OK"]
  142. fail_string = "Fail, Fail to switch apc"
  143. if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False:
  144. ret = False
  145. break
  146. # wait AP ready
  147. time.sleep(20)
  148. # create server
  149. server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
  150. server_sock.bind((pc_ip, tcp_port))
  151. server_sock.settimeout(5)
  152. server_sock.listen(5)
  153. if tx_enable is True:
  154. result.add_test_item(ssid + "_tx")
  155. if rx_enable is True:
  156. result.add_test_item(ssid + "_rx")
  157. # create RSSI Calibrator
  158. calibrator = RSSICalibrator.Calibrator()
  159. for att_value in att_test_list:
  160. # step 0 set att value
  161. checker_stings = ["R PC_COM L OK"]
  162. test_action_string = ["ATT <att_port> %s" % att_value]
  163. fail_string = "Fail, Fail to set att value"
  164. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
  165. ret = False
  166. break
  167. # continue
  168. # step 1 get AP RSSI
  169. checker_stings = ["R SSC1 A <rssi>:\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)" % ssid]
  170. test_action_string = ["SSC SSC1 sta -S -s %s" % ssid]
  171. fail_string = "Fail, Fail to scan"
  172. rssi = scan_count = 0
  173. for i in range(3):
  174. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
  175. continue
  176. rssi += int(self.test_env.get_variable_by_name("rssi")[1])
  177. scan_count += 1
  178. rssi = calibrator.calibrate_rssi(float(rssi) / scan_count if scan_count > 0 else 0, att_value)
  179. # step 2 connect to AP
  180. checker_stings = ["R SSC1 C +JAP:CONNECTED"]
  181. test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ssid, password)]
  182. fail_string = "Fail, Fail to JAP"
  183. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string,
  184. check_freq=1, check_time=30) is False:
  185. if rssi < -89:
  186. continue
  187. else:
  188. ret = False
  189. break
  190. # step 3 close all connections
  191. checker_stings = ["R SSC1 C +CLOSEALL"]
  192. test_action_string = ["SSC SSC1 soc -T"]
  193. fail_string = "Fail, Fail to close socket"
  194. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
  195. ret = False
  196. break
  197. # continue
  198. # step 4 create tcp connection
  199. checker_stings = ["R SSC1 A <client_sock>:\+BIND:(\d+),OK"]
  200. test_action_string = ["SSC SSC1 soc -B -t TCP"]
  201. fail_string = "Fail, Fail to bind"
  202. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
  203. ret = False
  204. break
  205. # continue
  206. checker_stings = ["P SSC1 RE \+CONNECT:\d+,OK"]
  207. test_action_string = ["SSC SSC1 soc -C -s <client_sock> -i %s -p %s" % (pc_ip, tcp_port)]
  208. fail_string = "Fail, Fail to connect socket"
  209. if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
  210. ret = False
  211. break
  212. # continue
  213. try:
  214. sock, addr = server_sock.accept()
  215. except socket.error, e:
  216. NativeLog.add_trace_critical("%s" % e)
  217. continue
  218. sock.settimeout(measure_period)
  219. # step 5 do throughput test
  220. send_thread = SendThread(sock if rx_enable is True else None, send_len)
  221. send_thread.start()
  222. recv_thread = RecvThread(sock if tx_enable is True else None)
  223. recv_thread.start()
  224. if tx_enable is True:
  225. # do send from target
  226. test_action_string = ["SSC SSC1 soc -S -s <client_sock> -l %s -n 10000000" % send_len]
  227. fail_string = "Fail, Fail to send"
  228. if self.load_and_exe_one_step([], test_action_string, fail_string) is False:
  229. pass
  230. # start throughput calculate
  231. send_thread.start_calc()
  232. recv_thread.start_calc()
  233. # sleep for measure period
  234. time.sleep(measure_period)
  235. # stop throughput calculate
  236. send_thread.stop_calc()
  237. recv_thread.stop_calc()
  238. send_thread.join()
  239. recv_thread.join()
  240. sock.close()
  241. # output throughput result
  242. # in Mbps
  243. if send_thread.get_bytes_sent() > 0:
  244. result.log_throughput(ssid + "_rx", rssi, att_value,
  245. float(send_thread.get_bytes_sent() * 8) / (measure_period * 1000000))
  246. if recv_thread.get_bytes_recv() > 0:
  247. result.log_throughput(ssid + "_tx", rssi, att_value,
  248. float(recv_thread.get_bytes_recv() * 8) / (measure_period * 1000000))
  249. result.output_to_file()
  250. pass
  251. server_sock.close()
  252. if not ret:
  253. NativeLog.add_trace_critical("Test SUC for %s" % ssid)
  254. elif ret:
  255. NativeLog.add_trace_critical("Test FAIL for %s!!!" % ssid)
  256. if ret:
  257. self.result_cntx.set_result("Succeed")
  258. else:
  259. self.result_cntx.set_result("Fail")
  260. # finally, execute done
  261. def result_check(self, port_name, data):
  262. TCActionBase.CommonTCActionBase.result_check(self, port_name, data)
  263. self.result_cntx.append_data(port_name, data)
  264. def main():
  265. pass
  266. if __name__ == '__main__':
  267. main()