esp-idf/components/test/TestCaseScript/IOT/SCIOT.py

358 lines
16 KiB
Python
Raw Normal View History

import Queue
from TCAction import TCActionBase
from NativeLog import NativeLog
from SCUDPServer import *
from TCAction.CmdExecutor import CmdExecutorBasic
from Utility import MakeFolder
TEST_RESULT_CATEGORY = ("AP", "Phone")
TEST_RESULT_PROPERTY = ("model", "total", "succeed", "failed", "total time1", "total time2")
SINGLE_TEST_RESULT = ("AP", "Phone", "result", "time1", "time2")
LOG_FILES = ("by_ap.tmp", "by_phone.tmp", "failed_item.tmp", "disqualified_item.tmp", "total.tmp")
LOG_PATH = os.path.join("AT_LOG", "IOT")
def make_session_id(mac, test_id):
return mac_to_bytes(mac) + chr((test_id & 0xFF00) >> 8) + chr(test_id & 0xFF)
class TestHandler(threading.Thread):
def __init__(self, session_id, ap, phone, udp_server, test_action):
threading.Thread.__init__(self)
self.setDaemon(True)
self.udp_server = udp_server
self.session_id = session_id
self.ap = ap
self.phone = phone
self.test_action = test_action
self.recv_queue = Queue.Queue(10)
self.abort_event = threading.Event()
self.start_time = time.time()
self.test_result = None
udp_server.register_test_handler(session_id, self)
pass
def req_receiver(self, msg, address):
self.recv_queue.put([msg, address])
pass
def res_receiver(self, msg, address):
self.recv_queue.put([msg, address])
pass
def abort_handler(self):
NativeLog.add_prompt_trace("[Test Handler][Debug] test aborted")
self.abort_event.set()
self.test_action.remove_from_available_list(self.phone)
pass
def wait_result(self, event, timeout=None):
time_start = time.time()
while True:
if self.abort_event.isSet() is True:
return False
if time.time() - self.start_time > ABORT_TIMEOUT:
return False
if timeout is not None:
if time.time() - time_start > timeout:
return False
if event == "ACK" or event == "result":
try:
ret = self.recv_queue.get(timeout=0.5)
except Queue.Empty, e:
continue
else:
msg = ret[0]
value_list = get_value_from_msg("type", msg)
msg_typ = ord(value_list[0])
if msg_typ == TYPE_VAL[event]:
NativeLog.add_prompt_trace("[Test Handler][Debug] wait message succeed")
return msg
elif (msg_typ & 0x80) == 0: # invalid request
self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["Not support"]],
[VALUE_NAME["session id"], self.session_id]],
ret[1])
pass
else:
pass
pass
def run(self):
for i in range(1):
# step1 send broadcast to SP
msg = [[VALUE_NAME["type"], TYPE_VAL["Init new test"]],
[VALUE_NAME["session id"], self.session_id]]
self.udp_server.send_request(("<broadcast>", self.udp_server.udp_port), self.session_id, msg)
# wait response
if self.wait_result("ACK") is False:
break
NativeLog.add_prompt_trace("[Step1] Initial new test succeed")
# step2 start smart config
checker_stings = ["ATR AT1 L OK"]
test_action_string = ["ATS AT1 AT+CWSTOPSMART"]
fail_string = "Fail, Failed to start smart config"
if self.test_action.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
NativeLog.add_prompt_trace(fail_string)
break
checker_stings = ["ATR AT1 L OK"]
test_action_string = ["ATS AT1 AT+CWSTARTSMART=1"]
if self.test_action.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False:
NativeLog.add_prompt_trace(fail_string)
break
NativeLog.add_prompt_trace("[Step2] Start smart config succeed")
# step3 send test request to SP
msg = [[VALUE_NAME["type"], TYPE_VAL["test request"]],
[VALUE_NAME["session id"], self.session_id],
[VALUE_NAME["ap ssid"], self.ap["ssid"]],
[VALUE_NAME["ap password"], self.ap["password"]],
[VALUE_NAME["ap bssid"], mac_to_bytes(self.ap["bssid"])],
# [VALUE_NAME["ET version"], 0x20],
[VALUE_NAME["ssid hidden"], self.ap["is_hidden"]],
[VALUE_NAME["ap encryption"], AP_ENCRYPTION_VAL[self.ap["encryption"]]]
]
self.udp_server.send_request((self.phone["ip"], self.udp_server.udp_port), self.session_id, msg)
# wait SP reply
if self.wait_result("ACK") is False:
break
NativeLog.add_prompt_trace("[Step3] Send test request succeed")
time_base = time.time()
# step4 wait target smart config succeed
checker_stings = ["ATR AT1 C get%%20wifi%%20info C %s C %s"
% (self.ap["ssid"], self.ap["password"])]
test_action_string = []
fail_string = "Fail, Fail to get ap info"
# if check target get smart config result fail, continue and get result from SP
ret = self.test_action.load_and_exe_one_step(checker_stings, test_action_string,
fail_string, check_time=600)
if ret is False:
NativeLog.add_prompt_trace("[Step4] Target smart config fail")
step_4_fail = True
else:
NativeLog.add_prompt_trace("[Step4] Target smart config succeed")
step_4_fail = False
time_target_succeed = time.time() - time_base
# step5 wait SP result
msg = self.wait_result("result")
if msg is False:
NativeLog.add_prompt_trace("[Test Handler][Debug] Failed to get result from SP")
break
else:
self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["ACK"]],
[VALUE_NAME["session id"], self.session_id]],
(self.phone["ip"], self.udp_server.udp_port))
tmp = get_value_from_msg(["result code", "start SC time", "recv UDP time"], msg)
result_code = ord(tmp[0])
if result_code == RESULT_CODE_VAL["OK"]:
sp_start_time = bytes_to_time(tmp[1])
sp_recv_udp_time = bytes_to_time(tmp[2])
smart_config_protocol_cost = time_target_succeed - sp_start_time
user_experience_time = sp_recv_udp_time - sp_start_time
self.test_result = ["Succeed", smart_config_protocol_cost, user_experience_time]
elif result_code == RESULT_CODE_VAL["recv UDP fail"]:
sp_start_time = bytes_to_time(tmp[1])
if step_4_fail is True:
smart_config_protocol_cost = 0
else:
smart_config_protocol_cost = time_target_succeed - sp_start_time
self.test_result = ["Failed", smart_config_protocol_cost, 0]
pass
else:
NativeLog.add_prompt_trace("[Test Handler][Debug] Disqualified message: %s" % tmp)
for k in range(RETRANSMIT_COUNT - 1):
if self.wait_result("result", RETRANSMIT_TIMEOUT) is not False:
self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["ACK"]],
[VALUE_NAME["session id"], self.session_id]],
(self.phone["ip"], self.udp_server.udp_port))
NativeLog.add_prompt_trace("[Step5] Receive test result from SP")
if self.test_result is None:
self.test_result = ["Disqualified", 0, 0]
self.udp_server.deregister_test_handler(self.session_id)
NativeLog.add_prompt_trace("One Test Done")
pass
def get_result(self):
if self.test_result is None:
NativeLog.add_trace_critical("Get result before test finish")
return self.test_result
pass
class SCIOT(TCActionBase.CommonTCActionBase):
def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH):
TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set,
timeout=timeout, log_path=log_path)
self.ap_list = []
self.test_result = dict.fromkeys(TEST_RESULT_CATEGORY)
self.test_result["AP"] = []
self.test_result["Phone"] = []
self.available_phone_list = []
self.pc_ip = "<pc_ip>"
self.udp_port = "<test_udp_port1>"
self.test_id = 0x00
self.resource_lock = threading.Lock()
self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name)
for i in range(1, len(cmd_set)):
if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "":
cmd_string = "self." + cmd_set[i][0]
exec cmd_string
for i in range(1, len(cmd_set)):
for j in range(len(cmd_set[i][1])):
if cmd_set[i][1][j] != "":
cmd_string = "self.ap_list.append(dict(zip(AP_PROPERTY, " + cmd_set[i][1][j] + ")))"
exec cmd_string
for ap in self.ap_list:
self.test_result["AP"].append(dict(zip(TEST_RESULT_PROPERTY, [ap["ssid"], 0, 0, 0, 0, 0])))
self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, "TEST_%s"
% (time.strftime("%y%m%d%H%M%S", time.localtime()))))
self.log_files = dict.fromkeys(LOG_FILES)
for _file in self.log_files:
self.log_files[_file] = os.path.join(self.log_folder,
(time.strftime("%H%M%S", time.localtime())) + _file)
pass
def update_phone_list(self, phone):
with self.resource_lock:
tmp = filter(lambda x: x["model"] == phone["model"], self.available_phone_list)
if len(tmp) == 1:
tmp[0]["ip"] = phone["ip"]
else:
self.available_phone_list.append(phone)
tmp = filter(lambda x: x["model"] == phone["model"], self.test_result["Phone"])
if len(tmp) == 0:
self.test_result["Phone"].append(dict(zip(TEST_RESULT_PROPERTY, [phone["model"], 0, 0, 0, 0, 0])))
pass
def remove_from_available_list(self, phone):
with self.resource_lock:
tmp = filter(lambda x: x["model"] == phone["model"], self.available_phone_list)
if len(tmp) == 1:
self.available_phone_list.remove(tmp[0])
pass
def allocate_test(self):
phone = None
test_count = 0xFFFF
with self.resource_lock:
for _phone in self.available_phone_list:
tmp = filter(lambda x: x["model"] == _phone["model"], self.test_result["Phone"])
if len(tmp) == 1:
_count = tmp[0]["total"]
if _count < test_count:
test_count = _count
phone = _phone
ap_list = self.ap_list[test_count % len(self.ap_list):]
return phone, ap_list
pass
def output_test_result(self, ap, phone, test_result):
result_str = "Time stamp" + ":\t" + NativeLog.generate_timestamp() + "\r\n"
result_str += "AP model" + ":\t" + str(ap["ssid"]) + "\r\n"
result_str += "AP encryption" + ":\t" + str(ap["encryption"]) + "\r\n"
result_str += "AP HT" + ":\t" + str(ap["ht"]) + "\r\n"
result_str += "AP ssid hidden" + ":\t" + str(ap["is_hidden"]) + "\r\n"
result_str += "Phone model" + ":\t" + str(phone["model"]) + "\r\n"
result_str += "Result" + ":\t" + str(test_result[0]) + "\r\n"
result_str += "Time1" + ":\t" + str(test_result[1]) + "\r\n"
result_str += "Time2" + ":\t" + str(test_result[2]) + "\r\n"
with self.resource_lock:
tmp = [filter(lambda x: x["model"] == ap["ssid"], self.test_result["AP"])[0],
filter(lambda x: x["model"] == phone["model"], self.test_result["Phone"])[0]]
if test_result[0] == "Succeed":
for _tmp in tmp:
_tmp["total"] += 1
_tmp["succeed"] += 1
_tmp["total time1"] += test_result[1]
_tmp["total time2"] += test_result[2]
pass
elif test_result[0] == "Disqualified":
for _tmp in tmp:
_tmp["total"] += 1
pass
else:
for _tmp in tmp:
_tmp["total"] += 1
_tmp["failed"] += 1
pass
tmp_result = dict(zip(TEST_RESULT_CATEGORY, ["", ""]))
for category in self.test_result:
for _result in self.test_result[category]:
for n in _result:
tmp_result[category] += str(n) + ":\t" + str(_result[n]) + "\r\n"
# update to log file
with open(self.log_files["by_ap.tmp"], "wb+") as f:
f.write(tmp_result["AP"])
with open(self.log_files["by_phone.tmp"], "wb+") as f:
f.write(tmp_result["Phone"])
with open(self.log_files["total.tmp"], "ab+") as f:
f.write(result_str)
if test_result[0] == "Failed":
with open(self.log_files["failed_item.tmp"], "ab+") as f:
f.write(result_str)
elif test_result[0] == "Disqualified":
with open(self.log_files["disqualified_item.tmp"], "ab+") as f:
f.write(result_str)
pass
def execute(self):
TCActionBase.TCActionBase.execute(self)
self.result_cntx.start()
pc_ip = CmdExecutorBasic.extract_parameter(self.pc_ip, self.test_env)
if isinstance(self.udp_port, int) is False:
udp_port = CmdExecutorBasic.extract_parameter(self.udp_port, self.test_env)
else:
udp_port = self.udp_port
server = UDPServer(pc_ip, udp_port, self.update_phone_list)
server.start()
while True:
phone, ap_list = self.allocate_test()
if phone is None:
time.sleep(5)
continue
for ap in ap_list:
NativeLog.add_prompt_trace("AP is %s, Phone is %s" % (ap["ssid"], phone["model"]))
session_id = make_session_id(phone["mac"], self.test_id)
self.test_id += 1
test_handler = TestHandler(session_id, ap, phone, server, self)
test_handler.start()
test_handler.join()
result = test_handler.get_result()
self.output_test_result(ap, phone, result)
# finally, execute done
server.join()
self.result_cntx.set_result("Succeed")
def result_check(self, port_name, data):
TCActionBase.CommonTCActionBase.result_check(self, port_name, data)
self.result_cntx.append_data(port_name, data)
def main():
pass
if __name__ == '__main__':
main()