multirunner.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. # -*- coding: utf-8 -*-
  2. """Testing framework module for running tests in Python unittest fashion
  3. Copyright (C) 2014 by the GRASS Development Team
  4. This program is free software under the GNU General Public
  5. License (>=v2). Read the file COPYING that comes with GRASS GIS
  6. for details.
  7. :authors: Vaclav Petras
  8. """
  9. from __future__ import print_function
  10. import sys
  11. import os
  12. import argparse
  13. import subprocess
  14. import locale
  15. try:
  16. from itertools import izip as zip
  17. except ImportError: # will be 3.x series
  18. pass
  19. if sys.version_info.major >= 3:
  20. unicode = str
  21. def _get_encoding():
  22. encoding = locale.getdefaultlocale()[1]
  23. if not encoding:
  24. encoding = 'UTF-8'
  25. return encoding
  26. def decode(bytes_, encoding=None):
  27. if isinstance(bytes_, bytes):
  28. return bytes_.decode(_get_encoding())
  29. else:
  30. return bytes_
  31. def encode(string, encoding=None):
  32. if isinstance(string, unicode):
  33. return string.encode(_get_encoding())
  34. else:
  35. return string
  36. def text_to_string(text):
  37. """Convert text to str. Useful when passing text into environments,
  38. in Python 2 it needs to be bytes on Windows, in Python 3 in needs unicode.
  39. """
  40. if sys.version[0] == '2':
  41. # Python 2
  42. return encode(text)
  43. else:
  44. # Python 3
  45. return decode(text)
  46. def main():
  47. parser = argparse.ArgumentParser(
  48. description='Run tests with new')
  49. parser.add_argument('--location', '-l', required=True, action='append',
  50. dest='locations', metavar='LOCATION',
  51. help='Directories with reports')
  52. parser.add_argument('--location-type', '-t', action='append',
  53. dest='location_types',
  54. default=[], metavar='TYPE',
  55. help='Add repeated values to a list',
  56. )
  57. parser.add_argument('--grassbin', required=True,
  58. help='Use file timestamp instead of date in test summary')
  59. # TODO: rename since every src can be used?
  60. parser.add_argument('--grasssrc', required=True,
  61. help='GRASS GIS source code (to take tests from)')
  62. parser.add_argument('--grassdata', required=True,
  63. help='GRASS GIS data base (GISDBASE)')
  64. parser.add_argument('--create-main-report',
  65. help='Create also main report for all tests',
  66. action="store_true", default=False, dest='main_report')
  67. args = parser.parse_args()
  68. gisdb = args.grassdata
  69. locations = args.locations
  70. locations_types = args.location_types
  71. # TODO: if locations empty or just one we can suppose the same all the time
  72. if len(locations) != len(locations_types):
  73. print("ERROR: Number of locations and their tags must be the same", file=sys.stderr)
  74. return 1
  75. main_report = args.main_report
  76. grasssrc = args.grasssrc # TODO: can be guessed from dist
  77. # TODO: create directory according to date and revision and create reports there
  78. # some predefined variables, name of the GRASS launch script + location/mapset
  79. #grass7bin = 'C:\Program Files (x86)\GRASS GIS 7.9.git\grass79dev.bat'
  80. grass7bin = args.grassbin # TODO: can be used if pressent
  81. ########### SOFTWARE
  82. # query GRASS 7 itself for its GISBASE
  83. # we assume that GRASS GIS' start script is available and in the PATH
  84. # the shell=True is here because of MS Windows? (code taken from wiki)
  85. startcmd = grass7bin + ' --config path'
  86. p = subprocess.Popen(startcmd, shell=True,
  87. stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  88. out, err = p.communicate()
  89. if p.returncode != 0:
  90. print("ERROR: Cannot find GRASS GIS 7 start script (%s):\n%s" % (startcmd, err), file=sys.stderr)
  91. return 1
  92. gisbase = decode(out.strip())
  93. # set GISBASE environment variable
  94. os.environ['GISBASE'] = text_to_string(gisbase)
  95. # define GRASS Python environment
  96. grass_python_dir = os.path.join(gisbase, "etc", "python")
  97. sys.path.append(grass_python_dir)
  98. ########### DATA
  99. # define GRASS DATABASE
  100. # Set GISDBASE environment variable
  101. os.environ['GISDBASE'] = text_to_string(gisdb)
  102. # import GRASS Python package for initialization
  103. import grass.script.setup as gsetup
  104. # launch session
  105. # we need some location and mapset here
  106. # TODO: can init work without it or is there some demo location in dist?
  107. location = locations[0].split(':')[0]
  108. mapset = 'PERMANENT'
  109. gsetup.init(gisbase, gisdb, location, mapset)
  110. reports = []
  111. for location, location_type in zip(locations, locations_types):
  112. # here it is quite a good place to parallelize
  113. # including also type to make it unique and preserve it for sure
  114. report = 'report_for_' + location + '_' + location_type
  115. absreport = os.path.abspath(report)
  116. p = subprocess.Popen([sys.executable, '-tt',
  117. '-m', 'grass.gunittest.main',
  118. '--grassdata', gisdb, '--location', location,
  119. '--location-type', location_type,
  120. '--output', absreport],
  121. cwd=grasssrc)
  122. returncode = p.wait()
  123. reports.append(report)
  124. if main_report:
  125. # TODO: solve the path to source code (work now only for grass source code)
  126. arguments = [sys.executable, grasssrc + '/lib/python/guittest/' + 'multireport.py', '--timestapms']
  127. arguments.extend(reports)
  128. p = subprocess.Popen(arguments)
  129. returncode = p.wait()
  130. if returncode != 0:
  131. print("ERROR: Creation of main report failed.", file=sys.stderr)
  132. return 1
  133. return 0
  134. if __name__ == '__main__':
  135. sys.exit(main())