multirunner.py 5.7 KB

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