mirror of https://github.com/axmolengine/axmol.git
380 lines
12 KiB
Python
380 lines
12 KiB
Python
|
#!/usr/bin/python
|
||
|
# create new project by cocos-console
|
||
|
# compile, deploy project and run
|
||
|
# perpose: for autotest cocos2d-console command.
|
||
|
# now support: mac- mac/ios/android
|
||
|
# will add: window-android,linux-android
|
||
|
|
||
|
import os
|
||
|
import subprocess
|
||
|
import sys
|
||
|
import json
|
||
|
import time
|
||
|
import socket
|
||
|
import threading
|
||
|
import smtplib
|
||
|
from email.mime.text import MIMEText
|
||
|
from os.path import join, getsize
|
||
|
|
||
|
# default console_param.
|
||
|
console_param = '[console run]'
|
||
|
# get param from commit.
|
||
|
if os.environ.has_key('payload'):
|
||
|
payload_str = os.environ['payload']
|
||
|
payload = json.loads(payload_str)
|
||
|
if payload.has_key('console'):
|
||
|
console_param = payload['console']
|
||
|
console_param = console_param[1:len(console_param)-1]
|
||
|
print 'console_param:',console_param
|
||
|
|
||
|
console_param_arr = console_param.split(' ')
|
||
|
|
||
|
# enum command type
|
||
|
class ENUM_PARAM:
|
||
|
new = 0
|
||
|
compile = 1
|
||
|
deploy = 2
|
||
|
run = 3
|
||
|
|
||
|
# partition different level
|
||
|
LEVEL_COCOS = {
|
||
|
ENUM_PARAM.new : 1,
|
||
|
ENUM_PARAM.compile : 2,
|
||
|
ENUM_PARAM.deploy : 4,
|
||
|
ENUM_PARAM.run : 8
|
||
|
}
|
||
|
|
||
|
# level's cocos command
|
||
|
COCOS_CMD = {
|
||
|
ENUM_PARAM.new:'new',
|
||
|
ENUM_PARAM.compile:'compile',
|
||
|
ENUM_PARAM.deploy:'deploy',
|
||
|
ENUM_PARAM.run:'run'
|
||
|
}
|
||
|
|
||
|
# set cocos_param for run different command
|
||
|
cocos_param = 0
|
||
|
for level in LEVEL_COCOS:
|
||
|
if console_param_arr.count(COCOS_CMD[level]):
|
||
|
cocos_param = cocos_param + LEVEL_COCOS[level]
|
||
|
if cocos_param < LEVEL_COCOS[ENUM_PARAM.new]:
|
||
|
cocos_param = LEVEL_COCOS[ENUM_PARAM.new]
|
||
|
print 'cocos_param:', cocos_param
|
||
|
|
||
|
# project types
|
||
|
project_types = ['cpp', 'lua']
|
||
|
# project suffix
|
||
|
PROJ_SUFFIX = 'Proj'
|
||
|
# different phone platform
|
||
|
phonePlats = ['mac','ios','android']
|
||
|
|
||
|
# need use console's position, perhaps should be set an env-param
|
||
|
cocos_console_dir = 'tools/cocos2d-console/bin/'
|
||
|
|
||
|
# now cocos2d-console suport different run on Platforms, e.g: only run android on win
|
||
|
runSupport = {
|
||
|
'darwin' : {'mac':1,'ios':1,'android':1},
|
||
|
'win' : {'mac':0,'ios':0,'android':1},
|
||
|
'linux' : {'mac':0,'ios':0,'android':1}
|
||
|
}
|
||
|
|
||
|
# get current running system
|
||
|
curPlat = sys.platform
|
||
|
if curPlat.find('linux') >= 0:
|
||
|
curPlat = 'linux'
|
||
|
elif curPlat.find('darwin') >= 0:
|
||
|
curPlat = 'darwin'
|
||
|
else:
|
||
|
curPlat = 'win'
|
||
|
print 'current platform is:', curPlat
|
||
|
|
||
|
# delete project.(will use different system command to delete.just mac now.)
|
||
|
def clean_project():
|
||
|
print 'delete older project.'
|
||
|
for proj in project_types:
|
||
|
cmd = 'rm -rf '+proj+PROJ_SUFFIX
|
||
|
os.system(cmd)
|
||
|
|
||
|
# file path.(for add console listen command.)
|
||
|
FILE_PATH = '/Classes/AppDelegate.cpp'
|
||
|
FILE_DIR = {
|
||
|
'cpp':'',
|
||
|
'lua':'/frameworks/runtime-src'
|
||
|
}
|
||
|
PARSE_WORD = 'director->setDisplayStats(true);'
|
||
|
CONSOLE_COMMAND = 'director->getConsole()->listenOnTCP(5678);'
|
||
|
|
||
|
# add console listenOnTCP to AppDelegate.cpp.
|
||
|
def addConsoleListenOnTCP(name):
|
||
|
filePath = name+PROJ_SUFFIX+FILE_DIR[name]+FILE_PATH
|
||
|
print 'filePath:',filePath
|
||
|
strCont = ''
|
||
|
if os.path.isfile(filePath):
|
||
|
file_object = open(filePath, 'r')
|
||
|
strLine = file_object.readline()
|
||
|
while strLine:
|
||
|
strCont = strCont + strLine
|
||
|
if strLine.find(PARSE_WORD) > -1:
|
||
|
print 'add console listenOnTCP command.'
|
||
|
strCont = strCont+'\n\t' + CONSOLE_COMMAND + '\n'
|
||
|
strLine = file_object.readline()
|
||
|
|
||
|
file_object.close()
|
||
|
file_object = open(filePath, 'w')
|
||
|
file_object.write(strCont)
|
||
|
file_object.close()
|
||
|
time.sleep(2)
|
||
|
else:
|
||
|
print 'file is not exist.'
|
||
|
|
||
|
# console result, for record result
|
||
|
console_result = 'the result of cocos-console-test is:\n\r'
|
||
|
|
||
|
# get current android devices count.
|
||
|
def getAndroidDevices():
|
||
|
cmd = 'adb devices'
|
||
|
info_devices = os.popen(cmd).read()
|
||
|
arrDevices = info_devices.split('\n')
|
||
|
del arrDevices[0]
|
||
|
count = 0
|
||
|
for device in arrDevices:
|
||
|
# e.g: emulator-5554 device, contains 'device', so, min length is len('device')
|
||
|
if len(device) > len('device') and (device.find('device') >= 0):
|
||
|
count += 1
|
||
|
return count
|
||
|
|
||
|
# close running app or exe by using console command.
|
||
|
IP_PHONE = {
|
||
|
'mac':'localhost',
|
||
|
'ios':'localhost'
|
||
|
}
|
||
|
PORT = 5678
|
||
|
|
||
|
def close_proj(proj, phone):
|
||
|
print 'close running project'
|
||
|
# connect socket
|
||
|
strClose = 'close ' + proj + ' on ' + phone
|
||
|
if IP_PHONE.has_key(phone):
|
||
|
soc = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||
|
print proj, phone, IP_PHONE[phone]
|
||
|
try:
|
||
|
soc.connect((IP_PHONE[phone], PORT))
|
||
|
cmd = 'director end\r\n'
|
||
|
print 'cmd close:', cmd
|
||
|
soc.send(cmd)
|
||
|
time.sleep(2)
|
||
|
strClose = strClose + ' success.'
|
||
|
except Exception, e:
|
||
|
print 'socket is not connect.'
|
||
|
strClose = strClose + ' failed.' + ' socket is not connect.'
|
||
|
else:
|
||
|
strClose = strClose + ' failed.' + ' no ' +phone+ ' type.'
|
||
|
time.sleep(2)
|
||
|
return strClose
|
||
|
|
||
|
# appendToResult
|
||
|
def appendToResult(content):
|
||
|
global console_result
|
||
|
console_result = console_result + content
|
||
|
|
||
|
info_of_close_app = {}
|
||
|
cur_test_name = ''
|
||
|
class myThread(threading.Thread):
|
||
|
def __init__(self,threadname):
|
||
|
threading.Thread.__init__(self,name=threadname)
|
||
|
def run(self):
|
||
|
run_name = self.getName()
|
||
|
print 'run_name:', run_name
|
||
|
if run_name == 'close':
|
||
|
while True:
|
||
|
soc = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||
|
try:
|
||
|
soc.connect(('localhost', PORT))
|
||
|
cmd_close = 'director end\r\n'
|
||
|
print 'cmd close:', cmd_close
|
||
|
soc.send(cmd_close)
|
||
|
time.sleep(2)
|
||
|
global cur_test_name
|
||
|
print 'cur_test_name:', cur_test_name
|
||
|
info_of_close_app[cur_test_name] = True
|
||
|
break
|
||
|
except Exception, e:
|
||
|
time.sleep(5)
|
||
|
|
||
|
# if any error
|
||
|
ANY_ERROR_IN_RUN = 0
|
||
|
# excute cocos command
|
||
|
def cocos_project(level):
|
||
|
global ANY_ERROR_IN_RUN
|
||
|
print 'will excute cocos_command: ', COCOS_CMD[level], level
|
||
|
appendToResult('will excute ' + COCOS_CMD[level] + ' command:'+"\n\r\t")
|
||
|
for proj in project_types:
|
||
|
print 'proj: ', proj
|
||
|
if level == ENUM_PARAM.new:
|
||
|
cmd = './'+cocos_console_dir+'cocos new -l '+proj+' '+proj+PROJ_SUFFIX
|
||
|
print proj,'cmd:',cmd
|
||
|
info_create = os.system(cmd) #call cmd on win is diff
|
||
|
if info_create == 0:
|
||
|
time.sleep(12)
|
||
|
addConsoleListenOnTCP(proj)
|
||
|
print 'create project',proj,' is:', not info_create
|
||
|
ANY_ERROR_IN_RUN = ANY_ERROR_IN_RUN + info_create
|
||
|
appendToResult(' '+cmd +': ' + str(not info_create) + ".\n\r\t")
|
||
|
else:
|
||
|
for phone in phonePlats:
|
||
|
print 'platform is: ', phone
|
||
|
cmd = './'+cocos_console_dir+'cocos '+COCOS_CMD[level]+' -s '+proj+PROJ_SUFFIX+' -p '+phone
|
||
|
print 'cmd:',cmd
|
||
|
info_cmd = ''
|
||
|
if level == ENUM_PARAM.compile:
|
||
|
if runSupport[curPlat][phone]:
|
||
|
info_cmd = os.system(cmd)
|
||
|
print 'info '+COCOS_CMD[level]+':', not info_cmd
|
||
|
appendToResult(' '+cmd +': ' + str(not info_cmd) + ".\n\r\t")
|
||
|
else:
|
||
|
if runSupport[curPlat][phone]:
|
||
|
print 'in desploy or run:', phone, getAndroidDevices()
|
||
|
if phone == 'android' and getAndroidDevices() == 0:
|
||
|
strInfo = 'no android device, please checkout the device is running ok.'
|
||
|
print strInfo
|
||
|
else:
|
||
|
if level == ENUM_PARAM.run:
|
||
|
global cur_test_name
|
||
|
cur_test_name = proj+','+phone
|
||
|
thread_close = myThread('close')
|
||
|
thread_close.start()
|
||
|
info_cmd = os.system(cmd)
|
||
|
time.sleep(5)
|
||
|
appendToResult(' '+cmd +': ' + str(not info_cmd) + ".\n\r\t")
|
||
|
|
||
|
# build and run according to params of provided.(lv_ignore: e.g:ignore new)
|
||
|
def build_run(lv_ignore):
|
||
|
print 'will build and run, in function build_run'
|
||
|
for level in LEVEL_COCOS:
|
||
|
print 'level:', level, cocos_param, LEVEL_COCOS[level]
|
||
|
if cocos_param >= LEVEL_COCOS[level] and level > lv_ignore:
|
||
|
if level == ENUM_PARAM.new:
|
||
|
clean_project()
|
||
|
cocos_project(level)
|
||
|
|
||
|
# android simulator name.
|
||
|
ANDROID_SIMULATOR_NAME = 'console-test'
|
||
|
# start android simulator if no android devices connected.
|
||
|
def start_android_simulator():
|
||
|
print 'in function start_android_simulator.'
|
||
|
if getAndroidDevices() > 0:
|
||
|
print 'already connected android device.'
|
||
|
return
|
||
|
if cocos_param >= LEVEL_COCOS[ENUM_PARAM.deploy]:
|
||
|
cmd_start = [ 'emulator -avd '+ANDROID_SIMULATOR_NAME ]
|
||
|
# print 'cmd_start:', cmd_start
|
||
|
# info_start = subprocess.Popen(cmd_start, stdin=subprocess.PIPE, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||
|
# print 'start an android simulator:', not info_start
|
||
|
|
||
|
# send email
|
||
|
EMAIL_KEYS={
|
||
|
0:'EMAIL_HOST',
|
||
|
1:'EMAIL_USER',
|
||
|
2:'EMAIL_PWD',
|
||
|
3:'EMAIL_POSTFIX',
|
||
|
4:'EMAIL_LIST',
|
||
|
5:'NEED_SEND_EMAIL'
|
||
|
}
|
||
|
|
||
|
OBJ_EMAIL_INFO = {}
|
||
|
print 'will get env info.'
|
||
|
for key in EMAIL_KEYS:
|
||
|
if os.environ.has_key(EMAIL_KEYS[key]):
|
||
|
OBJ_EMAIL_INFO[EMAIL_KEYS[key]] = os.environ[EMAIL_KEYS[key]]
|
||
|
if key == 4:
|
||
|
# string to list by ' ', for separate users.
|
||
|
OBJ_EMAIL_INFO[EMAIL_KEYS[4]] = OBJ_EMAIL_INFO[EMAIL_KEYS[4]].split(' ')
|
||
|
|
||
|
print 'will send email.', OBJ_EMAIL_INFO
|
||
|
def send_mail(to_list,sub,title,content):
|
||
|
mail_user = OBJ_EMAIL_INFO[ EMAIL_KEYS[1] ]
|
||
|
mail_postfix = OBJ_EMAIL_INFO[ EMAIL_KEYS[3] ]
|
||
|
mail_host = OBJ_EMAIL_INFO[ EMAIL_KEYS[0] ]
|
||
|
mail_pass = OBJ_EMAIL_INFO[ EMAIL_KEYS[2] ]
|
||
|
me = mail_user+"<"+mail_user+"@"+mail_postfix+">"
|
||
|
msg = MIMEText(content,_subtype='plain',_charset='gb2312')
|
||
|
msg['Subject'] = sub
|
||
|
msg['From'] = me
|
||
|
msg['To'] = " ".join(to_list)
|
||
|
print 'to users:', msg['To']
|
||
|
msg['Content'] = 'test'
|
||
|
try:
|
||
|
s = smtplib.SMTP()
|
||
|
s.connect(mail_host)
|
||
|
s.login(mail_user,mail_pass)
|
||
|
s.sendmail(me, to_list, str(msg))
|
||
|
print 'info:', me, to_list, str(msg)
|
||
|
s.close()
|
||
|
appendToResult( 'send email true:' + str(msg) )
|
||
|
return True
|
||
|
except Exception, e:
|
||
|
appendToResult( 'send email false:' + str(e) )
|
||
|
print str(e)
|
||
|
return False
|
||
|
|
||
|
def sendEmail(msg):
|
||
|
send_mail(OBJ_EMAIL_INFO[EMAIL_KEYS[4]], "cocos-console-test result", 'for error.', msg)
|
||
|
|
||
|
# get package size
|
||
|
def getdirsize(dir):
|
||
|
size = 0L
|
||
|
for root, dirs, files in os.walk(dir):
|
||
|
size += sum([getsize(join(root, name)) for name in files])
|
||
|
return size
|
||
|
APP_FILE_DIR = {
|
||
|
'cpp':'bin/debug/',
|
||
|
'lua':'runtime/'
|
||
|
}
|
||
|
APP_FILE_SUFFIX = {
|
||
|
'mac':'.app',
|
||
|
'ios':'.app',
|
||
|
'android':'-debug-unaligned.apk'
|
||
|
}
|
||
|
if os.environ.has_key('APP_FILE_SUFFIX'):
|
||
|
str_app_suffix = os.environ['APP_FILE_SUFFIX']
|
||
|
APP_FILE_SUFFIX = eval(str_app_suffix)
|
||
|
|
||
|
def getPackageSize():
|
||
|
for proj in project_types:
|
||
|
for phone in phonePlats:
|
||
|
# if runSupport[curPlat][phone]:
|
||
|
package_path = './'+proj+PROJ_SUFFIX+'/'+APP_FILE_DIR[proj]+phone+'/'+proj+PROJ_SUFFIX+APP_FILE_SUFFIX[phone]
|
||
|
print 'package_path', package_path
|
||
|
package_size = 0
|
||
|
if os.path.isfile(package_path):
|
||
|
package_size = os.path.getsize(package_path);
|
||
|
else:
|
||
|
package_size = getdirsize(package_path);
|
||
|
strSize = 'size of '+proj+PROJ_SUFFIX+' '+phone+' is:'+str(package_size/(1024))+'KB'+'\n\t'
|
||
|
print 'strSize:', strSize
|
||
|
appendToResult(strSize)
|
||
|
|
||
|
def main():
|
||
|
print 'in main:'
|
||
|
# start_android_simulator()
|
||
|
print 'will build_run:'
|
||
|
build_run(-1)
|
||
|
print 'ANY_ERROR_IN_RUN:', ANY_ERROR_IN_RUN
|
||
|
print 'end build run. and get package size.'
|
||
|
getPackageSize()
|
||
|
print 'will send email:'
|
||
|
print 'console_result:', console_result
|
||
|
if OBJ_EMAIL_INFO[ EMAIL_KEYS[5] ] or ANY_ERROR_IN_RUN:
|
||
|
sendEmail(console_result)
|
||
|
|
||
|
# -------------- main --------------
|
||
|
if __name__ == '__main__':
|
||
|
sys_ret = 0
|
||
|
try:
|
||
|
sys_ret = main()
|
||
|
except:
|
||
|
traceback.print_exc()
|
||
|
sys_ret = 1
|
||
|
finally:
|
||
|
sys.exit(sys_ret)
|