Пример #1
0
 def __init__(self,
              cmd,
              width=None,
              height=None,
              overlap=0,
              processes=None,
              split=False,
              debug=False,
              region=None,
              move=None,
              log=False,
              start_row=0,
              start_col=0,
              out_prefix='',
              *args,
              **kargs):
     kargs['run_'] = False
     self.mset = Mapset()
     self.module = Module(cmd, *args, **kargs)
     self.width = width
     self.height = height
     self.overlap = overlap
     self.processes = processes
     self.region = region if region else Region()
     self.start_row = start_row
     self.start_col = start_col
     self.out_prefix = out_prefix
     self.log = log
     self.move = move
     self.gisrc_src = os.environ['GISRC']
     self.n_mset, self.gisrc_dst = None, None
     if self.move:
         self.n_mset = copy_mapset(self.mset, self.move)
         self.gisrc_dst = write_gisrc(self.n_mset.gisdbase,
                                      self.n_mset.location,
                                      self.n_mset.name)
         rasters = [r for r in select(self.module.inputs, 'raster')]
         if rasters:
             copy_rasters(rasters,
                          self.gisrc_src,
                          self.gisrc_dst,
                          region=self.region)
         vectors = [v for v in select(self.module.inputs, 'vector')]
         if vectors:
             copy_vectors(vectors, self.gisrc_src, self.gisrc_dst)
         groups = [g for g in select(self.module.inputs, 'group')]
         if groups:
             copy_groups(groups,
                         self.gisrc_src,
                         self.gisrc_dst,
                         region=self.region)
     self.bboxes = split_region_tiles(region=region,
                                      width=width,
                                      height=height,
                                      overlap=overlap)
     self.msetstr = cmd.replace('.', '') + "_%03d_%03d"
     self.inlist = None
     if split:
         self.split()
     self.debug = debug
Пример #2
0
 def get_works(self):
     """Return a list of tuble with the parameters for cmd_exe function"""
     works = []
     reg = Region()
     if self.move:
         mdst, ldst, gdst = read_gisrc(self.gisrc_dst)
     else:
         ldst, gdst = self.mset.location, self.mset.gisdbase
     cmd = self.module.get_dict()
     groups = [g for g in select(self.module.inputs, 'group')]
     for row, box_row in enumerate(self.bboxes):
         for col, box in enumerate(box_row):
             inms = None
             if self.inlist:
                 inms = {}
                 cols = len(box_row)
                 for key in self.inlist:
                     indx = row * cols + col
                     inms[key] = "%s@%s" % (self.inlist[key][indx],
                                            self.mset.name)
             # set the computational region, prepare the region parameters
             bbox = dict([(k[0], str(v)) for k, v in box.items()[:-2]])
             bbox['nsres'] = '%f' % reg.nsres
             bbox['ewres'] = '%f' % reg.ewres
             new_mset = self.msetstr % (self.start_row + row,
                                        self.start_col + col),
             works.append((bbox, inms,
                           self.gisrc_src,
                           write_gisrc(gdst, ldst, new_mset),
                           cmd, groups))
     return works
Пример #3
0
 def get_works(self):
     """Return a list of tuble with the parameters for cmd_exe function"""
     works = []
     reg = Region()
     if self.move:
         mdst, ldst, gdst = read_gisrc(self.gisrc_dst)
     else:
         ldst, gdst = self.mset.location, self.mset.gisdbase
     cmd = self.module.get_dict()
     groups = [g for g in select(self.module.inputs, 'group')]
     for row, box_row in enumerate(self.bboxes):
         for col, box in enumerate(box_row):
             inms = None
             if self.inlist:
                 inms = {}
                 cols = len(box_row)
                 for key in self.inlist:
                     indx = row * cols + col
                     inms[key] = "%s@%s" % (self.inlist[key][indx],
                                            self.mset.name)
             # set the computational region, prepare the region parameters
             bbox = dict([(k[0], str(v)) for k, v in box.items()[:-2]])
             bbox['nsres'] = '%f' % reg.nsres
             bbox['ewres'] = '%f' % reg.ewres
             new_mset = self.msetstr % (self.start_row + row,
                                        self.start_col + col),
             works.append((bbox, inms, self.gisrc_src,
                           write_gisrc(gdst, ldst, new_mset), cmd, groups))
     return works
Пример #4
0
 def __init__(self, cmd, width=None, height=None, overlap=0, processes=None,
              split=False, debug=False, region=None, move=None, log=False,
              start_row=0, start_col=0, out_prefix='', mapset_prefix=None,
              *args, **kargs):
     kargs['run_'] = False
     self.mset = Mapset()
     self.module = Module(cmd, *args, **kargs)
     self.width = width
     self.height = height
     self.overlap = overlap
     self.processes = processes
     self.region = region if region else Region()
     self.start_row = start_row
     self.start_col = start_col
     self.out_prefix = out_prefix
     self.log = log
     self.move = move
     self.gisrc_src = os.environ['GISRC']
     self.n_mset, self.gisrc_dst = None, None
     if self.move:
         self.n_mset = copy_mapset(self.mset, self.move)
         self.gisrc_dst = write_gisrc(self.n_mset.gisdbase,
                                      self.n_mset.location,
                                      self.n_mset.name)
         rasters = [r for r in select(self.module.inputs, 'raster')]
         if rasters:
             copy_rasters(rasters, self.gisrc_src, self.gisrc_dst,
                          region=self.region)
         vectors = [v for v in select(self.module.inputs, 'vector')]
         if vectors:
             copy_vectors(vectors, self.gisrc_src, self.gisrc_dst)
         groups = [g for g in select(self.module.inputs, 'group')]
         if groups:
             copy_groups(groups, self.gisrc_src, self.gisrc_dst,
                         region=self.region)
     self.bboxes = split_region_tiles(region=region,
                                      width=width, height=height,
                                      overlap=overlap)
     if mapset_prefix:
         self.msetstr = mapset_prefix + "_%03d_%03d"
     else:
         self.msetstr = cmd.replace('.', '') + "_%03d_%03d"
     self.inlist = None
     if split:
         self.split()
     self.debug = debug
Пример #5
0
    def _run_test_module(self, module, results_dir, gisdbase, location):
        """Run one test file."""
        self.testsuite_dirs[module.tested_dir].append(module.name)
        cwd = os.path.join(results_dir, module.tested_dir, module.name)
        data_dir = os.path.join(module.file_dir, 'data')
        if os.path.exists(data_dir):
            # TODO: link dir instead of copy tree and remove link afterwads
            # (removing is good because of testsuite dir in samplecode)
            # TODO: use different dir name in samplecode and test if it works
            shutil.copytree(data_dir, os.path.join(cwd, 'data'),
                            ignore=shutil.ignore_patterns('*.svn*'))
        ensure_dir(os.path.abspath(cwd))
        # TODO: put this to constructor and copy here again
        env = os.environ.copy()
        mapset, mapset_dir = self._create_mapset(gisdbase, location, module)
        gisrc = gsetup.write_gisrc(gisdbase, location, mapset)

        # here is special setting of environmental variables for running tests
        # some of them might be set from outside in the future and if the list
        # will be long they should be stored somewhere separately

        # use custom gisrc, not current session gisrc
        env['GISRC'] = gisrc
        # percentage in plain format is 0...10...20... ...100
        env['GRASS_MESSAGE_FORMAT'] = 'plain'

        stdout_path = os.path.join(cwd, 'stdout.txt')
        stderr_path = os.path.join(cwd, 'stderr.txt')
        stdout = open(stdout_path, 'w')
        stderr = open(stderr_path, 'w')

        self.reporter.start_file_test(module)
        # TODO: we might clean the directory here before test if non-empty

        if module.file_type == 'py':
            # ignoring shebang line to use current Python
            # and also pass parameters to it
            # add also '-Qwarn'?
            p = subprocess.Popen([sys.executable, '-tt', '-3',
                                  module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=stdout, stderr=stderr)
        elif module.file_type == 'sh':
            # ignoring shebang line to pass parameters to shell
            # expecting system to have sh or something compatible
            # TODO: add some special checks for MS Windows
            # using -x to see commands in stderr
            # using -e to terminate fast
            # from dash manual:
            # -e errexit     If not interactive, exit immediately if any
            #                untested command fails.  The exit status of a com‐
            #                mand is considered to be explicitly tested if the
            #                command is used to control an if, elif, while, or
            #                until; or if the command is the left hand operand
            #                of an '&&' or '||' operator.
            p = subprocess.Popen(['sh', '-e', '-x', module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=stdout, stderr=stderr)
        else:
            p = subprocess.Popen([module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=stdout, stderr=stderr)
        returncode = p.wait()
        stdout.close()
        stderr.close()
        self._file_anonymizer.anonymize([stdout_path, stderr_path])

        test_summary = update_keyval_file(
            os.path.join(os.path.abspath(cwd), 'test_keyvalue_result.txt'),
            module=module, returncode=returncode)
        self.reporter.end_file_test(module=module, cwd=cwd,
                                    returncode=returncode,
                                    stdout=stdout_path, stderr=stderr_path,
                                    test_summary=test_summary)
        # TODO: add some try-except or with for better error handling
        os.remove(gisrc)
        # TODO: only if clean up
        if self.clean_mapsets:
            shutil.rmtree(mapset_dir)
Пример #6
0
    def _run_test_module(self, module, results_dir, gisdbase, location):
        """Run one test file."""
        self.testsuite_dirs[module.tested_dir].append(module.name)
        cwd = os.path.join(results_dir, module.tested_dir, module.name)
        data_dir = os.path.join(module.file_dir, "data")
        if os.path.exists(data_dir):
            # TODO: link dir instead of copy tree and remove link afterwads
            # (removing is good because of testsuite dir in samplecode)
            # TODO: use different dir name in samplecode and test if it works
            shutil.copytree(
                data_dir,
                os.path.join(cwd, "data"),
                ignore=shutil.ignore_patterns("*.svn*"),
            )
        ensure_dir(os.path.abspath(cwd))
        # TODO: put this to constructor and copy here again
        env = os.environ.copy()
        mapset, mapset_dir = self._create_mapset(gisdbase, location, module)
        gisrc = gsetup.write_gisrc(gisdbase, location, mapset)

        # here is special setting of environmental variables for running tests
        # some of them might be set from outside in the future and if the list
        # will be long they should be stored somewhere separately

        # use custom gisrc, not current session gisrc
        env["GISRC"] = gisrc
        # percentage in plain format is 0...10...20... ...100
        env["GRASS_MESSAGE_FORMAT"] = "plain"

        stdout_path = os.path.join(cwd, "stdout.txt")
        stderr_path = os.path.join(cwd, "stderr.txt")

        self.reporter.start_file_test(module)
        # TODO: we might clean the directory here before test if non-empty

        if module.file_type == "py":
            # ignoring shebang line to use current Python
            # and also pass parameters to it
            # add also '-Qwarn'?
            if sys.version_info.major >= 3:
                args = [sys.executable, "-tt", module.abs_file_path]
            else:
                args = [sys.executable, "-tt", "-3", module.abs_file_path]
            p = subprocess.Popen(args,
                                 cwd=cwd,
                                 env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        elif module.file_type == "sh":
            # ignoring shebang line to pass parameters to shell
            # expecting system to have sh or something compatible
            # TODO: add some special checks for MS Windows
            # using -x to see commands in stderr
            # using -e to terminate fast
            # from dash manual:
            # -e errexit     If not interactive, exit immediately if any
            #                untested command fails.  The exit status of a com‐
            #                mand is considered to be explicitly tested if the
            #                command is used to control an if, elif, while, or
            #                until; or if the command is the left hand operand
            #                of an '&&' or '||' operator.
            p = subprocess.Popen(
                ["sh", "-e", "-x", module.abs_file_path],
                cwd=cwd,
                env=env,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
        else:
            p = subprocess.Popen(
                [module.abs_file_path],
                cwd=cwd,
                env=env,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
        stdout, stderr = p.communicate()
        returncode = p.returncode
        encodings = [_get_encoding(), "utf8", "latin-1", "ascii"]

        def try_decode(data, encodings):
            """Try to decode data (bytes) using one of encodings

            Falls back to decoding as UTF-8 with replacement for bytes.
            Strings are returned unmodified.
            """
            for encoding in encodings:
                try:
                    return decode(data, encoding=encoding)
                except UnicodeError:
                    pass
            if isinstance(data, bytes):
                return data.decode(encoding="utf-8", errors="replace")
            return data

        stdout = try_decode(stdout, encodings=encodings)
        stderr = try_decode(stderr, encodings=encodings)

        with open(stdout_path, "w") as stdout_file:
            stdout_file.write(stdout)
        with open(stderr_path, "w") as stderr_file:
            if type(stderr) == "bytes":
                stderr_file.write(decode(stderr))
            else:
                if isinstance(stderr, str):
                    stderr_file.write(stderr)
                else:
                    stderr_file.write(stderr.encode("utf8"))
        self._file_anonymizer.anonymize([stdout_path, stderr_path])

        test_summary = update_keyval_file(
            os.path.join(os.path.abspath(cwd), "test_keyvalue_result.txt"),
            module=module,
            returncode=returncode,
        )
        self.reporter.end_file_test(
            module=module,
            cwd=cwd,
            returncode=returncode,
            stdout=stdout_path,
            stderr=stderr_path,
            test_summary=test_summary,
        )
        # TODO: add some try-except or with for better error handling
        os.remove(gisrc)
        # TODO: only if clean up
        if self.clean_mapsets:
            shutil.rmtree(mapset_dir)
Пример #7
0
def export_png_in_projection(src_mapset_name,
                             map_name,
                             output_file,
                             epsg_code,
                             routpng_flags,
                             compression,
                             wgs84_file,
                             use_region=True):
    """

    :param use_region: use computation region and not map extent
    """
    if use_region:
        src_region = get_region()
        src_proj_string = get_location_proj_string()

    # TODO: change only location and not gisdbase?
    # we rely on the tmp dir having enough space for our map
    tgt_gisdbase = tempfile.mkdtemp()
    # this is not needed if we use mkdtemp but why not
    tgt_location = 'r.out.png.proj_location_%s' % epsg_code
    # because we are using PERMANENT we don't have to create mapset explicitly
    tgt_mapset_name = 'PERMANENT'

    src_mapset = Mapset(name=src_mapset_name, use_current=True)
    assert src_mapset.exists()

    # get source (old) and set target (new) GISRC enviromental variable
    # TODO: set environ only for child processes could be enough and it would
    # enable (?) parallel runs
    src_gisrc = os.environ['GISRC']
    tgt_gisrc = gsetup.write_gisrc(tgt_gisdbase, tgt_location, tgt_mapset_name)
    os.environ['GISRC'] = tgt_gisrc
    # we do this only after we obtained region, so it was applied
    # and we don't need it in the temporary (tgt) mapset
    if os.environ.get('WIND_OVERRIDE'):
        old_temp_region = os.environ['WIND_OVERRIDE']
        del os.environ['WIND_OVERRIDE']
    else:
        old_temp_region = None

    tgt_mapset = Mapset(tgt_gisdbase, tgt_location, tgt_mapset_name)

    try:
        # the function itself is not safe for other (backgroud) processes
        # (e.g. GUI), however we already switched GISRC for us
        # and child processes, so we don't influece others
        gs.create_location(dbase=tgt_gisdbase,
                           location=tgt_location,
                           epsg=epsg_code,
                           datum=None,
                           datum_trans=None)
        assert tgt_mapset.exists()

        # we need to make the mapset change in the current GISRC (tgt)
        # note that the C library for this process still holds the
        # path to the old GISRC file (src)
        tgt_mapset.set_as_current(gisrc=tgt_gisrc)

        # setting region
        if use_region:
            # respecting computation region of the src location
            # by previous use g.region in src location
            # and m.proj and g.region now
            # respecting MASK of the src location would be hard
            # null values in map are usually enough
            tgt_proj_string = get_location_proj_string()
            tgt_region = reproject_region(src_region,
                                          from_proj=src_proj_string,
                                          to_proj=tgt_proj_string)
            # uses g.region thus and sets region only for child processes
            # which is enough now
            # TODO: unlike the other branch, this keeps the current
            # resolution which is not correct
            set_region(tgt_region)
        else:
            # find out map extent to import everything
            # using only classic API because of some problems with pygrass
            # on ms windows
            rproj_out = gs.read_command('r.proj',
                                        input=map_name,
                                        dbase=src_mapset.database,
                                        location=src_mapset.location,
                                        mapset=src_mapset.name,
                                        output=map_name,
                                        flags='g')
            a = gs.parse_key_val(rproj_out, sep='=', vsep=' ')
            gs.run_command('g.region', **a)

        # map import
        gs.message("Reprojecting...")
        gs.run_command('r.proj',
                       input=map_name,
                       dbase=src_mapset.database,
                       location=src_mapset.location,
                       mapset=src_mapset.name,
                       output=map_name,
                       quiet=True)

        # actual export
        gs.message("Rendering...")
        raster_to_png(map_name,
                      output_file,
                      compression=compression,
                      routpng_flags=routpng_flags)

        # outputting file with WGS84 coordinates
        if wgs84_file:
            gs.verbose("Projecting coordinates to LL WGS 84...")
            with open(wgs84_file, 'w') as data_file:
                if use_region:
                    # map which is smaller than region is imported in its own
                    # small extent, but we export image in region, so we need
                    # bounds to be for region, not map
                    # hopefully this is consistent with r.out.png behavior
                    data_file.write(
                        map_extent_to_file_content(proj_to_wgs84(get_region()))
                        + '\n')
                else:
                    # use map to get extent
                    # the result is actually the same as using map
                    # if region is the same as map (use_region == False)
                    data_file.write(
                        map_extent_to_file_content(
                            get_map_extent_for_location(map_name)) + '\n')

    finally:
        # juts in case we need to do something in the old location
        # our callers probably do
        os.environ['GISRC'] = src_gisrc
        if old_temp_region:
            os.environ['WIND_OVERRIDE'] = old_temp_region
        # set current in library
        src_mapset.set_as_current(gisrc=src_gisrc)

        # delete the whole gisdbase
        # delete file by file to ensure that we are deleting only our things
        # exception will be raised when removing non-empty directory
        tgt_mapset.delete()
        os.rmdir(tgt_mapset.location_path)
        # dir created by tempfile.mkdtemp() needs to be romved manually
        os.rmdir(tgt_gisdbase)
        # we have to remove file created by tempfile.mkstemp function
        # in write_gisrc function
        os.remove(tgt_gisrc)
Пример #8
0
def export_png_in_projection(src_mapset_name, map_name, output_file,
                             epsg_code,
                             routpng_flags, compression, wgs84_file,
                             use_region=True):
    """

    :param use_region: use computation region and not map extent
    """
    if use_region:
        src_region = get_region()
        src_proj_string = get_location_proj_string()

    # TODO: change only location and not gisdbase?
    # we rely on the tmp dir having enough space for our map
    tgt_gisdbase = tempfile.mkdtemp()
    # this is not needed if we use mkdtemp but why not
    tgt_location = 'r.out.png.proj_location_%s' % epsg_code
    # because we are using PERMANENT we don't have to create mapset explicitly
    tgt_mapset_name = 'PERMANENT'

    src_mapset = Mapset(name=src_mapset_name, use_current=True)
    assert src_mapset.exists()

    # get source (old) and set target (new) GISRC enviromental variable
    # TODO: set environ only for child processes could be enough and it would
    # enable (?) parallel runs
    src_gisrc = os.environ['GISRC']
    tgt_gisrc = gsetup.write_gisrc(tgt_gisdbase,
                                   tgt_location, tgt_mapset_name)
    os.environ['GISRC'] = tgt_gisrc
    # we do this only after we obtained region, so it was applied
    # and we don't need it in the temporary (tgt) mapset
    if os.environ.get('WIND_OVERRIDE'):
        old_temp_region = os.environ['WIND_OVERRIDE']
        del os.environ['WIND_OVERRIDE']
    else:
        old_temp_region = None

    tgt_mapset = Mapset(tgt_gisdbase, tgt_location, tgt_mapset_name)

    try:
        # the function itself is not safe for other (backgroud) processes
        # (e.g. GUI), however we already switched GISRC for us
        # and child processes, so we don't influece others
        gs.create_location(dbase=tgt_gisdbase,
                           location=tgt_location,
                           epsg=epsg_code,
                           datum=None,
                           datum_trans=None)
        assert tgt_mapset.exists()

        # we need to make the mapset change in the current GISRC (tgt)
        # note that the C library for this process still holds the
        # path to the old GISRC file (src)
        tgt_mapset.set_as_current(gisrc=tgt_gisrc)

        # setting region
        if use_region:
            # respecting computation region of the src location
            # by previous use g.region in src location
            # and m.proj and g.region now
            # respecting MASK of the src location would be hard
            # null values in map are usually enough
            tgt_proj_string = get_location_proj_string()
            tgt_region = reproject_region(src_region,
                                          from_proj=src_proj_string,
                                          to_proj=tgt_proj_string)
            # uses g.region thus and sets region only for child processes
            # which is enough now
            # TODO: unlike the other branch, this keeps the current
            # resolution which is not correct
            set_region(tgt_region)
        else:
            # find out map extent to import everything
            # using only classic API because of some problems with pygrass
            # on ms windows
            rproj_out = gs.read_command('r.proj', input=map_name,
                                        dbase=src_mapset.database,
                                        location=src_mapset.location,
                                        mapset=src_mapset.name,
                                        output=map_name, flags='g')
            a = gs.parse_key_val(rproj_out, sep='=', vsep=' ')
            gs.run_command('g.region', **a)

        # map import
        gs.message("Reprojecting...")
        gs.run_command('r.proj', input=map_name, dbase=src_mapset.database,
                       location=src_mapset.location, mapset=src_mapset.name,
                       output=map_name, quiet=True)

        # actual export
        gs.message("Rendering...")
        raster_to_png(map_name, output_file, compression=compression,
                      routpng_flags=routpng_flags)

        # outputting file with WGS84 coordinates
        if wgs84_file:
            gs.verbose("Projecting coordinates to LL WGS 84...")
            with open(wgs84_file, 'w') as data_file:
                if use_region:
                    # map which is smaller than region is imported in its own
                    # small extent, but we export image in region, so we need
                    # bounds to be for region, not map
                    # hopefully this is consistent with r.out.png behavior
                    data_file.write(
                        map_extent_to_file_content(
                            proj_to_wgs84(get_region())) + '\n')
                else:
                    # use map to get extent
                    # the result is actually the same as using map
                    # if region is the same as map (use_region == False)
                    data_file.write(
                        map_extent_to_file_content(
                            get_map_extent_for_location(map_name)) +
                        '\n')

    finally:
        # juts in case we need to do something in the old location
        # our callers probably do
        os.environ['GISRC'] = src_gisrc
        if old_temp_region:
            os.environ['WIND_OVERRIDE'] = old_temp_region
        # set current in library
        src_mapset.set_as_current(gisrc=src_gisrc)

        # delete the whole gisdbase
        # delete file by file to ensure that we are deleting only our things
        # exception will be raised when removing non-empty directory
        tgt_mapset.delete()
        os.rmdir(tgt_mapset.location_path)
        # dir created by tempfile.mkdtemp() needs to be romved manually
        os.rmdir(tgt_gisdbase)
        # we have to remove file created by tempfile.mkstemp function
        # in write_gisrc function
        os.remove(tgt_gisrc)
Пример #9
0
 def __init__(
     self,
     cmd,
     width=None,
     height=None,
     overlap=0,
     processes=None,
     split=False,
     debug=False,
     region=None,
     move=None,
     log=False,
     start_row=0,
     start_col=0,
     out_prefix="",
     mapset_prefix=None,
     *args,
     **kargs,
 ):
     kargs["run_"] = False
     self.mset = Mapset()
     self.module = Module(cmd, *args, **kargs)
     self.width = width
     self.height = height
     self.overlap = overlap
     self.processes = processes
     self.region = region if region else Region()
     self.start_row = start_row
     self.start_col = start_col
     self.out_prefix = out_prefix
     self.log = log
     self.move = move
     self.gisrc_src = os.environ["GISRC"]
     self.n_mset, self.gisrc_dst = None, None
     if self.move:
         self.n_mset = copy_mapset(self.mset, self.move)
         self.gisrc_dst = write_gisrc(self.n_mset.gisdbase,
                                      self.n_mset.location,
                                      self.n_mset.name)
         rasters = [r for r in select(self.module.inputs, "raster")]
         if rasters:
             copy_rasters(rasters,
                          self.gisrc_src,
                          self.gisrc_dst,
                          region=self.region)
         vectors = [v for v in select(self.module.inputs, "vector")]
         if vectors:
             copy_vectors(vectors, self.gisrc_src, self.gisrc_dst)
         groups = [g for g in select(self.module.inputs, "group")]
         if groups:
             copy_groups(groups,
                         self.gisrc_src,
                         self.gisrc_dst,
                         region=self.region)
     self.bboxes = split_region_tiles(region=region,
                                      width=width,
                                      height=height,
                                      overlap=overlap)
     if mapset_prefix:
         self.mapset_prefix = mapset_prefix
     else:
         self.mapset_prefix = append_node_pid("grid_" +
                                              legalize_vector_name(cmd))
     self.msetstr = self.mapset_prefix + "_%03d_%03d"
     self.inlist = None
     if split:
         self.split()
     self.debug = debug
Пример #10
0
    def _run_test_module(self, module, results_dir, gisdbase, location):
        """Run one test file."""
        self.testsuite_dirs[module.tested_dir].append(module.name)
        cwd = os.path.join(results_dir, module.tested_dir, module.name)
        data_dir = os.path.join(module.file_dir, 'data')
        if os.path.exists(data_dir):
            # TODO: link dir instead of copy tree and remove link afterwads
            # (removing is good because of testsuite dir in samplecode)
            # TODO: use different dir name in samplecode and test if it works
            shutil.copytree(data_dir, os.path.join(cwd, 'data'),
                            ignore=shutil.ignore_patterns('*.svn*'))
        ensure_dir(os.path.abspath(cwd))
        # TODO: put this to constructor and copy here again
        env = os.environ.copy()
        mapset, mapset_dir = self._create_mapset(gisdbase, location, module)
        gisrc = gsetup.write_gisrc(gisdbase, location, mapset)
        env['GISRC'] = gisrc

        stdout_path = os.path.join(cwd, 'stdout.txt')
        stderr_path = os.path.join(cwd, 'stderr.txt')
        stdout = open(stdout_path, 'w')
        stderr = open(stderr_path, 'w')

        self.reporter.start_file_test(module)
        # TODO: we might clean the directory here before test if non-empty

        if module.file_type == 'py':
            # ignoring shebang line to use current Python
            # and also pass parameters to it
            # add also '-Qwarn'?
            p = subprocess.Popen([sys.executable, '-tt', '-3',
                                  module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=stdout, stderr=stderr)
        elif module.file_type == 'sh':
            # ignoring shebang line to pass parameters to shell
            # expecting system to have sh or something compatible
            # TODO: add some special checks for MS Windows
            # using -x to see commands in stderr
            # using -e to terminate fast
            # from dash manual:
            # -e errexit     If not interactive, exit immediately if any
            #                untested command fails.  The exit status of a com‐
            #                mand is considered to be explicitly tested if the
            #                command is used to control an if, elif, while, or
            #                until; or if the command is the left hand operand
            #                of an '&&' or '||' operator.
            p = subprocess.Popen(['sh', '-e', '-x', module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=stdout, stderr=stderr)
        else:
            p = subprocess.Popen([module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=stdout, stderr=stderr)
        returncode = p.wait()
        stdout.close()
        stderr.close()
        self._file_anonymizer.anonymize([stdout_path, stderr_path])

        test_summary = update_keyval_file(
            os.path.join(cwd, 'test_keyvalue_result.txt'),
            module=module, returncode=returncode)
        self.reporter.end_file_test(module=module, cwd=cwd,
                                    returncode=returncode,
                                    stdout=stdout_path, stderr=stderr_path,
                                    test_summary=test_summary)
        # TODO: add some try-except or with for better error handling
        os.remove(gisrc)
        # TODO: only if clean up
        if self.clean_mapsets:
            shutil.rmtree(mapset_dir)
Пример #11
0
    def _run_test_module(self, module, results_dir, gisdbase, location):
        """Run one test file."""
        self.testsuite_dirs[module.tested_dir].append(module.name)
        cwd = os.path.join(results_dir, module.tested_dir, module.name)
        data_dir = os.path.join(module.file_dir, 'data')
        if os.path.exists(data_dir):
            # TODO: link dir instead of copy tree and remove link afterwads
            # (removing is good because of testsuite dir in samplecode)
            # TODO: use different dir name in samplecode and test if it works
            shutil.copytree(data_dir, os.path.join(cwd, 'data'),
                            ignore=shutil.ignore_patterns('*.svn*'))
        ensure_dir(os.path.abspath(cwd))
        # TODO: put this to constructor and copy here again
        env = os.environ.copy()
        mapset, mapset_dir = self._create_mapset(gisdbase, location, module)
        gisrc = gsetup.write_gisrc(gisdbase, location, mapset)

        # here is special setting of environmental variables for running tests
        # some of them might be set from outside in the future and if the list
        # will be long they should be stored somewhere separately

        # use custom gisrc, not current session gisrc
        env['GISRC'] = gisrc
        # percentage in plain format is 0...10...20... ...100
        env['GRASS_MESSAGE_FORMAT'] = 'plain'

        stdout_path = os.path.join(cwd, 'stdout.txt')
        stderr_path = os.path.join(cwd, 'stderr.txt')

        self.reporter.start_file_test(module)
        # TODO: we might clean the directory here before test if non-empty

        if module.file_type == 'py':
            # ignoring shebang line to use current Python
            # and also pass parameters to it
            # add also '-Qwarn'?
            if sys.version_info.major >= 3:
                args = [sys.executable, '-tt', module.abs_file_path]
            else:
                args = [sys.executable, '-tt', '-3', module.abs_file_path]
            p = subprocess.Popen(args, cwd=cwd, env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        elif module.file_type == 'sh':
            # ignoring shebang line to pass parameters to shell
            # expecting system to have sh or something compatible
            # TODO: add some special checks for MS Windows
            # using -x to see commands in stderr
            # using -e to terminate fast
            # from dash manual:
            # -e errexit     If not interactive, exit immediately if any
            #                untested command fails.  The exit status of a com‐
            #                mand is considered to be explicitly tested if the
            #                command is used to control an if, elif, while, or
            #                until; or if the command is the left hand operand
            #                of an '&&' or '||' operator.
            p = subprocess.Popen(['sh', '-e', '-x', module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        else:
            p = subprocess.Popen([module.abs_file_path],
                                 cwd=cwd, env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        stdout, stderr = p.communicate()
        returncode = p.returncode
        encodings = [_get_encoding(), 'utf8', 'latin-1', 'ascii']
        detected = False
        idx = 0
        while not detected:
            try:
                stdout = decode(stdout, encoding=encodings[idx])
                detected = True
            except:
                idx += 1
                pass

        detected = False
        idx = 0
        while not detected:
            try:
                stderr = decode(stderr, encoding=encodings[idx])
                detected = True
            except:
                idx += 1
                pass

        with open(stdout_path, 'w') as stdout_file:
            stdout_file.write(stdout)
        with open(stderr_path, 'w') as stderr_file:
            if type(stderr) == 'bytes':
                stderr_file.write(decode(stderr))
            else:
                if isinstance(stderr, str):
                    stderr_file.write(stderr)
                else:
                    stderr_file.write(stderr.encode('utf8'))
        self._file_anonymizer.anonymize([stdout_path, stderr_path])

        test_summary = update_keyval_file(
            os.path.join(os.path.abspath(cwd), 'test_keyvalue_result.txt'),
            module=module, returncode=returncode)
        self.reporter.end_file_test(module=module, cwd=cwd,
                                    returncode=returncode,
                                    stdout=stdout_path, stderr=stderr_path,
                                    test_summary=test_summary)
        # TODO: add some try-except or with for better error handling
        os.remove(gisrc)
        # TODO: only if clean up
        if self.clean_mapsets:
            shutil.rmtree(mapset_dir)
Пример #12
0
 def __init__(
     self,
     cmd,
     width=None,
     height=None,
     overlap=0,
     processes=None,
     split=False,
     debug=False,
     region=None,
     move=None,
     log=False,
     start_row=0,
     start_col=0,
     out_prefix="",
     mapset_prefix=None,
     patch_backend=None,
     *args,
     **kargs,
 ):
     kargs["run_"] = False
     self.mset = Mapset()
     self.module = Module(cmd, *args, **kargs)
     self.width = width
     self.height = height
     self.overlap = overlap
     self.processes = processes
     self.region = region if region else Region()
     self.start_row = start_row
     self.start_col = start_col
     self.out_prefix = out_prefix
     self.log = log
     self.move = move
     # by default RasterRow is used as previously
     # if overlap > 0, r.patch won't work properly
     if not patch_backend:
         self.patch_backend = "RasterRow"
     elif patch_backend not in ("r.patch", "RasterRow"):
         raise RuntimeError(
             _("Parameter patch_backend must be 'r.patch' or 'RasterRow'"))
     elif patch_backend == "r.patch" and self.overlap:
         raise RuntimeError(
             _("Patching backend 'r.patch' doesn't work for overlap > 0"))
     else:
         self.patch_backend = patch_backend
     self.gisrc_src = os.environ["GISRC"]
     self.n_mset, self.gisrc_dst = None, None
     self.estimate_tile_size()
     if self.move:
         self.n_mset = copy_mapset(self.mset, self.move)
         self.gisrc_dst = write_gisrc(self.n_mset.gisdbase,
                                      self.n_mset.location,
                                      self.n_mset.name)
         rasters = [r for r in select(self.module.inputs, "raster")]
         if rasters:
             copy_rasters(rasters,
                          self.gisrc_src,
                          self.gisrc_dst,
                          region=self.region)
         vectors = [v for v in select(self.module.inputs, "vector")]
         if vectors:
             copy_vectors(vectors, self.gisrc_src, self.gisrc_dst)
         groups = [g for g in select(self.module.inputs, "group")]
         if groups:
             copy_groups(groups,
                         self.gisrc_src,
                         self.gisrc_dst,
                         region=self.region)
     self.bboxes = split_region_tiles(region=region,
                                      width=self.width,
                                      height=self.height,
                                      overlap=overlap)
     if mapset_prefix:
         self.mapset_prefix = mapset_prefix
     else:
         self.mapset_prefix = append_node_pid("grid_" +
                                              legalize_vector_name(cmd))
     self.msetstr = self.mapset_prefix + "_%03d_%03d"
     self.inlist = None
     if split:
         self.split()
     self.debug = debug