SomkePretreatment.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. # -*- coding:utf-8 -*-
  2. import os
  3. import sys
  4. import time
  5. import re
  6. # import getopt
  7. import json
  8. import chardet
  9. import datetime
  10. import hashlib # md5验证;
  11. import subprocess
  12. import urllib2
  13. import threading
  14. from ssat_sdk.basessh2 import baseSSH2
  15. from ssat_sdk.tv_operator import TvOperator
  16. # 导入测试精灵;
  17. from ssat_sdk.device_manage.testWizardClient import TestWizardClient
  18. from SATClient import SATClient
  19. # 导入http相关库:python2.x中2个一起用,python3.x合并成一个urllib
  20. import urllib
  21. import urllib2
  22. class SomkePretreatment:
  23. def __init__(self, taskId=None):
  24. self.taskId = taskId
  25. if self.taskId is None:
  26. self.__parseCommandLine()
  27. # 任务信息;
  28. self.taskInfo = {}
  29. self.ota_local_name = 'usb_ota.zip'
  30. # 上传升级包的位置;
  31. self.updateZip = ' /storage/905A-30AB/usb_ota.zip' # 弃用:改由usb切换器切换;
  32. # ota路径;
  33. self.ota_server_path = "/home/RT2841_2851_dailybuild/DailyBuild_RT2841_%s/" % str(time.strftime("%m%d"))
  34. # ota名称;
  35. self.ota_server_name = 'signed-ota_rt2841_update.zip'
  36. # apk安装ota的命令;
  37. self.installCmd = ' shell am start -n com.apps.ota/.ui.MainActivity'
  38. # ssh2;
  39. self.ssh2 = baseSSH2()
  40. # 遥控器;
  41. self.redhat3 = TvOperator()
  42. # 获取任务信息;
  43. self.getTaskInfo()
  44. '''
  45. 函数:解析命令行参数
  46. 参数:
  47. 返回:
  48. 注意:argv[0]属于程序本身名称
  49. '''
  50. def __parseCommandLine(self):
  51. if sys.argv.__len__() > 1:
  52. try:
  53. args = json.loads(sys.argv[1].replace("'", '"'))
  54. # 解析出taskId;
  55. if "TaskId" in args:
  56. self.taskId = args["TaskId"]
  57. print "TaskId=", self.taskId
  58. except Exception, e:
  59. print u"解析json失败:%s" % sys.argv[1]
  60. # 不使用重定向;
  61. def __cmdExecute2(self, cmd):
  62. # 定义文件名称;
  63. file_name = str(time.time())
  64. # 输出到文件中;
  65. cmd = cmd + ' >> ' + file_name
  66. print u'执行cmd:', cmd
  67. proc = subprocess.Popen(cmd, shell=True)
  68. # 等待完成;
  69. proc.wait()
  70. # 读取文件内容;
  71. data = ''
  72. with open(file_name, mode="rb") as f:
  73. data = f.read()
  74. os.remove(file_name)
  75. print u"cmd结果:", data
  76. return data
  77. def __cmdExecute(self, cmd):
  78. print u'执行cmd:', cmd
  79. proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  80. # 等待完成;
  81. stdout,stderr = proc.communicate()
  82. if proc.returncode == 0:
  83. print u'执行成功'
  84. # 返回执行结果;
  85. # print u"__cmdExecute结果:%s" % stdout
  86. return stdout
  87. def __adbConnect(self):
  88. try:
  89. # 启用adb的root权限;
  90. cmd = "adb connect " + self.taskInfo["deviceSerial"]
  91. proc = self.__cmdExecute(cmd)
  92. if proc.find("connected to " + self.taskInfo["deviceSerial"] + ":5555") < 0 and proc.find(
  93. "already connected to " + self.taskInfo["deviceSerial"] + ":5555") < 0:
  94. return False
  95. print "adb connect success"
  96. return True
  97. except Exception, e:
  98. print 'adb connect error:', e
  99. return False
  100. def adbCheck(self):
  101. try:
  102. cmd = "adb devices"
  103. proc = self.__cmdExecute(cmd)
  104. if proc.find(self.taskInfo["deviceSerial"] + ":5555\tdevice\r\n") > -1:
  105. print "adb connected"
  106. return True
  107. print "adb didn't connected"
  108. return False
  109. except Exception,e:
  110. return False
  111. def __adbDisconnect(self):
  112. # 启用adb的root权限;
  113. cmd = "adb disconnect " + self.taskInfo["deviceSerial"]
  114. proc = self.__cmdExecute(cmd)
  115. if proc.find("disconnected " + self.taskInfo["deviceSerial"]) < 0 and proc.find(
  116. "error: no such device '" + self.taskInfo["deviceSerial"] + ":5555'") < 0:
  117. return False
  118. print "adb disConnect success"
  119. return True
  120. def __adbRoot(self):
  121. try:
  122. # 启用adb的root权限;
  123. cmd = "adb -s " + self.taskInfo["deviceSerial"] + " root"
  124. proc = self.__cmdExecute(cmd)
  125. if proc.find("adbd is already running as root") < 0 and proc.find(
  126. "restarting adbd as root") < 0 and proc != '':
  127. return False
  128. print "adb root success"
  129. return True
  130. except Exception, e:
  131. print 'adb root error:', e
  132. return False
  133. def __adbRemount(self):
  134. # 启用adb的root权限;
  135. cmd = "adb -s " + self.taskInfo["deviceSerial"] + " remount /data"
  136. proc = self.__cmdExecute(cmd)
  137. if proc.find("adbd is already running as root") < 0 and proc.find("restarting adbd as root") < 0 and proc != '':
  138. return False
  139. print "adb root success"
  140. return True
  141. def __adbInstallApk(self, apk_path):
  142. if os.path.exists(apk_path):
  143. cmd = 'adb -s ' + self.taskInfo['deviceSerial'] + ' install -r -t ' + apk_path
  144. proc = self.__cmdExecute(cmd)
  145. if (proc.find('Success') >= 0):
  146. print "install ota_install.apk success"
  147. # 启动app;
  148. cmd = 'adb -s ' + self.taskInfo[
  149. 'deviceSerial'] + r' shell am start -n com.apps.ota.myapplication/.DeleteZipActivity'
  150. proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()[
  151. 0]
  152. return True
  153. return False
  154. def __adbUninstallApk(self, apk_name):
  155. return False
  156. def __requestTaskInfo(self):
  157. # 请求服务器;
  158. data = {'data':{"taskId" : self.taskId}}
  159. msg = {'requestMsg' : json.dumps(data)}
  160. try:
  161. post_data = urllib.urlencode(msg)
  162. url = 'http://10.126.16.60:8580/btc_task_se/ajaxExternalInteractiveManage!getSmokeTaskInfo.action'
  163. response = urllib2.urlopen(url, post_data)
  164. data = response.read().decode("utf-8")
  165. res = json.loads(data)
  166. if str(res['responseMsg']['code']) == '00':
  167. self.taskInfo = {
  168. "host": res['responseMsg']['data']['compileInfo']['serverName'],
  169. "hostPort": res['responseMsg']['data']['compileInfo']['serverPort'],
  170. "hostUser": res['responseMsg']['data']['compileInfo']['serverAccount'],
  171. "hostPwd": res['responseMsg']['data']['compileInfo']['serverPassword'],
  172. "deviceSerial": res['responseMsg']['data']['deviceId']
  173. }
  174. # 服务器路径;
  175. ser_path = res['responseMsg']['data']['compileInfo']['resultPath']
  176. self.ota_server_path = "%sDailyBuild_RT2841_%s/" % (ser_path, str(time.strftime("%m%d")))
  177. print u"taskInfo",self.taskInfo
  178. print u"ser_path",ser_path
  179. print u"ota_server_path", self.ota_server_path
  180. # 返回结果;
  181. return True
  182. except Exception, e:
  183. print u"获取任务信息失败",e
  184. # 默认返回False
  185. return False
  186. # 获取Windows下的USB路径(多个时默认使用第一个识别的)
  187. def getWindowsUsbPath(self):
  188. disks = self.__cmdExecute("wmic logicaldisk get deviceid, description")
  189. charsInfo = chardet.detect(disks)
  190. print u'当前编码信息=',charsInfo
  191. if charsInfo['encoding'] == "GB2312":
  192. disks = disks.decode("GB2312").encode('utf-8')
  193. elif charsInfo['encoding'] == "UTF-16":
  194. disks = disks.decode("utf-16").encode('utf-8').decode('utf-8-sig')
  195. disks = disks.split('\r\n')
  196. for disk in disks:
  197. if u'可移动磁盘' in disk:
  198. return re.search(r'\w:', disk).group()
  199. return None
  200. # 适用于Android 9以上
  201. def getTVUsbPath(self):
  202. # 获取storage下的目录;
  203. sdcards = self.__cmdExecute('adb shell ls storage')
  204. if sdcards.__len__() == 0:
  205. return None
  206. # 按换行符分隔;
  207. sdcards = sdcards.split('\r\n')
  208. # 要过滤的目录;
  209. sdcards = list(set(sdcards) ^ set(['emulated','self','']))
  210. if sdcards.__len__() == 0:
  211. return None
  212. # 返回第一个元素;
  213. return sdcards[0]
  214. def __AdbPush(self, file, tvdir):
  215. data = self.__cmdExecute('adb push %s %s\n'%(file, tvdir))
  216. str = '%s: 1 file pushed.'%file
  217. if data.find(str) < 0 or data.find("[100%%] %s" % tvdir) < 0:
  218. return False
  219. print u'push %s 成功'%file
  220. return True
  221. def AdbPush(self, file, tvdir, trys=3):
  222. if trys <= 0:
  223. trys = 1
  224. while trys > 0:
  225. trys = trys - 1
  226. if self.__AdbPush(file, tvdir) is True:
  227. return True
  228. return False
  229. def __AdbInstallAPK(self, file):
  230. data = self.__cmdExecute('adb install -r %s'%file)
  231. if data != "Success\r\n":
  232. return False
  233. return True
  234. def AdbInstallAPK(self, file, trys=3):
  235. if trys <= 0:
  236. trys = 1
  237. while trys > 0:
  238. trys = trys - 1
  239. if self.__AdbInstallAPK(file) is True:
  240. return True
  241. return False
  242. # adb shell pm list packages | findstr /x "<package name>"
  243. def IsAPKInstalled(self, apk_name):
  244. apk_name = 'package:%s'%apk_name
  245. data = self.__cmdExecute('adb shell pm list packages | findstr /x "%s"'%apk_name)
  246. return True if data.lower() == apk_name.lower() else False
  247. '''
  248. 函数:获取任务信息;
  249. 参数:
  250. 返回:
  251. '''
  252. def getTaskInfo(self):
  253. # 任务信息;
  254. if self.taskId is None or self.taskInfo.__len__() == 0: #测试开关;
  255. self.taskId = 5520
  256. self.taskInfo = {
  257. "host": "10.201.251.254",
  258. "hostPort": 22,
  259. "hostUser": "wjf",
  260. "hostPwd": "wjf2019",
  261. "deviceSerial": '192.168.18.210'
  262. }
  263. # 请求服务器;
  264. if self.__requestTaskInfo() is False:
  265. return
  266. # 初始化ssh2;
  267. self.ssh2.init_ssh2(self.taskInfo['hostUser'], self.taskInfo['hostPwd'], self.taskInfo['host'], self.taskInfo['hostPort'])
  268. self.redhat3.sendKey('home',2)
  269. self.redhat3.sendKey('home',2)
  270. self.__adbConnect()
  271. '''
  272. 函数:下载apk
  273. 参数:
  274. 返回:
  275. '''
  276. def downloadApk(self, apk_url, save_path):
  277. pass
  278. '''
  279. 函数:apk是否已在本地;
  280. 参数:
  281. 返回:
  282. '''
  283. def isApkExist(self, apk_md5, apk_path):
  284. local_md5 = ''
  285. file_data = []
  286. md5_local = hashlib.md5()
  287. if os.path.exists(apk_path):
  288. with open(apk_path, mode='rb') as f:
  289. while True:
  290. data = f.read(8192)
  291. if not data:
  292. break
  293. md5_local.update(data)
  294. local_md5 = md5_local.hexdigest()
  295. print u"本地MD5=", local_md5
  296. return True if apk_md5 == local_md5 else False
  297. def installApk(self, apk_path):
  298. # 先连接才能root;
  299. if self.__adbConnect() is False:
  300. return False
  301. # 安装apk
  302. if self.__adbInstallApk(apk_path) is False:
  303. return False
  304. # 断开adb连接;
  305. # self.__adbDisconnect()
  306. return True
  307. def unInstallApk(self, apk_name):
  308. # 先连接才能root;
  309. if self.__adbConnect() is False:
  310. return
  311. # 启用adb的root权限;
  312. if self.__adbRoot() is False:
  313. return
  314. if self.__adbUninstallApk(apk_name) is False:
  315. return
  316. def parseOTAImageName(self):
  317. pass
  318. def isOTAImageOnServer(self):
  319. cmd = "ls %s" % self.ota_server_path
  320. status, data = self.ssh2.execute_cmd(cmd)
  321. if status is True and data.find(self.ota_server_name) >= 0:
  322. return True
  323. return False
  324. def downloadOTAImage(self):
  325. print u"downloadOTAImage start"
  326. sftp_path = self.ota_server_path + self.ota_server_name
  327. usbSwitch = TestWizardClient()
  328. '''
  329. 尝试5次切换U盘
  330. '''
  331. tryCount = 5
  332. switchRet = False
  333. while tryCount > 0:
  334. if usbSwitch.sendUsbSwitch(1) is True:
  335. switchRet = True
  336. break
  337. time.sleep(2)
  338. tryCount = tryCount - 1
  339. if switchRet is False:
  340. print u"切换U盘到电脑失败"
  341. return False
  342. time.sleep(5) # 等待Windows识别U盘。
  343. usbPath = self.getWindowsUsbPath()
  344. if usbPath is None:
  345. print u"获取U盘盘符失败"
  346. return False
  347. local_path = usbPath + "\\" + self.ota_local_name
  348. return self.ssh2.sftp_download_md5(sftp_path, local_path)
  349. def isOTAImageOnLocal(self):
  350. pass
  351. def uploadOTAImage2TV(self):
  352. # 必须先root才能push;
  353. if self.__adbRoot() is False:
  354. print u"adb root失败"
  355. return False
  356. '''
  357. 尝试5次切换U盘
  358. '''
  359. tryCount = 5
  360. switchRet = False
  361. usbSwitch = TestWizardClient()
  362. while tryCount > 0:
  363. if usbSwitch.sendUsbSwitch(0) is True:
  364. switchRet = True
  365. break
  366. time.sleep(2)
  367. tryCount = tryCount - 1
  368. if switchRet is False:
  369. print u"切换U盘到TV失败"
  370. return False
  371. return True
  372. def reomveOTAImageOnTV(self):
  373. pass
  374. def installOTAImage(self):
  375. print u"installOTAImage start"
  376. try:
  377. self.redhat3.sendKey("home")
  378. time.sleep(1.5)
  379. cmd = 'adb -s ' + self.taskInfo['deviceSerial'] + self.installCmd
  380. proc = self.__cmdExecute(cmd)
  381. print proc
  382. self.redhat3.sendKey("down")
  383. time.sleep(1.5)
  384. self.redhat3.sendKey("ok")
  385. time.sleep(1.5)
  386. self.redhat3.sendKey("ok")
  387. # 等待60秒启动安装;
  388. time.sleep(60)
  389. except Exception, e:
  390. print u'安装失败=', e
  391. def checkOTAInstall(self):
  392. try:
  393. # 先connect,再devices
  394. cmd = 'adb connect ' + self.taskInfo['deviceSerial']
  395. proc = self.__cmdExecute(cmd)
  396. if proc.find('connected') >= 0:
  397. cmd = 'adb devices'
  398. proc = self.__cmdExecute(cmd)
  399. if proc.find(self.taskInfo['deviceSerial'] + ':5555\tdevice') >= 0:
  400. print "device connect success"
  401. print "OTA update success!"
  402. return True
  403. time.sleep(10)
  404. return False
  405. except Exception, e:
  406. print u'检测失败=', e
  407. def initAtx(self):
  408. # 重启后,重连adb;
  409. client = SATClient()
  410. if client.send_add_device(self.taskInfo['deviceSerial']) is False:
  411. print u"重连adb设备失败",self.taskInfo['deviceSerial']
  412. self.__adbConnect()
  413. # 等待10;
  414. print "等待30秒,让TV完全启动。"
  415. time.sleep(30)
  416. # os.system(r'D:\SAT\tools\atx-init\atx-init.bat')
  417. # push 文件;
  418. if self.AdbPush(r'D:\SAT\tools\atx-init\atx-agent', '/data/local/tmp') is False:
  419. return False
  420. if self.AdbPush(r'D:\SAT\tools\atx-init\minicap', '/data/local/tmp') is False:
  421. return False
  422. if self.AdbPush(r'D:\SAT\tools\atx-init\minicap.so', '/data/local/tmp') is False:
  423. return False
  424. if self.AdbPush(r'D:\SAT\tools\atx-init\minitouch', '/data/local/tmp') is False:
  425. return False
  426. self.__cmdExecute('adb shell chmod 755 /data/local/tmp/atx-agent')
  427. self.__cmdExecute('adb shell chmod 755 /data/local/tmp/minicap')
  428. self.__cmdExecute('adb shell chmod 755 /data/local/tmp/minicap.so')
  429. self.__cmdExecute('adb shell chmod 755 /data/local/tmp/minitouch')
  430. if self.IsAPKInstalled('com.github.uiautomator') is True:
  431. print u'卸载:uiautomator'
  432. self.__cmdExecute('adb uninstall com.github.uiautomator')
  433. else:
  434. print 'uiautomator false'
  435. if self.IsAPKInstalled('com.github.uiautomator.test') is True:
  436. print u'卸载:uiautomator.test'
  437. self.__cmdExecute('adb uninstall com.github.uiautomator.test')
  438. else:
  439. print 'uiautomator.test false'
  440. # 安装apk
  441. if self.AdbInstallAPK(r'D:\SAT\tools\atx-init\app-uiautomator.apk') is False:
  442. return False
  443. if self.AdbInstallAPK(r'D:\SAT\tools\atx-init\app-uiautomator-test.apk') is False:
  444. return False
  445. if self.AdbInstallAPK(r'D:\SAT\tools\atx-init\exoplayer-demo-2.8.4.apk') is False:
  446. return False
  447. def turnOnTV(self):
  448. tryCount = 5
  449. while tryCount > 0:
  450. if self.adbCheck() is True:
  451. print u'开机成功'
  452. return True
  453. # 按下Power键;
  454. self.redhat3.sendKey("POWER")
  455. # 等待60秒;
  456. time.sleep(60)
  457. tryCount = tryCount -1
  458. # 尝试连接;
  459. # self.__adbConnect()
  460. print u'开机失败'
  461. return False
  462. if __name__ == "__main__":
  463. smp = SomkePretreatment()
  464. smp.getTaskInfo()
  465. smp.adbCheck()
  466. # print smp.getWindowsUsbPath()
  467. # if smp.isOTAImageOnServer():
  468. # if smp.downloadOTAImage():
  469. # print u'下载完成'
  470. # else:
  471. # print u'下载失败'
  472. # smp.taskInfo = {"deviceSerial":'192.168.1.101'}
  473. # #if smp.installApk('F:\SAT\SAT_Runner\ota_apk\RT2841\ota_install.apk') is True:
  474. # #if smp.uploadOTAImage2TV('F:\signed-ota_rt2841_update.zip') is True:
  475. # smp.installOTAImage()
  476. # time.sleep(30)
  477. # upStatus = False
  478. # for i in range(30):
  479. # if smp.checkOTAInstall() is True:
  480. # upStatus = True
  481. # break
  482. # if upStatus is False:
  483. # print "OTA update time out 15min"