mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-02 22:51:14 +00:00
add auto generated test folder to components:
1. add test cases and related scripts 2. add CI config files read README.md for detail
This commit is contained in:
357
components/test/TestCaseScript/IOT/SCIOT.py
Executable file
357
components/test/TestCaseScript/IOT/SCIOT.py
Executable file
@@ -0,0 +1,357 @@
|
||||
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()
|
Reference in New Issue
Block a user