#!/usr/bin/env python
import datetime
# -*- coding: UTF-8 -*-
import subprocess
import time
import sys
import os
import json
import requests
import logging
import HTTP_Requests as hr
import Response_Processing as rp
import Static_Functions as sf
import Excel_Operator as eo
import openpyxl
# try:
# from . import RSAEncrypt
# except:
import RSAEncrypt
class HTTP():
def __init__(self, ip=None, username=None, password=None):
self.logger = logging.getLogger(self.__class__.__name__)
# print(self.__class__.__name__())
self.ip=ip
self.username=username
self.password=password
self.stok = None
self.cookie = None
self.login_status = False
# dut对象记录所有测试结果的列表
self.test_results = []
# 创建dut对象的Excel工作簿对象
self.wb = openpyxl.Workbook()
# 添加一个工作表
self.ws = self.wb.active
self.ws.title = '测试结果'
self.headers = {"Host": "%s" % self.ip,
"Connection": "keep-alive",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Origin": "http://%s" % self.ip,
# "X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": "http://%s/webpages/login.html" % self.ip,
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.8",
"cookie": None
}
# 先将样机webserver状态设置为False
self.webserver_status = False
# 再调用http_request_init()检查样机webserver状态并登陆获取stok和cookie
self.http_request_init()
def _post_model_form_data(self, model_name=None, form_name=None, data=None):
# used by other function to post the whole data to the dut
self.logger.info(' start _post_model_form_data ')
submit_data = {
"module": model_name,
"form": form_name,
"data": data
}
self.logger.info('_post_model_form_data Post data is %s' % submit_data)
output = self.http_request_op(submit_data)
return output
def http_request_op(self, submit_data=None):
maxtrytime = 3
sleep_time = 1
connection_interval = 3
for item in range(1, maxtrytime):
try:
time.sleep(sleep_time)
if sleep_time != 1:
self.logger.debug('************** try to post data %s times **************' % item)
resp_dict = self._http_request_op(submit_data=submit_data)
return resp_dict
except ValueError as ex:
raise ValueError('Post data form error, web server code= %s' % ex)
except RuntimeError:
sleep_time += connection_interval
if item < maxtrytime:
continue
except requests.exceptions.ConnectionError:
sleep_time += connection_interval
if item < maxtrytime:
continue
else:
self.logger.error('Connection error')
except requests.exceptions.HTTPError:
sleep_time += connection_interval
if item < maxtrytime:
continue
else:
self.logger.error('HTTP error')
raise Exception(f'Post data error, submit_data is {submit_data}')
def _http_request_op(self, submit_data=None):
retry = 1
while not self.login_status:
self.http_request_init()
if self.login_status:
self.logger.info('Login dut success!')
break
self.logger.warning('Login failed, Retry to login, times=%s' % retry)
if retry >= 5:
raise RuntimeError("Login %s failed" % self.ip)
retry += 1
time.sleep(3)
# separators参数的作用是去掉,:后面的空格
raw_data = json.dumps(submit_data['data'], ensure_ascii=False, separators=(',', ':'))
form_raw = {"data": raw_data}
url = "http://%s/cgi-bin/luci/;stok=%s/admin/%s?form=%s" % (
self.ip, self.stok, submit_data['module'], submit_data['form'])
self.logger.debug("[+] url (%s)" % url)
try:
resp = requests.post(url=url, data=form_raw, headers=self.headers, timeout=30)
self.logger.debug("Post data function success")
#首先检查页面状态码是否为200
if resp.status_code == 200:
js = json.loads(resp.content)
time.sleep(0.2)
# 检查页面响应错误码是否为0
if str(js['error_code']) == '0':
self.logger.debug('Post data form success!')
return js
# 检查页面响应错误码不为0时,在发送一次请求
else:
self.logger.debug('*******************页面错误码不为0,再次尝试登陆****************************')
self.http_request_init()
time.sleep(3)
resp2 = requests.post(url=url, data=form_raw, headers=self.headers, timeout=30)
if resp2.status_code == 200:
js2 = json.loads(resp2.content)
time.sleep(0.2)
# 检查页面响应错误码是否为0
if str(js2['error_code']) == '0':
self.logger.debug('Post data form success!')
self.logger.debug('js2 is %s' % js2)
return js2
else:
raise RuntimeError('Web server return error, error code = %d' % js2['error_code'])
else:
raise RuntimeError('Web server return error, http code = %d' % resp2.status_code)
else:
raise RuntimeError('Web server return error, http code = %d' % resp.status_code)
except requests.exceptions.HTTPError as ex:
self.logger.error('Post data form failed! Http error:%s' % ex)
raise ex
except requests.exceptions.URLRequired as ex:
self.logger.error('Post data form failed! Url error:%s' % ex)
raise ex
except Exception as ex:
self.logger.error('Post data form failed! Unkonwn error:%s' % ex)
raise ex
def check_server_open(self):
headers_of_check_server_open = {"Host": "%s" % self.ip,
"Connection": "keep-alive",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Origin": "http://%s" % self.ip,
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": "http://%s/webpages/login.html" % self.ip,
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.8"
}
url_of_check_server_open = "http://%s/webpages/login.html" % self.ip
try:
resp = requests.get(url=url_of_check_server_open, headers=headers_of_check_server_open, timeout=30)
if resp.status_code == 200:
self.webserver_status = True
except Exception:
# 此处用于尝试重新发送请求检查webserver状态:
retry_times = 5
self.logger.debug("即将开始重新尝试,retry_times =" + str(retry_times))
while ((self.webserver_status == False) and (retry_times >= 1)):
try:
resp2 = requests.get(url=url_of_check_server_open, headers=headers_of_check_server_open, timeout=30)
if resp2.status_code == 200:
self.webserver_status = True
print('----------------------------------------重新连接webserver成功,确认样机webserver已开启')
except:
retry_times = retry_times - 1
print('----------------------------------------尝试第" + str(5 - retry_times) + "次连接样机失败,请检查样机状态')
time.sleep(0.7)
def http_request_init(self):
self.check_server_open() # webserver状态检查函数
print(f'----------------------------------------样机webserver状态为{self.webserver_status}')
if self.webserver_status == True:
# webserver状态检查成功,进入样机是否为出厂设置检查分支
self.check_status = '' # check_status来储存样机是否处于默认出厂状态
self.check_status = self.check_status_and_set_password()
self.check_status = self.check_status.lower() # 全小写避免样机差异,default代表处于默认出厂状态,modify代表已经被设置
# print('----------------------------------check_status=' + str(self.check_status))
# 其实是三个分支
if self.check_status == ('default'):
self.logger.info('----------------------------------------检查到样机的状态为默认的出厂设置')
self.mark_password = self.password # 用于记录用户设定的密码,然后在后面的set_new_password时传入
self.password = 'admin'
self.get_stok_cookie_by_password() # 包含了get uptime算密码的逻辑,但是算之前先把self.password设置为admin
self.set_new_password()
print('----------------------------------------出厂状态下,样机设置密码成功')
self.password = self.mark_password
self.get_stok_cookie_by_password() # 设定新密码后重新登录拿cookie和stok
self.login_status = True
# headers添加cookie
self.headers["cookie"] = self.cookie
print('----------------------------------------出厂状态下,样机登录成功')
if self.check_status == ('modify'):
self.get_stok_cookie_by_password()
self.login_status = True
# headers添加cookie
self.headers["cookie"] = self.cookie
print('----------------------------------------已修改密码状态下,样机登陆成功')
else:
print('----------------------------------------样机webserver未开启,请检查样机状态后重新实例化ERRouter_int类')
def check_status_and_set_password(self):
headers_of_check_status_and_set_password = {
"Host": "%s" % self.ip,
"Connection": "keep-alive",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Origin": "http://%s" % self.ip,
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": "http://%s/webpages/login.html" % self.ip,
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.8"
}
post_data_of_check_status_and_set_password = {"data": '{"method":"get"}'}
url_of_check_status_and_set_password = 'http://%s/cgi-bin/luci/;stok=/userconfig?form=cfg_save' % self.ip
resp = requests.post(url=url_of_check_status_and_set_password, data=post_data_of_check_status_and_set_password,
headers=headers_of_check_status_and_set_password)
time.sleep(0.5)
if resp.status_code == 200:
js = json.loads(resp.content)
time.sleep(0.2)
if str(js['error_code']) == '0':
return js['result']['config_status']
else:
print('----------------------------------------检查样机是否为出厂设置状态失败,error_code=%s' % str(js['error_code']))
time.sleep(0.2)
return '----------------------------------------获取dut状态失败,错误位于【error_code】,可能与post表单格式有关'
else:
print('----------------------------------------检查样机是否为出厂设置状态失败,http 响应 status_code=%s' % str(resp.status_code))
time.sleep(0.2)
return '----------------------------------------获取dut状态失败,错误位于【http 响应 status_code】,可能与url和headers有关'
def get_stok_cookie_by_password(self):
# get_stok_cookie_by_password()这个函数会自己去得到uptime然后计算加密,但是为了方便维护,把算密码和加密分开写
_uptime = self.get_uptime() # get_uptime()和get_encrypt_password()都会return相应值
time.sleep(2)
finaly_password = self.get_encrypt_password(up_time=_uptime)
post_data_of_get_stok_cookie_by_password = {
"data": '{"method":"login","params":{"username":"admin","password":"%s"}}' % finaly_password
}
headers_of_get_stok_cookie_by_password = {
"Host": "%s" % self.ip,
"Connection": "keep-alive",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Origin": "http://%s" % self.ip,
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": "http://%s/webpages/login.html" % self.ip,
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.8"
}
url_of_get_stok_cookie_by_password = "http://%s/cgi-bin/luci/;stok=/login?form=login" % self.ip
resp = requests.post(url=url_of_get_stok_cookie_by_password, data=post_data_of_get_stok_cookie_by_password,
headers=headers_of_get_stok_cookie_by_password)
try:
print('----------------------------------------正在获取cookie与stok......')
resp_dict = json.loads(resp.content)
self.stok = resp_dict['result']['stok']
# print(f'resp_dict is {resp_dict}')
self.cookie = resp.cookies
self.cookie = str(self.cookie)
# print(self.cookie)
self.cookie = self.cookie.split(' ')[1]
print("----------------------------------------得到登录的cookie与stok分别为")
print(f'----------------------------------------cookie:{self.cookie}')
print(f'----------------------------------------stok:{self.stok}\n')
return [self.cookie, self.stok]
except Exception as ex:
self.logger.warning("样机处于非出厂设置状态,用户名密码不正确,请重新检查用户名密码或恢复出厂设置后重新实例化ERRouter_int()类")
raise ex
def get_uptime(self):
headers_of_get_uptime = {
'Host': "%s" % self.ip,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Content-Length': '14',
'Origin': 'http://%s' % self.ip,
'Connection': 'keep-alive',
'Referer': 'http://%s/webpages/login.html' % self.ip,
'Pragma': 'no-cache',
'Cache-Control': 'no-cache'
}
url_of_get_uptime = 'http://%s/cgi-bin/luci/;stok=/locale?form=lang' % self.ip
post_data_of_get_uptime = {"operation": "read"}
req2 = requests.post(url=url_of_get_uptime, data=post_data_of_get_uptime, headers=headers_of_get_uptime)
st = req2.content
resp_dict = json.loads(st)
if 'uptime' in list(resp_dict['result'].keys()):
up_time = resp_dict['result']['uptime']
print('----------------------------------------获取到登录加密的up_time的值为: ' + str(up_time))
return str(up_time)
else:
print('----------------------------------------该机型登录机制未加时间戳' )
return None
def get_encrypt_password(self, up_time=None):
if up_time is not None:
_password_with_uptime = self.password + '_' + up_time
else:
_password_with_uptime = self.password
_encrypt_password = RSAEncrypt.Encrypt(_password_with_uptime)
# print('----------------------------------加密后密码为' + str(_encrypt_password))
return _encrypt_password
def set_new_password(self):
old_acc = 'admin'
old_pwd = '21dd905725bef0483f91a45c954f26dd0c6640329cf266f043d8a386855b22d2e056c' \
'0411a8f6246fcbb8e1804a5d433a92334b312a403616eb03ac17051a3f903f39c92a7' \
'e512fe5b8deac4e455fbe532cd919749a75ebf8e3ed0927cf5277c2d0304478a54efa' \
'aa1ecd05d1b760473e6bd06734075b6040998d77ee59d87bf'
new_acc = 'admin'
new_pwd = RSAEncrypt.Encrypt(self.mark_password)
post_data = \
{
"method": "set",
"params":
{
"old_acc": old_acc,
"old_pwd": old_pwd,
"new_acc": new_acc,
"new_pwd": new_pwd,
"cfm_pwd": new_pwd,
}
}
data_raw = json.dumps(post_data, separators=(',', ':'))
post_data_of_set_new_password = {"data": data_raw}
time.sleep(1)
url_of_set_new_password = 'http://%s/cgi-bin/luci/;stok=%s/admin/administration?form=accountfirstset' % (
self.ip, self.stok)
headers_of_set_new_password = {
"Host": "%s" % self.ip,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Content-Length': '14',
"Origin": "http://%s" % self.ip,
'Connection': 'keep-alive',
"Referer": "http://%s/webpages/login.html" % (self.ip),
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Cookie': '%s' % self.cookie
}
resp = requests.post(url=url_of_set_new_password, data=post_data_of_set_new_password,
headers=headers_of_set_new_password)
try:
js = json.loads(resp.content)
time.sleep(0.2)
if str(js['error_code']) == '0':
print('----------------------------------------设置密码' + self.mark_password + "成功")
except Exception:
self.logger.warning("设定密码时失败,请检查样机连接状态")
#*************************************************************************************************************************************************************************************************************************************
# *************************************************************************************************************************************************************************************************************************************
# *************************************************************************************************************************************************************************************************************************************
# *************************************************************************************************************************************************************************************************************************************
# *************************************************************************************************************************************************************************************************************************************
# def add_lan_network(self):
# post_data = {"method": "add", "params": {"index": 1, "old": "add",
# "new": {"default": "0", "name": "LAN2", "ipaddr": "192.168.2.1",
# "netmask": "255.255.255.0", "mode": "normal",
# "isolation": "off", "vlanid": "2", "igmp_snooping": "",
# "dhcp_mode": "dhcp_server", "enable": "on",
# "ipaddr_start": "192.168.2.100", "ipaddr_end": "192.168.2.199",
# "leasetime": "120", "gateway": "", "domain": "", "pri_dns": "",
# "snd_dns": "", "next_server": "", "option42": "",
# "option67": "", "option2": "", "option66": "", "option252": "",
# "option60": "", "option138": "", "option150": "",
# "option159": "", "option160": "", "option176": "",
# "option242": "", "relay_enable": "off", "dhcp_opts": []},
# "vlanid": "add"}}
# self.output = self._post_model_form_data(model_name='dhcps', form_name='lan', data=post_data)
# print(f'{self.output}')
def BasicTest_NetworkAttach(self):
self.network_mode_names = {
'prefer_lte': '4G优先',
'only_lte': '仅4G',
'only_wcdma': '仅3G'
# 后续添加5G相关内容
}
post_data = {"method":"get"}
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
self.LTE_Result = rp.parse_lte_status(resp)
Roaming = self.LTE_Result['数据漫游开关-data_roaming']
ISP = self.LTE_Result['当前运营商-current_operator']
self.preferred_network_type = self.LTE_Result['可用网络模式列表-available_network_modes']
self.Default_Network_Type = self.preferred_network_type[0]
self.Default_Profile_name = self.LTE_Result['配置文件名称-profile_name']
print(f'----------------------------------------以下是SIM1卡槽对应拨号信息,请确保SIM卡插在SIM1卡槽!!!\n{self.LTE_Result}')
print(f'----------------------------------------其中漫游状态:{Roaming},服务提供商:{ISP}')
print(f'----------------------------------------拨号成功,接下来是网络连通性测试')
sf.quick_internet_test()
print('\n\n\n')
def BasicTest_NetworkSwitch(self):
# 直接使用了BasicTest_NetworkAttach中的self.LTE_Result参数,所以再运行此用例前必须先运行BasicTest_NetworkAttach
print(f'----------------------------------------当前机型支持的网络模式有:{self.preferred_network_type}')
default_network_mode_name = self.network_mode_names[self.Default_Network_Type]
default_profile = self.Default_Profile_name
print(f'----------------------------------------默认网络模式为:{default_network_mode_name}')
sf.quick_internet_test()
print(f'----------------------------------------默认Profile为:{default_profile}')
for network_type in self.preferred_network_type:
if network_type != self.Default_Network_Type:
post_data = {"method":"set",
"params":{
"dial_setting":{
"profile_id":"8",
"profile_name":"China Unicom"
},
"failover_timeout":"100",
"network_mode":network_type,
"data_roaming":False
}
}
network_mode_name = self.network_mode_names[network_type]
print(f'----------------------------------------正在切换为{network_mode_name}模式')
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
time.sleep(5)
print(f'----------------------------------------切换成功,正在检查在{network_mode_name}模式下的网络可达性')
sf.quick_internet_test()
#完成遍历后将网络模式切换回原本模式
print(f'----------------------------------------BasicTest_NetworkSwitch完成!正在将网络模式切换为默认')
post_data = {"method": "set",
"params": {
"dial_setting": {
"profile_id": "8",
"profile_name": self.Default_Profile_name
},
"failover_timeout": "100",
"network_mode": self.Default_Network_Type,
"data_roaming": False
}
}
self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
print('\n\n\n')
def BasicTest_NetworkSearch(self):
self.start_search_time = time.time()
# 先开始搜索网络,再持续地检测搜索是否完成
post_data = {"method":"start"}
try:
resp = self._post_model_form_data(model_name='network_mobile', form_name='network_search', data=post_data)
if resp.get('error_code') != '0':
print("----------------------------------------网络搜索失败")
return False
except Exception as e:
print("----------------------------------------网络搜索失败 % s" % e)
#method修改为get,每秒一次持续检测是否搜索成功
max_wait_time = 30 # 最大等待60秒
poll_interval = 1 # 每秒检测一次
search_success = False
post_data = {"method": "get"}
while not search_success and time.time() - self.start_search_time < max_wait_time:
resp = self._post_model_form_data(model_name='network_mobile', form_name='network_search', data=post_data)
self.search_response = rp.parse_network_search_response(resp)
if self.search_response == None:
time.sleep(poll_interval)
else:
search_success = True
self.end_search_time = time.time()
if not search_success:
self.end_search_time = time.time()
print('----------------------------------------搜索网络超时,timeout=30s')
search_time = self.end_search_time - self.start_search_time
print(f'----------------------------------------搜索网络花费时间为{search_time}')
search_result = self.search_response['运营商列表-operator_list']
print(f'----------------------------------------搜索到的运营商列表如下:')
for operator_info in search_result:
operator = operator_info.get('alpha_short')
print(f'----------------------------------------{operator}')
print('\n\n\n')
def BasicTest_BandSelect(self):
self.start_search_time = time.time()
post_data = {"method":"start"}
#与搜索网络逻辑类似,先开始搜索Band,再持续检测搜索是否成功
try:
resp = self._post_model_form_data(model_name='network_mobile', form_name='band_search', data=post_data)
if resp.get('error_code') != '0':
print("----------------------------------------Band搜索失败")
return False
except Exception as e:
print("----------------------------------------Band搜索失败 % s" % e)
#method修改为get,每秒一次持续检测是否搜索成功
max_wait_time = 30 # 最大等待60秒
poll_interval = 1 # 每秒检测一次
search_success = False
post_data = {"method": "get"}
while not search_success and time.time() - self.start_search_time < max_wait_time:
resp = self._post_model_form_data(model_name='network_mobile', form_name='band_search', data=post_data)
self.search_response = rp.parse_band_search_response(resp)
if self.search_response == None:
time.sleep(poll_interval)
else:
search_success = True
self.end_search_time = time.time()
if not search_success:
self.end_search_time = time.time()
print('----------------------------------------搜索网络超时,timeout=30s')
search_time = self.end_search_time - self.start_search_time
print(f'----------------------------------------搜索网络花费时间为{search_time}')
print(f'----------------------------------------搜索到的Band列表如下:')
isp = self.search_response['运营商-isp']
search_result = self.search_response['Band列表-searched_list']
for band_info in search_result:
belong_to_isp = band_info.get('belong_to_isp')
band = band_info.get('band')
if belong_to_isp:
print(f'----------------------------------------Band:{band},属于运营商{isp}')
else:
print(f'----------------------------------------Band:{band},不属于任何运营商')
#搜索Band成功后,遍历每一个Band检查网络连通性
for band_info in search_result:
belong_to_isp = band_info.get('belong_to_isp')
band = band_info.get('band')
if belong_to_isp:
print(f'----------------------------------------正在选择Band: {band},属于运营商{isp},检测网络连通信中')
post_data = {"method":"set","params":{"auto":False,"selected_list":[{"band":band,"belong_to_isp":True}]}}
self._post_model_form_data(model_name='network_mobile', form_name='band_search', data=post_data)
time.sleep(60)
sf.quick_internet_test()
else:
print(f'----------------------------------------正在选择Band: {band},不属于任何运营商,检测网络连通信中')
post_data = {"method":"set","params":{"auto":False,"selected_list":[{"band":band,"belong_to_isp":False}]}}
self._post_model_form_data(model_name='network_mobile', form_name='band_search', data=post_data)
time.sleep(60)
sf.quick_internet_test()
#遍历完成后将Band模式切换回Auto,检查是否支持连接到2CA网络
print(f'----------------------------------------遍历Band完成!!!正在将Band模式切换回Auto,检查是否支持连接到2CA网络')
post_data = {"method":"set","params":{"auto":True}}
self._post_model_form_data(model_name='network_mobile', form_name='band_search', data=post_data)
time.sleep(60)
post_data = {"method": "get"}
resp = self._post_model_form_data(model_name='network_mobile', form_name='cellular_info', data=post_data)
systemstatus_ltewan = rp.parse_systemstatus_ltewan(resp)
print(f'----------------------------------------LTE WAN口信息如下\n{systemstatus_ltewan}')
auto_band_list = systemstatus_ltewan.get('频段-band')
band_num = len(auto_band_list)
if band_num == 1:
print(f'----------------------------------------Band数量为1,当前网络环境不支持2CA网络')
elif band_num > 1:
print(f'----------------------------------------Band数量 > 1,当前网络环境支持2CA网络')
def IPV6andIPv4_IPV4andIPV6(self):
post_data = {"method":"get"}
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
default_profile = rp.parse_lte_status(resp)
preferred_network_type = default_profile['可用网络模式列表-available_network_modes']
Default_Network_Type = preferred_network_type[0]
Default_Profile_name = default_profile['配置文件名称-profile_name']
print(f'----------------------------------------默认网络模式为:{self.network_mode_names[Default_Network_Type]}')
print(f'----------------------------------------默认Profile为:{Default_Profile_name}')
# 新建profile1,PDP type选择IPV4&IPV6,其他配置与默认profile保持一致才能保证拨号成功,新建完成后会自动将当前profile切换为新建profile;并且新建profile1成功后,需要记录下profile1的id,方便之后进行profile切换
post_data = {"method":"add",
"params":{
"profile_name":"profile1",
"pdp_type":"dual",
"apn_type":default_profile['APN类型-apn_type'],
"apn":default_profile['APN-apn'],
"username":"",
"password":"",
"authentication_type":default_profile['认证类型-authentication_type']
}
}
new_profile1_resp = self._post_model_form_data(model_name='network_mobile', form_name='isp_profile_list', data=post_data)
time.sleep(3)
self.profile1_id = rp.parse_profile_id(new_profile1_resp)
#
# 开启DUT LAN侧的IPv6,便于其给PC分配IPv6地址来测试IPv6可用性。
post_data = {"method":"set","params":{"index":0,"old":{"name":"LAN","vlanid":"1","proto":"slaac","slaac_type":"delegation","slaac_zone":"WAN7","slaac_prefixid":"0","slaac_dns":"auto","slaac_address":"2408:8469:ff90:70fc:21d:fff:fe00:2284/64","address":"2408:8469:ff90:70fc:21d:fff:fe00:2284/64","ra_status":"on","ra_priority":"medium","ra_valid_lifetime":"86400","ra_prefer_lifetime":"14400"},"new":{"vlanid":"1","proto":"slaac","slaac_type":"delegation","slaac_zone":"WAN7","slaac_addr_prefix":"","slaac_dns":"auto","slaac_address":"2408:8469:ff90:70fc:21d:fff:fe00:2284/64","ra_status":"on","ra_priority":"medium","ra_valid_lifetime":"86400","ra_prefer_lifetime":"14400"},"key":"key-2"}}
self._post_model_form_data(model_name='ipv6', form_name='lan_ipv6', data=post_data)
print(f'----------------------------------------正在默认网络模式{self.network_mode_names[Default_Network_Type]}下进行网络测试')
# sf.quick_internet_test()
# sf.quick_ipv6_test()
for network_type in preferred_network_type:
if network_type != Default_Network_Type:
post_data = {"method":"set",
"params":{
"dial_setting":{
"profile_id": self.profile1_id,
"profile_name":"profile1"
},
"failover_timeout":"100",
"network_mode":network_type,
"data_roaming":False
}
}
network_mode_name = self.network_mode_names[network_type]
print(f'----------------------------------------正在切换为{network_mode_name}模式')
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
time.sleep(20)
print(f'----------------------------------------切换成功,正在检查在{network_mode_name}模式下的网络可达性')
# sf.quick_internet_test()
# sf.quick_ipv6_test()
# 遍历网络模式完成,将网络模式切换为默认并将拨号profile切换为初始profile
print(f'----------------------------------------正在切换为默认网络模式:{Default_Network_Type}和默认profile:{Default_Profile_name}')
post_data = {"method":"set",
"params":{
"profile_id":default_profile['配置文件id-profile_id'],
"profile_name":default_profile['配置文件名称-profile_name'],
"pdp_type":default_profile['PDP类型-pdp_type'],
"apn_type":default_profile['APN类型-apn_type'],
"apn":default_profile['APN-apn'],
"username":"",
"password":"",
"authentication_type":default_profile['认证类型-authentication_type'],
}
}
self._post_model_form_data(model_name='network_mobile', form_name='isp_profile_list', data=post_data)
time.sleep(3)
post_data = {"method": "set",
"params": {
"dial_setting": {
"profile_id": default_profile['配置文件id-profile_id'],
"profile_name": default_profile['配置文件名称-profile_name']
},
"failover_timeout": "100",
"network_mode": Default_Network_Type,
"data_roaming": False
}
}
self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
time.sleep(3)
def IPV6andIPv4_IPv6Only(self):
post_data = {"method": "get"}
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
default_profile = rp.parse_lte_status(resp)
preferred_network_type = default_profile['可用网络模式列表-available_network_modes']
Default_Network_Type = preferred_network_type[0]
Default_Profile_name = default_profile['配置文件名称-profile_name']
print(f'----------------------------------------默认网络模式为:{self.network_mode_names[Default_Network_Type]}')
print(f'----------------------------------------默认Profile为:{Default_Profile_name}')
# 新建profile2,PDP type选择IPV6,其他配置与默认profile保持一致才能保证拨号成功,新建完成后会自动将当前profile切换为新建profile;并且新建profile2成功后,需要记录下profile2的id,方便之后进行profile切换
post_data = {"method": "add",
"params": {
"profile_name": "profile2",
"pdp_type": "ipv6",
"apn_type": default_profile['APN类型-apn_type'],
"apn": default_profile['APN-apn'],
"username": "",
"password": "",
"authentication_type": default_profile['认证类型-authentication_type']
}
}
new_profile2_resp = self._post_model_form_data(model_name='network_mobile', form_name='isp_profile_list', data=post_data)
time.sleep(3)
self.profile2_id = rp.parse_profile_id(new_profile2_resp)
# 在3.1测试中已经开启DUT LAN侧的IPv6给PC分配IPv6地址来测试IPv6可用性,故此处无需重复操作
# post_data = {"method": "set", "params": {"index": 0, "old": {"name": "LAN", "vlanid": "1", "proto": "slaac",
# "slaac_type": "delegation", "slaac_zone": "WAN7",
# "slaac_prefixid": "0", "slaac_dns": "auto",
# "slaac_address": "2408:8469:ff90:70fc:21d:fff:fe00:2284/64",
# "address": "2408:8469:ff90:70fc:21d:fff:fe00:2284/64",
# "ra_status": "on", "ra_priority": "medium",
# "ra_valid_lifetime": "86400",
# "ra_prefer_lifetime": "14400"},
# "new": {"vlanid": "1", "proto": "slaac", "slaac_type": "delegation",
# "slaac_zone": "WAN7", "slaac_addr_prefix": "",
# "slaac_dns": "auto",
# "slaac_address": "2408:8469:ff90:70fc:21d:fff:fe00:2284/64",
# "ra_status": "on", "ra_priority": "medium",
# "ra_valid_lifetime": "86400", "ra_prefer_lifetime": "14400"},
# "key": "key-2"}}
# self._post_model_form_data(model_name='ipv6', form_name='lan_ipv6', data=post_data)
print(
f'----------------------------------------正在默认网络模式{self.network_mode_names[Default_Network_Type]}下进行网络测试')
# sf.quick_internet_test()
# sf.quick_ipv6_test()
for network_type in preferred_network_type:
if network_type != Default_Network_Type:
post_data = {"method": "set",
"params": {
"dial_setting": {
"profile_id": self.profile2_id,
"profile_name": "profile2"
},
"failover_timeout": "100",
"network_mode": network_type,
"data_roaming": False
}
}
network_mode_name = self.network_mode_names[network_type]
print(f'----------------------------------------正在切换为{network_mode_name}模式')
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
time.sleep(20)
print(
f'----------------------------------------切换成功,正在检查在{network_mode_name}模式下的网络可达性')
# sf.quick_internet_test()
# sf.quick_ipv6_test()
# 遍历网络模式完成,将网络模式切换为默认并将拨号profile切换为初始profile
print(f'----------------------------------------正在切换为默认网络模式:{Default_Network_Type}和默认profile:{Default_Profile_name}')
post_data = {"method": "set",
"params": {
"profile_id": default_profile['配置文件id-profile_id'],
"profile_name": default_profile['配置文件名称-profile_name'],
"pdp_type": default_profile['PDP类型-pdp_type'],
"apn_type": default_profile['APN类型-apn_type'],
"apn": default_profile['APN-apn'],
"username": "",
"password": "",
"authentication_type": default_profile['认证类型-authentication_type'],
}
}
self._post_model_form_data(model_name='network_mobile', form_name='isp_profile_list', data=post_data)
time.sleep(3)
post_data = {"method": "set",
"params": {
"dial_setting": {
"profile_id": default_profile['配置文件id-profile_id'],
"profile_name": default_profile['配置文件名称-profile_name']
},
"failover_timeout": "100",
"network_mode": Default_Network_Type,
"data_roaming": False
}
}
self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
time.sleep(3)
def IPV6andIPv4_SwitchProfile(self):
post_data = {"method": "get"}
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
default_profile = rp.parse_lte_status(resp)
preferred_network_type = default_profile['可用网络模式列表-available_network_modes']
Default_Network_Type = preferred_network_type[0]
Default_Profile_name = default_profile['配置文件名称-profile_name']
print(f'----------------------------------------默认网络模式为:{self.network_mode_names[Default_Network_Type]}')
print(f'----------------------------------------默认Profile为:{Default_Profile_name}')
profile_sequence = [
(default_profile['配置文件名称-profile_name'], default_profile['配置文件id-profile_id']),
('Profile1', self.profile1_id),
('Profile2', self.profile2_id),
('Profile1', self.profile1_id),
(default_profile['配置文件名称-profile_name'], default_profile['配置文件id-profile_id']),
('Profile2', self.profile2_id),
(default_profile['配置文件名称-profile_name'], default_profile['配置文件id-profile_id'])
]
for profile_name , profile_id in profile_sequence:
print(f'----------------------------------------profile正在切换为:{profile_name},其id是{profile_id}')
post_data = {"method": "set",
"params": {
"profile_id": profile_id,
"profile_name": profile_name,
"pdp_type": default_profile['PDP类型-pdp_type'],
"apn_type": default_profile['APN类型-apn_type'],
"apn": default_profile['APN-apn'],
"username": "",
"password": "",
"authentication_type": default_profile['认证类型-authentication_type'],
}
}
self._post_model_form_data(model_name='network_mobile', form_name='isp_profile_list', data=post_data)
time.sleep(3)
post_data = {"method": "set",
"params": {
"dial_setting": {
"profile_id": profile_id,
"profile_name": profile_name
},
"failover_timeout": "100",
"network_mode": 'prefer_lte',
"data_roaming": False
}
}
self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
time.sleep(3)
print(f'----------------------------------------profile切换为:{profile_name}成功!正在检测网络环境')
def Performance_4GPerformance(self):
post_data = {"method": "get"}
resp = self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
default_profile = rp.parse_lte_status(resp)
# 先将网络模式设置为仅4G
post_data = {"method": "set",
"params": {
"dial_setting": {
"profile_id": default_profile['配置文件id-profile_id'],
"profile_name": default_profile['配置文件名称-profile_name']
},
"failover_timeout": "100",
"network_mode": 'only_lte',
"data_roaming": False
}
}
self._post_model_form_data(model_name='network_mobile', form_name='setting', data=post_data)
time.sleep(3)
speedtest_test_result = sf.basic_speedtest()
self.test_results.append({
'case_name': 'Performance_4GPerformance',
'result': 'Ref',
'remarks': speedtest_test_result
})
def export_results_to_excel(self, filename=None):
"""导出测试结果到Excel"""
if filename is None:
filename = f"test_results_{time.time()}.xlsx"
exporter = eo.TestResultExporter(filename)
exporter.export_from_dut(self)
return filename