PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/libreoffice-3.6.0.2/smoketest/lodownloadtest.py

#
Python | 681 lines | 627 code | 9 blank | 45 comment | 2 complexity | 5270e1207e4f075eb8adab024be52613 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, LGPL-3.0
  1. #!/usr/bin/env python
  2. # Version: MPL 1.1 / GPLv3+ / LGPLv3+
  3. #
  4. # The contents of this file are subject to the Mozilla Public License Version
  5. # 1.1 (the "License"); you may not use this file except in compliance with
  6. # the License or as specified alternatively below. You may obtain a copy of
  7. # the License at http://www.mozilla.org/MPL/
  8. #
  9. # Software distributed under the License is distributed on an "AS IS" basis,
  10. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. # for the specific language governing rights and limitations under the
  12. # License.
  13. #
  14. # Major Contributor(s):
  15. # [ Copyright (C) 2011 Yifan Jiang <yfjiang@suse.com> (initial developer) ]
  16. # [ Copyright (C) 2011 Petr Mladek <pmladek@suse.cz> ]
  17. #
  18. # All Rights Reserved.
  19. #
  20. # For minor contributions see the git repository.
  21. #
  22. # Alternatively, the contents of this file may be used under the terms of
  23. # either the GNU General Public License Version 3 or later (the "GPLv3+"), or
  24. # the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
  25. # in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
  26. # instead of those above.
  27. ##
  28. # The tool is designed to enable test machine fully automatically run smoketest
  29. # with both daily and pre release build located in dev-build.libreoffice.org.
  30. #
  31. # The tool is named as losmoketest for its purpose, meanwhile it help you to
  32. # check, download and install the latest build. By the fact the installation is
  33. # designed not to be different from manually doing these repeated work, the
  34. # installed libreoffice build can also be good for manual test.
  35. import sys, os, platform
  36. import datetime, time
  37. import subprocess, shutil
  38. import glob, re
  39. import urllib, urllib2
  40. import logging, getopt
  41. try:
  42. import ConfigParser as configparser # Python 3.0 change
  43. except ImportError:
  44. import configparser
  45. # FIXME: make this configurable via options or autodetect it
  46. build_version = "3.5"
  47. tag_version = "3-5"
  48. # devel build
  49. branding_pack="lodev"
  50. basis_pack="lodevbasis"
  51. # stable build
  52. #branding_pack="libreoffice"
  53. #basis_pack="libobasis"
  54. # possible program files of libreoffice, put all platform paths are
  55. # expected in this list
  56. lo_all_paths = [
  57. "/opt/lodev" + build_version, \
  58. "/opt/libreoffice" + build_version, \
  59. "/usr/lib/libreoffice", \
  60. "/usr/lib64/libreoffice", \
  61. "C:\program file\libreoffice", \
  62. ]
  63. build_check_interval = 5 #seconds
  64. # Distro list
  65. RPM_DISTRO_LIST = ['SuSE', 'fedora', 'redhat', 'centos', 'mandrake', 'mandriva', 'yellowdog', 'turbolinux']
  66. DEB_DISTRO_LIST = ['debian', 'ubuntu', 'Ubuntu']
  67. # Server urls
  68. SERVER_URL = "http://dev-builds.libreoffice.org"
  69. # Local dirs
  70. root_dir = os.getcwd()
  71. DOWNLOAD_DIR = os.path.join(root_dir, "_download")
  72. USR_DIR = os.path.join(root_dir, "_libo_smoke_user")
  73. LOCAL_BUILD_INFO_FILE = os.path.join(root_dir, "build.cfg")
  74. # INSTALL_DIR = os.path.join(root_dir, "_libo_smoke_installation")
  75. INSTALL_DIR = "" # Installation dir
  76. # SOFFICE_BIN bin
  77. if platform.system() == "Linux":
  78. SOFFICE_BIN = "soffice"
  79. LOSMOKETEST_BIN = "losmoketest"
  80. elif platform.system() == "Windows":
  81. SOFFICE_BIN = "soffice.exe"
  82. LOSMOKETEST_BIN = "losmoketest"
  83. else:
  84. SOFFICE_BIN = "soffice"
  85. LOSMOKETEST_BIN = "losmoketest"
  86. # Relative build url
  87. ## pre-releases
  88. PR_RPM_X86_PATH = "pre-releases/rpm/x86/"
  89. PR_RPM_X86_64_PATH = "pre-releases/rpm/x86_64/"
  90. PR_DEB_X86_PATH = "pre-releases/deb/x86/"
  91. PR_DEB_X86_64_PATH = "pre-releases/deb/x86_64/"
  92. PR_MAC_X86_PATH = "pre-releases/mac/x86/"
  93. PR_MAC_PPC_PATH = "pre-releases/mac/ppc/"
  94. PR_WIN_X86_PATH = "pre-releases/win/x86/"
  95. ## daily_master
  96. DAILY_MASTER_RPM_X86_PATH = "daily/Linux-x86_10-Release_Configuration/master/current"
  97. DAILY_MASTER_RPM_X86_64_PATH = "daily/Linux-x86_64_11-Release_Configuration/master/current"
  98. DAILY_MASTER_DEB_X86_PATH = "daily/Linux-x86_10-Release_Configuration/master/current"
  99. DAILY_MASTER_DEB_X86_64_PATH = "daily/Linux-x86_64_11-Release_Configuration/master/current"
  100. DAILY_MASTER_MAC_X86_PATH = "daily/MacOSX-Intel@3-OSX_10.6.0-gcc_4.0.1/master/current"
  101. DAILY_MASTER_MAC_PPC_PATH = "daily/MacOSX-PPC@12-OSX_10.5.0-gcc_4.0.1/master/current" # No build yet
  102. DAILY_MASTER_WIN_X86_PATH = "daily/Win-x86@7-MinGW/master/current" # cross compling build
  103. ## daily_branch
  104. DAILY_BRANCH_RPM_X86_PATH = "daily/Linux-x86_10-Release_Configuration/libreoffice-" + tag_version + "/current"
  105. DAILY_BRANCH_RPM_X86_64_PATH = "daily/Linux-x86_64_11-Release_Configuration/libreoffice-" + tag_version + "/current"
  106. DAILY_BRANCH_DEB_X86_PATH = "daily/Linux-x86_10-Release_Configuration/libreoffice-" + tag_version + "/current"
  107. DAILY_BRANCH_DEB_X86_64_PATH = "daily/Linux-x86_64_11-Release_Configuration/libreoffice-" + tag_version + "/current"
  108. DAILY_BRANCH_MAC_X86_PATH = "daily/MacOSX-Intel@3-OSX_10.6.0-gcc_4.0.1/libreoffice-" + tag_version + "/current"
  109. DAILY_BRANCH_MAC_PPC_PATH = "daily/MacOSX-PPC@12-OSX_10.5.0-gcc_4.0.1/libreoffice-" + tag_version + "/current"
  110. DAILY_BRANCH_WIN_X86_PATH = "daily/Win-x86@7-MinGW/libreoffice-" + tag_version + "/current"
  111. def platform_info():
  112. s = platform.system()
  113. arch_name = platform.machine()
  114. if arch_name in ['x86', 'i386', 'i586', 'i686']:
  115. arch_name = 'x86'
  116. if s == "Linux":
  117. if platform.dist()[0] in RPM_DISTRO_LIST:
  118. distro_name = platform.dist()[0]
  119. pck_name = 'rpm'
  120. elif platform.dist()[0] in DEB_DISTRO_LIST:
  121. distro_name = platform.dist()[0]
  122. pck_name = 'deb'
  123. elif s == "Windows":
  124. distro_name = platform.dist()[0]
  125. pck_name = 'exe'
  126. else:
  127. distro_name = platform.dist()[0]
  128. pck_name = 'dmg'
  129. return distro_name, pck_name, arch_name
  130. def local_build_info(t):
  131. if not os.path.exists(LOCAL_BUILD_INFO_FILE):
  132. logger.error("Can't find the file: " + LOCAL_BUILD_INFO_FILE)
  133. sys.exit()
  134. config = configparser.RawConfigParser()
  135. config.read(LOCAL_BUILD_INFO_FILE)
  136. try:
  137. build_name = config.get(t, 'build_name').strip('\n')
  138. build_time = datetime.datetime.strptime(config.get(t, 'build_time').strip('\n'), '%d-%b-%Y %H:%M')
  139. except ValueError:
  140. build_name = ''
  141. build_time = datetime.datetime.min
  142. try:
  143. testpack_name = config.get(t, 'testpack_name').strip('\n')
  144. testpack_build_time = datetime.datetime.strptime(config.get(t, 'testpack_build_time').strip('\n'), '%d-%b-%Y %H:%M')
  145. except ValueError:
  146. testpack_name = ''
  147. testpack_build_time = datetime.datetime.min
  148. return build_name, build_time, testpack_name, testpack_build_time
  149. def get_url_regexp(t, package, arch):
  150. '''
  151. return a url containing download links, i.e:
  152. http://dev-builds.libreoffice.org/pre-releases/rpm/x86_64/
  153. http://dev-builds.libreoffice.org/daily/Windows_Release_Configuration/libreoffice-3-4/current/
  154. http://dev-builds.libreoffice.org/daily/Linux_x86_Release_Configuration/libreoffice-3-4/current/
  155. meanwhile return a regexp object that matching corresponding downloadable
  156. package and its timestamp '''
  157. url = ""
  158. reg_lo = re.compile('^$')
  159. reg_tst = re.compile('^$')
  160. pck = package
  161. arc = arch
  162. if t == 'pre-releases':
  163. if pck == "rpm" and arc == "x86":
  164. url = SERVER_URL + "/" + PR_RPM_X86_PATH
  165. reg_lo = re.compile('\<a\ href=\"(LibO_\d.*x86_install-rpm.*en-US.*\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  166. reg_tst = re.compile('\<a\ href=\"(LibO-Test.*.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  167. elif pck == "rpm" and arc == "x86_64":
  168. url = SERVER_URL + "/" + PR_RPM_X86_64_PATH
  169. reg_lo = re.compile('\<a\ href=\"(LibO_\d.*x86-64_install-rpm.*en-US.*\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  170. reg_tst = re.compile('\<a\ href=\"(LibO-Test.*.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  171. elif pck == "deb" and arc == "x86":
  172. url = SERVER_URL + "/" + PR_DEB_X86_PATH
  173. reg_lo = re.compile('\<a\ href=\"(LibO_\d.*x86_install-deb.*en-US.*\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  174. elif pck == "deb" and arc == "x86_64":
  175. url = SERVER_URL + "/" + PR_DEB_X86_64_PATH
  176. reg_lo = re.compile('\<a\ href=\"(LibO_\d.*x86-64_install-deb.*en-US.*\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  177. elif pck == "exe" and arc == "x86":
  178. url = SERVER_URL + "/" + PR_WIN_X86_PATH
  179. reg_lo = re.compile('\<a\ href=\"(LibO_\d.*Win_x86_install_multi.exe)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  180. elif pck == "dmg" and arc == "x86":
  181. url = SERVER_URL + "/" + PR_MAC_X86_PATH
  182. reg_lo = re.compile('\<a\ href=\"(LibO_\d.*MacOS_x86_install_en-US.dmg)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  183. elif pck == "dmg" and arc == "ppc":
  184. url = SERVER_URL + "/" + PR_MAC_PPC_PATH
  185. reg_lo = re.compile('\<a\ href=\"(LibO_\d.*MacOS_PPC_install_en-US.dmg)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  186. else:
  187. logger.error("Unable to handle the system or arch!")
  188. elif t == 'daily_master':
  189. if pck == "rpm" and arc == "x86":
  190. url = SERVER_URL + "/" + DAILY_MASTER_RPM_X86_PATH
  191. reg_lo = re.compile('\<a\ href=\"(master\~\d.*LibO-Dev_.*x86_install-rpm_en-US.tar.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  192. elif pck == "rpm" and arc == "x86_64":
  193. url = SERVER_URL + "/" + DAILY_MASTER_RPM_X86_64_PATH
  194. reg_lo = re.compile('\<a\ href=\"(master\~\d.*LibO-Dev_.*x86-64_install-rpm_en-US.tar.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  195. elif pck == "deb" and arc == "x86":
  196. url = SERVER_URL + "/" + DAILY_MASTER_DEB_X86_PATH
  197. reg_lo = re.compile('\<a\ href=\"(master\~\d.*LibO-Dev_.*x86_install-deb_en-US.tar.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  198. elif pck == "deb" and arc == "x86_64":
  199. url = SERVER_URL + "/" + DAILY_MASTER_DEB_X86_64_PATH
  200. reg_lo = re.compile('^$') # No build yet
  201. elif pck == "exe" and arc == "x86":
  202. url = SERVER_URL + "/" + DAILY_MASTER_WIN_X86_PATH
  203. reg_lo = re.compile('^$') # No build yet
  204. elif pck == "dmg" and arc == "x86":
  205. url = SERVER_URL + "/" + DAILY_MASTER_MAC_X86_PATH
  206. reg_lo = re.compile('\<a\ href=\"(master\~\d.*LibO-Dev_.*x86_install_en-US.dmg)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  207. elif pck == "dmg" and arc == "ppc":
  208. url = SERVER_URL + "/" + DAILY_MASTER_MAC_PPC_PATH
  209. reg_lo = re.compile('^$') # No build yet
  210. else:
  211. logger.error("Unable to handle the system or arch!")
  212. elif t == 'daily_branch':
  213. if pck == "rpm" and arc == "x86":
  214. url = SERVER_URL + "/" + DAILY_BRANCH_RPM_X86_PATH
  215. reg_lo = re.compile('\<a\ href=\"(.*LibO_.*x86_install-rpm_en-US\.tar\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  216. elif pck == "rpm" and arc == "x86_64":
  217. url = SERVER_URL + "/" + DAILY_BRANCH_RPM_X86_64_PATH
  218. reg_lo = re.compile('\<a\ href=\"(.*LibO_.*x86-64_install-rpm_en-US\.tar\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  219. elif pck == "deb" and arc == "x86":
  220. url = SERVER_URL + "/" + DAILY_BRANCH_DEB_X86_PATH
  221. reg_lo = re.compile('\<a\ href=\"(.*LibO_.*x86_install-deb_en-US\.tar\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  222. elif pck == "deb" and arc == "x86_64":
  223. url = SERVER_URL + "/" + DAILY_BRANCH_DEB_X86_64_PATH
  224. reg_lo = re.compile('\<a\ href=\"(.*LibO_.*x86-64_install-deb_en-US\.tar\.gz)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  225. elif pck == "exe" and arc == "x86":
  226. url = SERVER_URL + "/" + DAILY_BRANCH_WIN_X86_PATH
  227. reg_lo = re.compile('\<a\ href=\"(.*LibO_.*install_.*\.exe)\".*(\d{2}\-[a-zA-Z]{3}\-\d{4}).*(\d{2}:\d{2}).*')
  228. elif pck == "dmg" and arc == "x86":
  229. url = SERVER_URL + "/" + DAILY_BRANCH_MAC_X86_PATH
  230. reg_lo = re.compile('^$') # No build yet
  231. elif pck == "dmg" and arc == "ppc":
  232. url = SERVER_URL + "/" + DAILY_BRANCH_MAC_PPC_PATH
  233. reg_lo = re.compile('^$') # No build yet
  234. else:
  235. logger.error("Unable to handle the system or arch!")
  236. else:
  237. logger.error("Error build type! The build type has to be:\n pre-releases, daily_master, daily_branch")
  238. return url, reg_lo, reg_tst
  239. def remote_build_info(url_reg):
  240. ''' Get the latest proper build info (build_name, build_time) from
  241. url. '''
  242. p = platform_info()
  243. pck = p[1]
  244. arc = p[2]
  245. r = url_reg[1]
  246. r_t = url_reg[2]
  247. f = urllib2.urlopen(url_reg[0])
  248. c = ''.join(f.readlines())
  249. f.close()
  250. build_list = r.findall(c)
  251. test_list = r_t.findall(c)
  252. build_name = ''
  253. build_time = datetime.datetime.min
  254. testpack_build_time = datetime.datetime.min
  255. testpack_name = ''
  256. for b in build_list:
  257. if datetime.datetime.strptime(b[1] + ' ' + b[2], '%d-%b-%Y %H:%M') > build_time:
  258. build_name = b[0]
  259. try:
  260. build_time = datetime.datetime.strptime(b[1] + ' ' + b[2], '%d-%b-%Y %H:%M')
  261. except:
  262. print "remote_build_info: wrong time date&format"
  263. for t in test_list:
  264. if datetime.datetime.strptime(t[1] + ' ' + t[2], '%d-%b-%Y %H:%M') > testpack_build_time:
  265. testpack_name = t[0]
  266. try:
  267. testpack_build_time = datetime.datetime.strptime(t[1] + ' ' + t[2], '%d-%b-%Y %H:%M')
  268. except:
  269. print "remote_build_info: wrong time date&format"
  270. return build_name, build_time, testpack_name, testpack_build_time
  271. # return True when something was downloaded
  272. def download(url_reg, build_type):
  273. logger.info('Checking new build ...')
  274. try:
  275. remote_build = remote_build_info(url_reg)
  276. local_build = local_build_info(build_type)
  277. if remote_build[1] > local_build[1]:
  278. logger.info('Found New LO build: ' + remote_build[0])
  279. if fetch_build(url_reg[0], remote_build[0]):
  280. set_build_config(build_type, 'build_name', remote_build[0])
  281. set_build_config(build_type, 'build_time', datetime.datetime.strftime(remote_build[1], '%d-%b-%Y %H:%M'))
  282. else:
  283. logger.error('Download libreoffice build failed!')
  284. if remote_build[3] > local_build[3] and (remote_build[1] - remote_build[3]) < datetime.timedelta(hours=1):
  285. logger.info('Found a relevant smoketest package: ' + remote_build[2])
  286. if fetch_build(url_reg[0], remote_build[2]):
  287. set_build_config(build_type, 'testpack_name', remote_build[2])
  288. set_build_config(build_type, 'testpack_build_time', datetime.datetime.strftime(remote_build[3], '%d-%b-%Y %H:%M'))
  289. return True
  290. else:
  291. logger.warning("Failed to find corresponding smoketest package")
  292. except urllib2.URLError, HTTPError:
  293. logger.error('Error fetch remote build info.')
  294. return False
  295. except KeyboardInterrupt:
  296. sys.exit()
  297. except:
  298. logger.error('Error fetch remote build info.')
  299. return False
  300. return False
  301. def fetch_build(url, filename):
  302. ''' Download a build from address url/filename '''
  303. logger.info("Downloading ... " + filename)
  304. u = urllib2.urlopen(url + '/' + filename)
  305. try:
  306. f = open(DOWNLOAD_DIR + '/' + filename, 'wb')
  307. f.write(u.read())
  308. f.close()
  309. except urllib2.HTTPError, e:
  310. print "HTTP Error:",e.code , url
  311. except urllib2.URLError, e:
  312. print "URL Error:",e.reason , url
  313. return True
  314. def set_build_config(section, option, value):
  315. config = configparser.RawConfigParser()
  316. config.readfp(open(LOCAL_BUILD_INFO_FILE))
  317. config.set(section, option, value)
  318. with open(LOCAL_BUILD_INFO_FILE, 'wb') as cfgfile:
  319. config.write(cfgfile)
  320. def uninstall(build_type):
  321. ''' Kill libreoffice processes and uninstall all previously installed
  322. libreoffice packages '''
  323. if build_type == "pre-releases":
  324. branding_pack="libreoffice"
  325. basis_pack="libobasis"
  326. logger.info("Uninstalling ...")
  327. pck = platform_info()[1]
  328. if pck == 'rpm':
  329. cmd_query = ["rpm", "-qa"]
  330. cmd_filter = ["grep", \
  331. "-e", branding_pack+build_version, \
  332. "-e", basis_pack+build_version, \
  333. ]
  334. P_query = subprocess.Popen(cmd_query, stdout = subprocess.PIPE)
  335. P_filter = subprocess.Popen(cmd_filter, stdin = P_query.stdout, stdout = subprocess.PIPE)
  336. P_query.stdout.close() # protection when P_filter exit before P_query
  337. str_filter = P_filter.communicate()[0]
  338. if str_filter == "":
  339. logger.warning("Nothing to uninstall")
  340. return
  341. else:
  342. cmd = ["sudo", "rpm", "-e"] + str_filter.split()
  343. elif pck == 'deb':
  344. cmd_query = ["dpkg", "--get-selections", branding_pack+build_version+"*", basis_pack+build_version+"*"]
  345. cmd_filter = ["cut", "-f", "1"]
  346. P_query = subprocess.Popen(cmd_query, stdout = subprocess.PIPE)
  347. P_filter = subprocess.Popen(cmd_filter, stdin = P_query.stdout, stdout = subprocess.PIPE)
  348. P_query.stdout.close()
  349. str_filter = P_filter.communicate()[0]
  350. if str_filter == "":
  351. logger.warning("Nothing to uninstall")
  352. return
  353. else:
  354. cmd = ["sudo", "dpkg ", "-P"] + str_filter.split()
  355. elif pck == 'exe':
  356. pass
  357. elif pck == 'dmg':
  358. pass
  359. else:
  360. logger.warning("Non supported package system")
  361. subprocess.check_call(cmd)
  362. def init_testing():
  363. logger.info("Initializing ...")
  364. post_testing()
  365. if not os.path.exists(DOWNLOAD_DIR):
  366. os.mkdir(DOWNLOAD_DIR)
  367. if not os.path.exists(USR_DIR):
  368. os.mkdir(USR_DIR)
  369. if not os.path.exists(LOCAL_BUILD_INFO_FILE):
  370. init_build_cfg = '[daily_branch]' + os.linesep\
  371. + 'build_name =' + os.linesep\
  372. + 'build_time =' + os.linesep\
  373. + 'testpack_name =' + os.linesep\
  374. + 'testpack_build_time =' + os.linesep\
  375. + '[daily_master]' + os.linesep\
  376. + 'build_name =' + os.linesep\
  377. + 'build_time =' + os.linesep\
  378. + 'testpack_name =' + os.linesep\
  379. + 'testpack_build_time =' + os.linesep\
  380. + '[pre-releases]' + os.linesep\
  381. + 'build_name =' + os.linesep\
  382. + 'build_time =' + os.linesep \
  383. + 'testpack_name =' + os.linesep\
  384. + 'testpack_build_time =' + os.linesep
  385. with open(LOCAL_BUILD_INFO_FILE, 'w+') as f:
  386. f.write(init_build_cfg)
  387. f.close()
  388. def post_testing():
  389. logger.info("Cleaning up ...")
  390. # clean up the extracted installer dir
  391. for r in os.walk(DOWNLOAD_DIR):
  392. if r[0] == DOWNLOAD_DIR:
  393. for d in r[1]:
  394. shutil.rmtree(os.path.join(r[0], d))
  395. def install(filename):
  396. ''' filename: local file path of tar.gz, dmg or exe. The script will
  397. extract the package and then install it '''
  398. logger.info("Installing ... " + filename)
  399. def _is_not_filtered(s):
  400. ''' True if the package s is not intended to installed. '''
  401. filter_pattern_list = ['.*kde.*', '.*gnome.*', '.*desktop.*', '!.*\.rpm$', '!.*\.deb$']
  402. for p in filter_pattern_list:
  403. r = re.compile(p)
  404. if r.match(s):
  405. return False
  406. return True
  407. fn, ext = os.path.splitext(filename)
  408. pcklist = []
  409. if ext == '.exe':
  410. # extract
  411. installer_dir = os.path.join(DOWNLOAD_DIR, filename.strip(ext))
  412. subprocess.check_call([filename, '/EXTRACTONLY=ON', '/S', '/D='+installer_dir])
  413. # install
  414. installer = glob.glob(os.path.join(installer_dir, 'libreoffice*msi'))[0]
  415. subprocess.check_call(['msiexec', '-i', installer, '-passive', 'ADDLOCAL=all'])
  416. elif ext == '.dmg':
  417. return
  418. elif ext == '.gz':
  419. # extract
  420. subprocess.check_call(['tar', 'xzf', filename, '-C', DOWNLOAD_DIR])
  421. # get a filtered install list
  422. for root, dirs, files in os.walk(DOWNLOAD_DIR):
  423. if 'RPMS' in root or 'DEBS' in root:
  424. pcklist = pcklist + [os.path.join(root_dir, root, f) for f in files]
  425. install_pcklist = filter(_is_not_filtered, pcklist)
  426. # install
  427. if platform_info()[1] == 'rpm':
  428. install_cmd = ["sudo", "rpm", "-iv"] + install_pcklist
  429. clean_tmp_cmd = ["sudo", "rm", "-f"] + pcklist
  430. elif platform_info()[1] == 'deb':
  431. install_cmd = ["sudo", "dpkg", "-i"] + install_pcklist
  432. else:
  433. logger.error('Cannot generate install command')
  434. return
  435. subprocess.check_call(install_cmd)
  436. subprocess.check_call(clean_tmp_cmd)
  437. else:
  438. logger.info("Unrecognized file extension")
  439. def verify_smoketest(headless):
  440. logger.info("Testing ...")
  441. s = platform.system()
  442. p = platform_info()
  443. pck = p[1]
  444. arc = p[2]
  445. lo_testable_paths = filter(lambda p: \
  446. os.path.exists(p + os.sep + "program" + os.sep + LOSMOKETEST_BIN) and \
  447. os.path.exists(p + os.sep + "program" + os.sep + SOFFICE_BIN), \
  448. lo_all_paths)
  449. if not lo_testable_paths:
  450. logger.error("Not found any Libreoffice or Test packages!")
  451. sys.exit(1)
  452. else:
  453. cmd_smoketests = [ p + os.sep + "program" + os.sep + LOSMOKETEST_BIN for p in lo_testable_paths ]
  454. if len(lo_testable_paths) > 1:
  455. logger.info("++More than one testable build is found, test them one by one.")
  456. # subprocess.call(cmd_smoketest);
  457. for c in cmd_smoketests:
  458. pattern = re.compile(LOSMOKETEST_BIN + "$")
  459. logger.info(" Test Binary: " + pattern.sub(SOFFICE_BIN, c))
  460. subprocess.call(c)
  461. def usage():
  462. print "\n[Usage]\n\n -f Force testing without asking \n\
  463. -t Testing type pre-release/daily \n\
  464. -l Download and test last builds in a loop \n\
  465. -v Run smoketest verification directly \n\
  466. -s Use the headless mode when running the tests \n\
  467. -i Install the latest build in the DOWNLOAD directory \n\
  468. -u Uninstall any existed libreoffice build \n\
  469. -d Download the latest build for the given test type \n\
  470. "
  471. def main():
  472. interactive = True
  473. build_type = "pre-releases"
  474. package_type = platform_info()[1]
  475. arch_type = platform_info()[2]
  476. loop = False
  477. interactive = True
  478. headless = False
  479. build_type = "pre-releases"
  480. # Handling options and arguments
  481. try:
  482. opts, args = getopt.getopt(sys.argv[1:], "dluihfvst:", ["download", "loop", "uninstall", "install", "help", "force", "verify", "headless", "type="])
  483. except getopt.GetoptError, err:
  484. logger.error(str(err))
  485. usage()
  486. sys.exit(2)
  487. for o, a in opts:
  488. if ("-t" in o) or ("--type" in o):
  489. build_type = a
  490. elif o in ("-s", "--headless"):
  491. headless = True
  492. url_reg = get_url_regexp(build_type, package_type, arch_type)
  493. for o, a in opts:
  494. if o in ("-f", "--force"):
  495. interactive = False
  496. elif o in ("-t", "--type"):
  497. pass
  498. elif o in ("-s", "--headless"):
  499. pass
  500. elif o in ("-h", "--help"):
  501. usage()
  502. sys.exit()
  503. elif o in ("-v", "--verify"):
  504. init_testing()
  505. verify_smoketest(headless)
  506. sys.exit()
  507. elif o in ("-i", "--install"):
  508. init_testing()
  509. uninstall(build_type)
  510. install(DOWNLOAD_DIR + os.sep + local_build_info(build_type)[0])
  511. install(DOWNLOAD_DIR + os.sep + local_build_info(build_type)[2])
  512. sys.exit()
  513. elif o in ("-u", "--uninstall"):
  514. uninstall(build_type)
  515. sys.exit()
  516. elif o in ("-d", "--download"):
  517. init_testing()
  518. download(url_reg, build_type)
  519. sys.exit()
  520. elif o in ("-l", "--loop"):
  521. loop = True
  522. else:
  523. assert False, "Unhandled option: " + o
  524. if interactive == True:
  525. key = raw_input("The testing will OVERRIDE existed libreoffice, continue(y/N)? ")
  526. if not (key == "y" or key == "Y" or key == "yes"):
  527. sys.exit()
  528. init_testing()
  529. first_run = True
  530. while loop or first_run:
  531. if download(url_reg, build_type):
  532. try:
  533. # FIXME: uninstall script fails but it need not break the whole game; so try it twice
  534. try:
  535. uninstall(build_type)
  536. except:
  537. logger.error("Some errors happened during uninstall. Trying once again.")
  538. uninstall(build_type)
  539. install(DOWNLOAD_DIR + os.sep + local_build_info(build_type)[0])
  540. install(DOWNLOAD_DIR + os.sep + local_build_info(build_type)[2])
  541. verify_smoketest(headless)
  542. except KeyboardInterrupt:
  543. sys.exit()
  544. except:
  545. continue
  546. else:
  547. logger.warning("No new build found.")
  548. if loop:
  549. time.sleep(build_check_interval)
  550. first_run = False
  551. if __name__ == '__main__':
  552. # logging
  553. logger = logging.getLogger('')
  554. logger.setLevel(logging.DEBUG)
  555. fh = logging.FileHandler(os.path.basename(__file__) + '.log')
  556. ch = logging.StreamHandler()
  557. formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
  558. ch.setFormatter(formatter)
  559. fh.setFormatter(formatter)
  560. logger.addHandler(ch)
  561. logger.addHandler(fh)
  562. main()