Example #1
0
def read_yaml_test(yaml_file):
    with open(yaml_file) as data_file:
        data = None
        try:
            data = yaml.load(data_file)
        except yaml.YAMLError:
            error_handler.call_error(
                Errors.INVALID_JSON,
                bcolors.bold(yaml_file) + " has invalid syntax")
        return data
Example #2
0
def read_json_test(json_file):
    with open(json_file) as data_file:
        data = None
        try:
            data = json.load(data_file)
        except ValueError:
            error_handler.call_error(
                Errors.INVALID_JSON,
                bcolors.bold(json_file) + " has invalid syntax")
    return data
Example #3
0
def load_config(ar, config_file=None):
    """
    :param ar arguments class

    :param config_file name of config file
    """
    data = list()
    if config_file is None:
        config_file = config_yaml
        my_file = Path(config_file)
        if my_file.is_file():
            if yaml_support:
                data = load_yaml(config_file)
            else:
                error_handler.call_error(Errors.YAML_DOESNT_SUPPORT,
                                         "Can't use " + config_yaml)
        else:
            config_file = config_json
            my_file = Path(config_file)
            if my_file.is_file():
                data = load_json(config_file)
            else:
                error_handler.add_suspicion(
                    bcolors.bold(config_yaml) + " or " +
                    bcolors.bold(config_json) +
                    " is missing or can\'t be opened.")
                ar.valid = False
                return
    else:
        my_file = Path(config_file)
        if my_file.is_file():
            file_type = config_file.split('.')[-1]
            if file_type == 'yaml':
                if not yaml_support:
                    error_handler.call_error(Errors.YAML_DOESNT_SUPPORT)
                else:
                    data = load_yaml(config_file)
            elif file_type == 'json':
                data = load_json(config_file)
            else:
                error_handler.add_suspicion(
                    bcolors.bold(config_file) +
                    " have to end with .json or .yaml")
                ar.valid = False
                return

        else:
            error_handler.add_suspicion(
                bcolors.bold(config_file) + " is missing or can\'t be opened.")
            ar.valid = False
            return
    parse_config(ar, config_file, data)
Example #4
0
def test_set_missing(test, test_directory, test_json_file):
    """
    try to recover from missing values

    :param test test class

    :param test_directory directory with test

    :param test_json_file json file
    """
    real_out = ""
    if test.output is not None:
        output = test_directory + test.output
        output_path = Path(output)
        if not output_path.is_file():
            error_handler.call_error(Errors.MISSING_FILE,
                                     bcolors.bold(output) + " is missing")
        with open(output) as input_file:
            real_out = input_file.read()
    input_data = None
    if test.input is not None:
        input = test_directory + test.input
        input_path = Path(input)
        if not input_path.is_file():
            error_handler.call_error(Errors.MISSING_FILE,
                                     bcolors.bold(input) + " is missing")
        with open(input) as input_file:
            input_data = bytes(input_file.read(), "UTF-8")
    if test.is_not_set():
        error_handler.call_warning(
            bcolors.bold(test_directory) + " is not valid test directory. " +
            bcolors.bold("Skipping test!"))
        score['SKIP'].append(test_directory)
        return None, None, False
    if test.code is None:
        test.code = 0
        error_handler.warning("key " + bcolors.bold("returnCode") + " in " +
                              test_json_file +
                              " is missing. Using default value: " +
                              bcolors.bold(str(test.code)))
    error_handler.call_warning()
    return input_data, real_out, True
Example #5
0
def parse_command_line_init_test(arguments, ar=Test()):
    i = 0
    while i < len(arguments):
        arg = arguments[i]
        if i == len(arguments) - 1:
            error_handler.call_error(
                Errors.WRONG_PARAM,
                "Wrong argument or incomplete argument " + bcolors.bold(arg))
            break
        next_arg = arguments[i + 1]
        i += 1
        if arg == '-i' or arg == '--input':
            ar.input = next_arg
        elif arg == '-o' or arg == '--output':
            ar.output = next_arg
        elif arg == '-n' or arg == '--name':
            ar.name = next_arg
        elif arg == '-r' or arg == '--return-code':
            if is_int(next_arg):
                ar.code = int(next_arg)
            else:
                error_handler.call_error(
                    Errors.WRONG_PARAM,
                    "Incompatible value for " + bcolors.bold(arg))
        elif arg == '-c' or arg == '--comment':
            ar.comment = next_arg
        elif arg == '-T' or arg == '--timeout':
            if is_int(next_arg):
                ar.timeout = int(next_arg)
            else:
                error_handler.call_error(
                    Errors.WRONG_PARAM,
                    "Incompatible value for " + bcolors.bold(arg))

        else:
            error_handler.call_error(
                Errors.WRONG_PARAM,
                "Wrong argument or incomplete argument " + bcolors.bold(arg))
            break
        i += 1
    return ar
Example #6
0
def lets_test(arguments):
    arguments = argstest.parse_args_test(arguments)
    if not arguments.valid:
        error_handler.call_error(Errors.WRONG_PARAM)
    if arguments.hlp:
        argstest.print_help()
        exit(0)
    elif arguments.version:
        print("Tester version - " + version)
        exit(0)
    if arguments.executable is None:
        error_handler.call_error(Errors.WRONG_PARAM, "Executable is not set")

    # init test variables
    my_test.executable = arguments.executable
    my_test.only_failed = arguments.onlyFailed
    my_test.resultDir = arguments.result_dir
    my_test.timeout = arguments.timeout
    my_test.exclude = arguments.exclude
    error_handler.no_warnings = arguments.no_warnings
    my_test.no_diff = arguments.no_diff
    # clearing result directory
    result_name = arguments.result_dir
    result_path = Path(result_name)
    if result_path.exists():
        if not result_path.is_dir():
            error_handler.call_error(
                Errors.WRONG_PARAM,
                bcolors.bold(result_name) + " is not a directory")
        else:
            rmtree(result_name)
    if arguments.clean:
        print(bcolors.note(arguments.result_dir) + " removed")
        exit(0)
    if arguments.tests_dir is None and arguments.test is None:
        error_handler.call_error(Errors.WRONG_INPUT, "No tests")
    if arguments.test is not None:
        my_test.run(arguments.test)
    elif arguments.tests_dir is not None:
        my_test.run_all(arguments.tests_dir)
    my_test.show_score()
Example #7
0
def read_test_file(test, test_file, data):
    """
    read test.json

    :param test test class

    :param test_file json file

    :param data file data
    """

    for key in data.keys():
        if key == 'input':
            if isinstance(data[key], str):
                test.input = data[key]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('input') + " in " + bcolors.bold(test_file) +
                    " has to be string")
        elif key == 'output':
            if isinstance(data[key], str):
                test.output = data[key]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('output') + " in " + bcolors.bold(test_file) +
                    " has to be string")
        elif key == 'comment':
            if isinstance(data[key], str):
                test.comment = data[key]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('comment') + " in " +
                    bcolors.bold(test_file) + " has to be string")
        elif key == 'returnCode':
            if isinstance(data[key], int):
                test.code = data[key]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('returnCode') + " in " +
                    bcolors.bold(test_file) + " has to be int")
        elif key == 'timeout':
            if isinstance(data[key], int) and data[key] > 0:
                test.timeout = data[key]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('timeout') + " in " +
                    bcolors.bold(test_file) + " has to be int bigger than 0")
        elif key == 'args':
            if isinstance(data[key], list):
                test.args = data[key]
            elif isinstance(data[key], str):
                test.args = [data[key]]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('args') + " in " + bcolors.bold(test_file) +
                    " has to be array, string")
        elif key == 'expectedFiles':
            if isinstance(data[key], list):
                test.expected_files = data[key]
            elif isinstance(data[key], str):
                test.expected_files = [data[key]]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('expectedFiles') + " in " +
                    bcolors.bold(test_file) + " has to be array or string")
        elif key == 'outputFiles':
            if isinstance(data[key], list):
                test.output_files = data[key]
            elif isinstance(data[key], str):
                test.output_files = [data[key]]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    bcolors.bold('output_files') + " in " +
                    bcolors.bold(test_file) + " has to be array or string")
        else:
            error_handler.warning("Unknown key \'" + bcolors.note(key) +
                                  "\' in " + test_file)
    if len(test.output_files) != len(test.expected_files):
        error_handler.call_error(
            Errors.FATAL_ERROR,
            "Count of files in " + bcolors.bold('outputFiles') + " and " +
            bcolors.bold('expectedFiles') + " is different")
Example #8
0
def run(test_directory):
    """
    run test and store results

    :param test_directory test directory
    """
    # exclude
    if check_exclude(test_directory):
        return
    if test_directory[-1] != '/':
        test_directory += '/'
    test_d = Path(test_directory)
    if not test_d.is_dir():
        error_handler.call_error(
            Errors.WRONG_INPUT,
            bcolors.bold(test_directory) + " does not exists or is not folder")
    test = Test()
    test_json_file = test_directory + test_file_name + ".json"
    test_yaml_file = test_directory + test_file_name + ".yaml"
    test_json_file_path = Path(test_json_file)
    test_yaml_file_path = Path(test_yaml_file)
    test.timeout = timeout
    yaml_exists = test_yaml_file_path.is_file()
    if not (yaml_exists or test_json_file_path.is_file()):
        missing_test(test, test_directory)
    else:
        test_file = None
        data = None
        if yaml_exists:
            if yaml_support:
                test_file = test_yaml_file
                data = read_yaml_test(test_file)
            else:
                error_handler.call_error(
                    Errors.YAML_DOESNT_SUPPORT,
                    "Can not read " + bcolors.note(test_file_name + ".yaml"))
        else:
            test_file = test_json_file
            data = read_json_test(test_file)
        read_test_file(test, test_file, data)
    input_data, real_out, valid = test_set_missing(test, test_directory,
                                                   test_json_file)
    if not valid:
        return
    cm = ""
    if test.args is not None and len(test.args) > 0:
        cm = ' '.join(test.args)
        cm = ' ' + cm
    cmd = (executable + cm)
    process = Popen(cmd.split(' '), stdout=PIPE, stderr=PIPE, stdin=PIPE)
    out = None
    err = None
    runout = False
    if input_data is None:
        try:
            out, err = process.communicate(timeout=test.timeout)
        except TimeoutExpired:
            process.kill()
            runout = True
    else:
        try:
            out, err = process.communicate(input=input_data,
                                           timeout=test.timeout)
        except TimeoutExpired:
            process.kill()
            runout = True

    proc_out = ""
    if out is not None:
        proc_out = out.decode('utf-8')
    proc_err = ""
    if err is not None:
        proc_err = err.decode('utf-8')
    if runout:
        score["FAIL"].append(test_directory)
        print(bcolors.note(test_directory) + ":")
        if test.comment != "":
            print("\t" + bcolors.warning(test.comment))
        print(bcolors.warning("\tRequest timed out"))
        print(bcolors.fail('\tTest FAILED\n'))
        return
    proc_rc = -9
    if process.returncode is not None:
        proc_rc = int(process.returncode)

    result_code = test.code == proc_rc
    result_out = real_out == proc_out
    result_files = None
    missing_files = list()
    wrong_files = list()
    if len(test.output_files) > 0:
        result_files = True
        i = 0
        while i < len(test.expected_files):
            exp = test_directory + test.expected_files[i]
            exp_path = Path(exp)
            p_out = test.output_files[i]
            p_out_path = Path(p_out)
            v = True
            if not exp_path.is_file():
                missing_files.append(exp)
                result_files = False
                v = False
            if not p_out_path.is_file():
                missing_files.append(p_out)
                result_files = False
                v = False
            if v:
                with open(exp, "r") as myfile:
                    exp_data = myfile.read()
                with open(p_out, "r") as myfile:
                    out_data = myfile.read()
                if exp_data == out_data:
                    result_files = result_files and True
                else:
                    result_files = False
                    d_out = out_data.strip().splitlines()
                    d_exp = exp_data.strip().splitlines()
                    diff = list()
                    for line in difflib.unified_diff(d_exp,
                                                     d_out,
                                                     test.expected_files[i],
                                                     p_out,
                                                     n=0,
                                                     lineterm=''):
                        diff.append(line)
                    diff = "\n".join(diff) + "\n"
                    wrong_files.append([exp, p_out, diff])

            i += 1
    result = result_code and result_out
    if result_files is not None:
        result = result and result_files
    if result:
        score["OK"].append(test_directory)
        if not only_failed:
            print(bcolors.note(test_directory) + ":")
            print(bcolors.success('\tTest OK\n'))
    else:
        test_failed(proc_err, proc_out, proc_rc, real_out, result_code,
                    result_out, result_files, test, test_directory,
                    missing_files, wrong_files)
Example #9
0
def parse_config(ar, config_file, data):
    for key in data.keys():
        if key == 'onlyFailed':
            if isinstance(data[key], bool):
                ar.onlyFailed = data[key]
            else:
                error_handler.call_error(Errors.INVALID_JSON,
                                         "OnlyFailed has to be bool")
        elif key == 'noWarnings':
            if isinstance(data[key], bool):
                ar.no_warnings = data[key]
            else:
                error_handler.call_error(Errors.INVALID_JSON,
                                         "noWarnings has to be bool")
        elif key == 'noDiff':
            if isinstance(data[key], bool):
                ar.no_diff = data[key]
            else:
                error_handler.call_error(Errors.INVALID_JSON,
                                         "noDiff has to be bool")
        elif key == "testsDir":
            if isinstance(data[key], str):
                ar.tests_dir = data[key]
                if ar.tests_dir[-1] != '/':
                    ar.tests_dir += '/'
            else:
                error_handler.call_error(Errors.INVALID_JSON,
                                         "testsDirectory has to be string")
        elif key == "resultDir":
            if isinstance(data[key], str):
                ar.result_dir = data[key]
                if ar.result_dir[-1] != '/':
                    ar.result_dir += '/'
            else:
                error_handler.call_error(Errors.INVALID_JSON,
                                         "resultDirectory has to be string")
        elif key == "timeout":
            if isinstance(data[key], int) and data[key] > 0:
                ar.timeout = data[key]
            else:
                error_handler.call_error(
                    Errors.INVALID_JSON,
                    "timeout has to be int and greater than 0")
        elif key == "exclude":
            if isinstance(data[key], str):
                if data[key] != "":
                    ar.exclude = [data[key]]
            elif isinstance(data[key], list):
                ar.exclude = data[key]
            else:
                error_handler.call_error(Errors.INVALID_JSON,
                                         "exclude has to be string or array")
        elif key == "executable":
            if isinstance(data[key], str):
                ar.executable = data[key]
            else:
                error_handler.call_error(Errors.INVALID_JSON,
                                         "executable has to be string path")
        else:
            error_handler.warning("Unknown key \'" + bcolors.note(key) +
                                  "\' in " + config_file)
Example #10
0
def lets_init(arguments):
    if arguments[0] == 'init':
        if len(arguments) > 1 and arguments[1] == '--json':
            arg = arguments.copy()
            arg.pop(0)
            arg.pop(0)
            use_all = False
            force = False
            if len(arg) > 0:
                if arg[0] == '--all':
                    arg.pop(0)
                    use_all = True
                if len(arg) > 0 and arg[0] == '--force':
                    arg.pop(0)
                    force = True
            json_file_path = Path(argstest.config_json)
            arg = argstest.parse_command_line_init(arg)
            if not arg.valid:
                error_handler.call_error(Errors.WRONG_PARAM)
            if arg.hlp:
                argstest.print_init_help()
                exit(0)
            arg = arg.export(use_all)
            json_data = json.dumps(arg, indent=4)
            if json_file_path.exists():
                if force:
                    error_handler.call_warning("Rewriting " + bcolors.note(argstest.config_json))
                else:
                    error_handler.call_error(Errors.FATAL_ERROR, bcolors.note(argstest.config_json) +
                                             " already exists. If you want to rewrite it use --force option")
            with open(argstest.config_json, "w") as json_file:
                print(json_data, file=json_file)
            print(bcolors.success("Success: ") + argstest.config_json + ' created')

        else:
            if not yaml_support:
                error_handler.call_error(Errors.YAML_DOESNT_SUPPORT, "Can not export to yaml")
            arg = arguments.copy()
            arg.pop(0)
            use_all = False
            force = False
            if len(arg) > 0:
                if arg[0] == '--all':
                    arg.pop(0)
                    use_all = True
                if len(arg) > 0 and arg[0] == '--force':
                    arg.pop(0)
                    force = True
            arg = argstest.parse_command_line_init(arg)
            if not arg.valid:
                error_handler.call_error(Errors.WRONG_PARAM)
            if arg.hlp:
                argstest.print_init_help()
                exit(0)
            arg = arg.export(use_all)
            yaml_data = yaml.dump(arg, explicit_start=True, default_flow_style=False)
            yaml_file_path = Path(argstest.config_yaml)
            if yaml_file_path.exists():
                if force:
                    error_handler.call_warning("Rewriting " + bcolors.note(argstest.config_yaml))
                else:
                    error_handler.call_error(Errors.FATAL_ERROR, bcolors.note(argstest.config_yaml) +
                                             " already exists. If you want to rewrite it use --force option")
            with open(argstest.config_yaml, "w") as yaml_file:
                print(yaml_data, file=yaml_file)
            print(bcolors.success("Success: ") + argstest.config_yaml + ' created')

    elif arguments[0] == 'testinit':
        if len(arguments) > 1 and arguments[1] == '--json':
            arg = arguments.copy()
            arg.pop(0)
            arg.pop(0)
            use_all = False
            force = False
            if '-h' in arg:
                argstest.print_testinit_help()
                exit(0)
            if len(arg) > 0:
                if arg[0] == '--all':
                    arg.pop(0)
                    use_all = True
                if len(arg) > 0 and arg[0] == '--force':
                    arg.pop(0)
                    force = True
            arg = argstest.parse_command_line_init_test(arg)
            name = my_test.test_file_name_json
            if arg.name is not None:
                if arg.name[-1] != '/':
                    arg.name += '/'
                    makedirs(arg.name)
                name = arg.name + name
            arg = arg.export(use_all)
            json_data = json.dumps(arg, indent=4)
            json_file_path = Path(name)
            if json_file_path.exists():
                if force:
                    error_handler.call_warning("Rewriting " + bcolors.note(name))
                else:
                    error_handler.call_error(Errors.FATAL_ERROR, bcolors.note(name) +
                                             " already exists. If you want to rewrite it use --force option")
            with open(name, "w") as json_file:
                print(json_data, file=json_file)
            print(bcolors.success("Success: ") + name + ' created')

        else:
            if not yaml_support:
                error_handler.call_error(Errors.YAML_DOESNT_SUPPORT, "Can not export to yaml")
            arg = arguments.copy()
            arg.pop(0)
            use_all = False
            force = False
            if '-h' in arg:
                argstest.print_testinit_help()
                exit(0)
            if len(arg) > 0:
                if arg[0] == '--all':
                    arg.pop(0)
                    use_all = True
                if len(arg) > 0 and arg[0] == '--force':
                    arg.pop(0)
                    force = True
            arg = argstest.parse_command_line_init_test(arg)
            name = my_test.test_file_name_yaml
            if arg.name is not None:
                if arg.name[-1] != '/':
                    arg.name += '/'
                    makedirs(arg.name)
                name = arg.name + name
            arg = arg.export(use_all)
            yaml_data = yaml.dump(arg, explicit_start=True, default_flow_style=False)
            json_file_path = Path(name)
            if json_file_path.exists():
                if force:
                    error_handler.call_warning("Rewriting " + bcolors.note(name))
                else:
                    error_handler.call_error(Errors.FATAL_ERROR, bcolors.note(name) +
                                             " already exists. If you want to rewrite it use --force option")
            with open(name, "w") as yaml_file:
                print(yaml_data, file=yaml_file)
            print(bcolors.success("Success: ") + name + ' created')