自动化测试

公司SCM组需要做个自动化的项目,目的是从gerrit到jenkins到release发布网站再到target测试的自动化流程,实现自动化测试发布的镜像版本,该过程是用python写的,代码如下:

#!/usr/bin/python
import os
import sys
import time
import errno
import serial
import paramiko
import hashlib
import random
import subprocess
import thread

from datetime import datetime
from xml.etree.ElementTree import ElementTree, Element, dump
from argparse import ArgumentParser

# constants
ENTER = chr(13)
ON = 1
OFF = 0

PLUG_1 = 0
PLUG_2 = 1
PLUG_3 = 2
PLUG_4 = 3
MAX_NUM_OF_ATTEMPTS = 5
UART_BAUD_RATE = 115200
DELAY_1 = 1
DELAY_2 = 2
DELAY_3 = 3
DELAY_4 = 4
DELAY_5 = 5
SERIAL = 0
PLUG_IDX = 1
RUNNING_DUT_DIR = '../running_duts'
TEST_RESULT_DIR = '../test_results'
PROFILE_COMMON = 'common'
PROFILE_TV = 'tv'
PROFILE_MOBILE = 'mobile'
ARCH_ARM = 'arm'
ARCH_ARM64 = 'arm64'
ARCH_X86 = 'x86'
DISP_X11 = 'x11'
DISP_WAYLAND = 'wayland'
SVR_PUBLIC = 'public'
SVR_RSA = 'rsa'
SVR_SPIN = 'spin'
CONN_UTP = 'eth0'
CONN_WLAN = 'wlan0'
# variables
cwd = '' 
test_dut_idx = None
ttyACM = ''
username = 'root'
password = 'tizen'


# Configure DUTs
#You can find the serial number of USB-Switch with command below.
# $ sudo clewarecontrol -l
usb_switch_serials = [ 
'650014',
]

#Please configure "number of dut" properly.
num_of_dut = 2

duts = [ 
{'name' : 'dut0',
'uart' : '/dev/ttyUSB0',
'dc_supl' : (usb_switch_serials[0],PLUG_1), 
'ip_addr' : '192.168.10.10'},

{'name' : 'dut1',
'uart' : '/dev/ttyUSB1',
'dc_supl' : (usb_switch_serials[0],PLUG_4), 
'ip_addr' : '192.168.10.11'},

{'name' : 'dut2',
'uart' : '/dev/ttyUSB2',
'dc_supl' : (usb_switch_serials[0],PLUG_3), 
'ip_addr' : '192.168.10.12'},

{'name' : 'dut3',
'uart' : '/dev/ttyUSB3',
'dc_supl' : (usb_switch_serials[0],PLUG_2), 
'ip_addr' : '192.168.10.13'},
]

# Configure Test
wait_time_for_boot = 16

boot_tcs = [ 
{'profile' : PROFILE_COMMON,
'arch_type': ARCH_ARM,
'disp_svr' : DISP_X11,
'testcases' : [
{'name' : 'dbus_is_running',
'grep_key' : 'dbus', 
'pattern' : '/usr/bin/dbus-daemon'},
{'name' : 'enlightenment_is_running',
'grep_key' : 'enlightenment', 
'pattern' : '/usr/bin/enlightenment'},
{'name' : 'Xorg_is_running',
'grep_key' : 'Xorg', 
'pattern' : '/usr/bin/Xorg'},
{'name' : 'bluetooth_is_running',
'grep_key' : 'bluetooth', 
'pattern' : '/lib/bluetooth/bluetoothd'},
{'name' : 'media-server_is_running',
'grep_key' : 'media-server', 
'pattern' : '/usr/bin/media-server'},
{'name' : 'security-server_is_running',
'grep_key' : 'security-server', 
'pattern' : '/usr/bin/security-server'},
{'name' : 'ofono_is_running',
'grep_key' : 'ofono', 
'pattern' : '/usr/sbin/ofonod'},
]
},
{'profile' : PROFILE_COMMON,
'arch_type' : ARCH_ARM,
'disp_svr' : DISP_WAYLAND, 
'testcases' : [
{'name' : 'dbus_is_running',
'grep_key' : 'dbus', 
'pattern' : '/usr/bin/dbus-daemon'},
{'name' : 'bluetooth_is_running',
'grep_key' : 'bluetooth', 
'pattern' : '/lib/bluetooth/bluetoothd'},
{'name' : 'media-server_is_running',
'grep_key' : 'media-server', 
'pattern' : '/usr/bin/media-server'},
{'name' : 'security-server_is_running',
'grep_key' : 'security-server', 
'pattern' : '/usr/bin/security-server'},
{'name' : 'ofono_is_running',
'grep_key' : 'ofono', 
'pattern' : '/usr/sbin/ofonod'},
]
},
{'profile' : PROFILE_TV, 
'arch_type': ARCH_ARM,
'disp_svr' : DISP_X11,
'testcases' : [
{'name' : 'dbus_is_running',
'grep_key' : 'dbus', 
'pattern' : '/usr/bin/dbus-daemon'},
{'name' : 'enlightenment_is_running',
'grep_key' : 'enlightenment', 
'pattern' : '/usr/bin/enlightenment'},
{'name' : 'Xorg_is_running',
'grep_key' : 'Xorg', 
'pattern' : '/usr/bin/Xorg'},
{'name' : 'bluetooth_is_running',
'grep_key' : 'bluetooth', 
'pattern' : '/lib/bluetooth/bluetoothd'},
{'name' : 'media-server_is_running',
'grep_key' : 'media-server', 
'pattern' : '/usr/bin/media-server'},
{'name' : 'security-server_is_running',
'grep_key' : 'security-server', 
'pattern' : '/usr/bin/security-server'},
{'name' : 'ofono_is_running',
'grep_key' : 'ofono', 
'pattern' : '/usr/sbin/ofonod'},
]
},
{'profile' : PROFILE_MOBILE,
'arch_type': ARCH_ARM,
'disp_svr' : DISP_X11,
'testcases' : [
{'name' : 'dbus_is_running',
'grep_key' : 'dbus', 
'pattern' : '/usr/bin/dbus-daemon'},
{'name' : 'enlightenment_is_running',
'grep_key' : 'enlightenment', 
'pattern' : '/usr/bin/enlightenment'},
{'name' : 'Xorg_is_running',
'grep_key' : 'Xorg', 
'pattern' : '/usr/bin/Xorg'},
{'name' : 'bluetooth_is_running',
'grep_key' : 'bluetooth', 
'pattern' : '/lib/bluetooth/bluetoothd'},
{'name' : 'media-server_is_running',
'grep_key' : 'media-server', 
'pattern' : '/usr/bin/media-server'},
{'name' : 'security-server_is_running',
'grep_key' : 'security-server', 
'pattern' : '/usr/bin/security-server'},
{'name' : 'ofono_is_running',
'grep_key' : 'ofono', 
'pattern' : '/usr/sbin/ofonod'},
]
},
]

# functions
def binary_url_factory(profile,arch_type,disp_type,svr_type):

http = 'http://'

public_url = 'download.tizen.org'
public_common_url = http+public_url\
+'/snapshots/tizen/common/latest/images/'
public_tv_url = http+public_url\
+'/snapshots/tizen/tv/latest/images/'
public_mobile_url = http+public_url\
+'/snapshots/tizen/mobile/latest/images/' 

if profile == PROFILE_COMMON and arch_type == ARCH_ARM \
and disp_type == DISP_X11 and svr_type == SVR_PUBLIC:

return (public_common_url\
+'arm-x11/common-boot-armv7l-odroidu3/',
public_common_url+'arm-x11/common-x11-3parts-armv7l-odroidu3/')

if profile == PROFILE_COMMON and arch_type == ARCH_ARM \
and disp_type == DISP_WAYLAND and svr_type == SVR_PUBLIC:

return (public_common_url\
+'arm-wayland/common-boot-armv7l-odroidu3/',\
public_common_url\
+'arm-wayland/common-wayland-3parts-armv7l-odroidu3/')

if profile == PROFILE_TV and arch_type == ARCH_ARM \
and disp_type == DISP_X11 and svr_type == SVR_PUBLIC:

return (None,
public_tv_url+'arm-x11/tv-x11-3parts-armv7l-odroidu3/')

if profile == PROFILE_MOBILE and arch_type == ARCH_ARM \
and disp_type == DISP_X11 and svr_type == SVR_PUBLIC:

return (None,
public_mobile_url+'arm-x11/mobile-x11-3parts-armv7l-odroidu3/')

else:
raise RuntimeError('Incorrect parameters..('\
+profile+','+arch_type+','+disp_type+','+svr_type+')')

def copy_latest_bins(profile,arch_type,disp_type,svr_type,build_id):
os.system('echo "Copy latest bins from download server..."')
boot_url,platform_url = binary_url_factory(profile,arch_type,\
disp_type,svr_type)

wget_cmd = "wget -r -np -A.tar.gz "
global cwd

hash_object = hashlib.sha1(build_id)
cwd = str(hash_object.hexdigest())

os.mkdir(cwd)
os.chdir(cwd)

if boot_url != None:
os.system(wget_cmd+boot_url)
if platform_url != None:
os.system(wget_cmd+platform_url)

os.system('find . -type f -name "*.tar.gz" -exec mv {} ./ \\;')
os.system('ls -alF | grep ^d | awk \'{print $NF}\' | xargs rm -rf')

def get_available_dut():
if not os.path.isdir(RUNNING_DUT_DIR):
os.mkdir(RUNNING_DUT_DIR)
for i in range(0,num_of_dut):
try: 
f = open(RUNNING_DUT_DIR+'/dut'+str(i),'r')
f.close()
except IOError:
f = open(RUNNING_DUT_DIR+'/dut'+str(i),'w')
f.close()
global test_dut_idx
test_dut_idx = i
break
else:
clean_test_bins()
raise RuntimeError("There's no DUT available!")
os.system('echo "DUT'+str(test_dut_idx)+' is available!"')
os.system('echo "Wait '+str(DELAY_3*test_dut_idx)+' seconds..."')
time.sleep(DELAY_3*test_dut_idx)
return duts[test_dut_idx]

def return_dut_resource():
global test_dut_idx
global ttyACM
os.system('rm -rf '+RUNNING_DUT_DIR+'/dut'+str(test_dut_idx))
os.system('rm -rf '+RUNNING_DUT_DIR+'/'+ttyACM)

def init_uart(uart_tty):
os.system('echo "Initialize UART"')
try:
ser = serial.Serial(uart_tty,UART_BAUD_RATE)
except:
common_exceptions()
raise RuntimeError("Can't open UART.")
return ser

def set_usb_power_switch(plug,on_off,delay):
serial = plug[SERIAL]
index = plug[PLUG_IDX]
if on_off == ON:
print('echo Turn on plug'+str(index+1)\
+', delay : '+str(delay))
else:
print('Turn off plug'+str(index+1)\
+', delay : '+str(delay))
os.system('clewarecontrol -d '\
+serial+' -c 1 -as '+str(index)+' '+str(on_off))
time.sleep(delay)

def start_download():
global ttyACM
os.system('echo "Download binaries..."')
time.sleep(DELAY_1+DELAY_5)
p1 = subprocess.Popen(['ls','/dev'],stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep','ttyACM'],\
stdin=p1.stdout,stdout=subprocess.PIPE).stdout
data = p2.read().strip().split()

for loop in data:
  try:
f = open(RUNNING_DUT_DIR+'/'+loop,'r')
f.close()
except IOError:
f = open(RUNNING_DUT_DIR+'/'+loop,'w')
f.close()
ttyACM = loop
break
else:
common_exceptions()
raise RuntimeError("Can't find ttyACM")

p2.close()
print(data)

result = os.system('lthor -d /dev/'+ttyACM+' *.tar.gz')
if result != 0:
common_exceptions()
raise RuntimeError("Failed to download binaries")
os.system('rm -rf '+RUNNING_DUT_DIR+'/'+ttyACM)

def print_boot_up_tizen():
os.system('echo "Boot up tizen........"')
for i in range(0,wait_time_for_boot):
os.system('echo "....Wait '\
+str(wait_time_for_boot-i)+' seconds ....."')
time.sleep(DELAY_1)
print ('\n')

def login_shell_uart():
os.system('echo "Log in shell (UART)..."')
ser.write(username+ENTER)
time.sleep(DELAY_1)
ser.write(password+ENTER)
time.sleep(DELAY_2)

def set_dut_config(connector_type,ip):
os.system('echo "Set DUT private IP('+ip+') to make a ssh connection"')
ser.write('ifconfig '+connector_type+' '+ip+ENTER)
time.sleep(DELAY_2)
ser.write('route add default gw 192.168.10.1'+ENTER)

ser.write('systemctl restart sshd.service'+ENTER)
time.sleep(DELAY_3)

def set_host_config():
os.system('echo "Set host private IP(192.168.10.1) '\
+'to make a ssh connection"')
os.system('ifconfig eth1 192.168.10.1')
time.sleep(DELAY_2)

def connect_to_dut_ssh(ip):
os.system('echo "Make a ssh connection now."')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for attempt in range(MAX_NUM_OF_ATTEMPTS):
try:
ssh.connect(ip,username=username,password=password)
except EnvironmentError as enverr:
if enverr.errno == errno.ECONNREFUSED:
time.sleep(DELAY_3)
else:
break
else:
common_exceptions()
raise RuntimeError\
("Maximum number of unsuccessful attempts reached")
return ssh

def clean_test_bins():
global cwd
os.chdir('../')
os.system('rm -rf ./'+cwd)

def common_exceptions():
set_usb_power_switch(test_dut['dc_supl'],OFF,1)
return_dut_resource()
clean_test_bins()

def check_command_result(test_name,grep_key,correct_pattern):
result = False
stdin,stdout,stderr = ssh.exec_command('ps -ax | grep '+grep_key)
for line in stdout:
if line.find(correct_pattern) >= 0:
result = True
break
print(test_name+' == '+str(result))
return result

def apply_indent(elem,level = 0):
indent = '\n' + level * ' '
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = indent + ' '
if not elem.tail or not elem.tail.strip():
elem.tail = indent
for elem in elem:
apply_indent(elem,level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = indent
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = indent

def check_boot_status(profile,arch_type,disp_svr,build_id):
global boot_tcs
cnt = 0
idx = None
for i in range(len(boot_tcs)):
if boot_tcs[i]["profile"] == profile \
and boot_tcs[i]["arch_type"] == arch_type \
and boot_tcs[i]["disp_svr"] == disp_svr:
idx = i
break
else:
common_exceptions()
raise RuntimeError("Can't find test cases for this profile") 

testsuite = Element("testsuite")
for tc in boot_tcs[idx]["testcases"]:
tc["result"] = check_command_result\
(tc["name"],tc["grep_key"],tc["pattern"])
testcase = Element("testcase")
testcase.attrib["name"]=tc["name"]
if tc["result"] == False:
cnt = cnt+1
testcase.attrib["passed"]=str(tc["result"])

testsuite.append(testcase)
testsuite.attrib["failures"] = str(cnt)
apply_indent(testsuite)
dump(testsuite)

if not os.path.isdir(TEST_RESULT_DIR):
os.mkdir(TEST_RESULT_DIR)

profile_dir = TEST_RESULT_DIR+'/'+profile

if not os.path.isdir(profile_dir):
os.mkdir(profile_dir)

result_dir = profile_dir+'/'+build_id
os.mkdir(result_dir)

ElementTree(testsuite).write(result_dir+'/result.xml')
if cnt > 0:
common_exceptions()
raise RuntimeError\
("Boot failed - Some mandatory processes doesn't exist")

def shutdown_dut():
stdin,stdout,stderr = ssh.exec_command('shutdown now')
time.sleep(DELAY_5)

def transfer_file_sftp(src,dest):
host = test_dut['ip_addr']
port = 22
transport = paramiko.Transport((host,port))

transport.connect(username = username,password = password)
sftp = paramiko.SFTPClient.from_transport(transport)

sftp.put(src,dest)

sftp.close()
def init_wireless_lan():

os.system('wget http://ftp2.halpanet.org/source/_dev/linux-firmware.git/rtlwifi/rtl8192cufw_TMSC.bin')

ser.write('echo sdb > /sys/class/usb_mode/usb0/funcs_fconf'+ENTER)
time.sleep(DELAY_1)
ser.write('echo 1 > /sys/class/usb_mode/usb0/enable'+ENTER)
time.sleep(DELAY_1)
ser.write('systemctl restart sdbd.service'+ENTER)
time.sleep(DELAY_2)

os.system('sdb root on')
os.system('sdb push ./rtl8192cufw_TMSC.bin /lib/firmwares/rtlwifi/')

time.sleep(DELAY_2)
ser.write("echo 'ctrl_interface=/var/run/wpa_supplicant' > ~/wpa.conf"+ENTER)
time.sleep(DELAY_1)
ser.write("echo 'update_config=1' >> ~/wpa.conf"+ENTER)
time.sleep(DELAY_1)

time.sleep(DELAY_2)
ser.write('wpa_supplicant -B -i wlan0 -c ~/wpa.conf'+ENTER)
time.sleep(DELAY_2)
ser.write('wpa_cli -iwlan0 scan'+ENTER)
time.sleep(DELAY_2)
ser.write('wpa_cli -iwlan0 scan_results'+ENTER)
time.sleep(DELAY_2)

def send_enter_via_serial(cnt):
for i in range(cnt):
ser.write(ENTER)
time.sleep(0.1)
ser.write('thordown'+ENTER)

if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument("profile",
help="Tizen profile what you want to test.(common,tv,mobile)",
type=str)
parser.add_argument("arch_type",
help="Architecture what you want to test.(arm,arm64)",
type=str)
parser.add_argument("disp_svr_type",
help="Display_server_type what you want to test.(x11,wayland)",
type=str)
parser.add_argument("download_svr_type",
help="The type of download server that save binaries what you want to test.(public,spin)",
type=str)
parser.add_argument("--buildid",
help="Jenkins buildid.(ex. 2015-01-01_01-00-00)",
type=str)

args = parser.parse_args()

profile = args.profile
arch_type = args.arch_type
disp_svr_type = args.disp_svr_type
download_svr_type = args.download_svr_type
jenkins_buildid = None

if args.buildid:
jenkins_buildid = args.buildid
else:
dt = datetime.now()
jenkins_buildid = dt.strftime('%Y-%m-%d_%H-%M-%S')

#Copy latest bins
copy_latest_bins(profile,arch_type,\
disp_svr_type,download_svr_type,jenkins_buildid)

#Find an available DUT
test_dut = get_available_dut();

#Initialize UART
ser = init_uart(test_dut['uart'])

thread.start_new_thread(send_enter_via_serial,(30,))

#Turn on Odroid U3
set_usb_power_switch(test_dut['dc_supl'],OFF,DELAY_1)
set_usb_power_switch(test_dut['dc_supl'],ON,DELAY_1)

#Start Download
start_download()

#Boot up tizen
print_boot_up_tizen()

#log in shell via UART
login_shell_uart()

#init wireless lan
#init_wireless_lan()

#Set DUT configuration (Odroid U3)
set_dut_config(CONN_UTP,test_dut['ip_addr'])
#set_dut_config(CONN_WLAN,test_dut['ip_addr'])

#Set host configuration
set_host_config()

#Make a ssh connection
ssh = connect_to_dut_ssh(test_dut['ip_addr'])

#Execute cmd (ps -ax | grep process_name)
check_boot_status(profile,arch_type,disp_svr_type,jenkins_buildid)

#shutdown DUT before turn off pwr
shutdown_dut()

#Close ssh connection
ssh.close()

#Close UART connection
ser.close()

#Turn off odroid U3
set_usb_power_switch(test_dut['dc_supl'],OFF,DELAY_1)

#Return DUT resource for next test
return_dut_resource()

#Clean test binaries
clean_test_bins()


你可能感兴趣的:(自动化测试)