UDPThroughput.py 12 KB

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