def read()

in osbenchmark/workload/loader.py [0:0]


    def read(self, workload_name, workload_spec_file, mapping_dir):
        """
        Reads a workload file, verifies it against the JSON schema and if valid, creates a workload.

        :param workload_name: The name of the workload.
        :param workload_spec_file: The complete path to the workload specification file.
        :param mapping_dir: The directory where the mapping files for this workload are stored locally.
        :return: A corresponding workload instance if the workload file is valid.
        """

        self.logger.info("Reading workload specification file [%s].", workload_spec_file)
        # render the workload to a temporary file instead of dumping it into the logs. It is easier to check for error messages
        # involving lines numbers and it also does not bloat Benchmark's log file so much.
        tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".json")
        try:
            rendered = render_template_from_file(
                workload_spec_file, self.workload_params,
                complete_workload_params=self.complete_workload_params)
            with open(tmp.name, "wt", encoding="utf-8") as f:
                f.write(rendered)
            self.logger.info("Final rendered workload for '%s' has been written to '%s'.", workload_spec_file, tmp.name)
            workload_spec = json.loads(rendered)
        except jinja2.exceptions.TemplateNotFound:
            self.logger.exception("Could not load [%s]", workload_spec_file)
            raise exceptions.SystemSetupError("Workload {} does not exist".format(workload_name))
        except json.JSONDecodeError as e:
            self.logger.exception("Could not load [%s].", workload_spec_file)
            msg = "Could not load '{}': {}.".format(workload_spec_file, str(e))
            if e.doc and e.lineno > 0 and e.colno > 0:
                line_idx = e.lineno - 1
                lines = e.doc.split("\n")
                ctx_line_count = 3
                ctx_start = max(0, line_idx - ctx_line_count)
                ctx_end = min(line_idx + ctx_line_count, len(lines))
                erroneous_lines = lines[ctx_start:ctx_end]
                erroneous_lines.insert(line_idx - ctx_start + 1, "-" * (e.colno - 1) + "^ Error is here")
                msg += " Lines containing the error:\n\n{}\n\n".format("\n".join(erroneous_lines))
            msg += "The complete workload has been written to '{}' for diagnosis.".format(tmp.name)
            raise WorkloadSyntaxError(msg)
        except Exception as e:
            self.logger.exception("Could not load [%s].", workload_spec_file)
            msg = "Could not load '{}'. The complete workload has been written to '{}' for diagnosis.".format(workload_spec_file, tmp.name)
            # Convert to string early on to avoid serialization errors with Jinja exceptions.
            raise WorkloadSyntaxError(msg, str(e))
        # check the workload version before even attempting to validate the JSON format to avoid bogus errors.
        raw_version = workload_spec.get("version", WorkloadFileReader.MAXIMUM_SUPPORTED_TRACK_VERSION)
        try:
            workload_version = int(raw_version)
        except ValueError:
            raise exceptions.InvalidSyntax("version identifier for workload %s must be numeric but was [%s]" % (
                workload_name, str(raw_version)))
        if WorkloadFileReader.MINIMUM_SUPPORTED_TRACK_VERSION > workload_version:
            raise exceptions.BenchmarkError("Workload {} is on version {} but needs to be updated at least to version {} to work with the "
                                        "current version of Benchmark.".format(workload_name, workload_version,
                                                                           WorkloadFileReader.MINIMUM_SUPPORTED_TRACK_VERSION))
        if WorkloadFileReader.MAXIMUM_SUPPORTED_TRACK_VERSION < workload_version:
            raise exceptions.BenchmarkError("Workload {} requires a newer version of Benchmark. "
                        "Please upgrade Benchmark (supported workload version: {}, "
                                        "required workload version: {}).".format(
                                            workload_name,
                                            WorkloadFileReader.MAXIMUM_SUPPORTED_TRACK_VERSION,
                                                                              workload_version))
        try:
            jsonschema.validate(workload_spec, self.workload_schema)
        except jsonschema.exceptions.ValidationError as ve:
            raise WorkloadSyntaxError(
                "Workload '{}' is invalid.\n\nError details: {}\nInstance: {}\nPath: {}\nSchema path: {}".format(
                    workload_name, ve.message, json.dumps(
                        ve.instance, indent=4, sort_keys=True),
                        ve.absolute_path, ve.absolute_schema_path))

        current_workload = self.read_workload(workload_name, workload_spec, mapping_dir)

        unused_user_defined_workload_params = self.complete_workload_params.unused_user_defined_workload_params()
        if len(unused_user_defined_workload_params) > 0:
            err_msg = (
                "Some of your workload parameter(s) {} are not used by this workload; perhaps you intend to use {} instead.\n\n"
                "All workload parameters you provided are:\n"
                "{}\n\n"
                "All parameters exposed by this workload:\n"
                "{}".format(
                    ",".join(opts.double_quoted_list_of(sorted(unused_user_defined_workload_params))),
                    ",".join(opts.double_quoted_list_of(sorted(opts.make_list_of_close_matches(
                        unused_user_defined_workload_params,
                        self.complete_workload_params.workload_defined_params
                    )))),
                    "\n".join(opts.bulleted_list_of(sorted(list(self.workload_params.keys())))),
                    "\n".join(opts.bulleted_list_of(self.complete_workload_params.sorted_workload_defined_params))))

            self.logger.critical(err_msg)
            # also dump the message on the console
            console.println(err_msg)
            raise exceptions.WorkloadConfigError(
                "Unused workload parameters {}.".format(sorted(unused_user_defined_workload_params))
            )
        return current_workload