Esempio n. 1
0
 def parse(self, filepath=None, all_sections=False, paths=[], **kwargs):
     assert filepath, "File Path must be provided"
     root = None
     if "::" in filepath: [filepath, root] = filepath.split("::", 2)
     if not isinstance(paths, list) and isinstance(paths, str):
         paths = [paths]
     filepath = utils.find_file(filepath, paths)
     text = "\n".join(utils.read_lines(filepath))
     tmpl = Environment().from_string(text)
     if root:
         block = tmpl.blocks[root]
         text = "\n".join(block(tmpl.new_context(kwargs)))
         return json.fix(text,
                         "Invalid json file supplied",
                         True,
                         object_pairs_hook=SpyTestDict)
     if not all_sections or not tmpl.blocks:
         text = Environment().from_string(text).render(**kwargs)
         return json.fix(text,
                         "Invalid json file supplied",
                         True,
                         object_pairs_hook=SpyTestDict)
     retval = SpyTestDict()
     for root in tmpl.blocks:
         block = tmpl.blocks[root]
         text = "\n".join(block(tmpl.new_context(**kwargs)))
         retval[root] = json.fix(text,
                                 "Invalid json file supplied",
                                 True,
                                 object_pairs_hook=SpyTestDict)
     return retval
Esempio n. 2
0
def _read_pid(wa):
    file_prefix = os.getenv("SPYTEST_FILE_PREFIX", "results")
    for slave in wa.slaves.values():
        filepath = os.path.join(wa.logs_path, slave.name,
                                "{}_pid.txt".format(file_prefix))
        try:
            slave.pid = utils.read_lines(filepath)[0]
        except:
            pass
Esempio n. 3
0
def ansible_playbook(playbook, host_list, username, password, logs_path=None):

    ansible_cfg = os.path.join(os.path.dirname(__file__), '..', "ansible",
                               "ansible.cfg")
    ansible_cfg = os.path.abspath(ansible_cfg)
    ansible_dir = os.path.dirname(sys.executable)
    ansible_exe = os.path.join(ansible_dir, "ansible-playbook")

    if logs_path: os.environ["ANSIBLE_LOCAL_TEMP"] = logs_path
    os.environ["ANSIBLE_CONFIG"] = ansible_cfg
    # added the SSH_ARGS as environment variable to supress host checking as the nodes
    # in the case would be dut's with dynamic inventory.
    os.environ[
        "ANSIBLE_SSH_ARGS"] = "-o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
    fp = tempfile.NamedTemporaryFile(delete=False)
    _fp_write(fp, "[hosts]\n")
    for host in host_list:
        _fp_write(fp, "{}\n".format(host))
    _fp_write(fp, "[hosts:vars]\n")
    _fp_write(fp, "ansible_user={}\n".format(username))
    _fp_write(fp, "ansible_password={}\n".format(password))
    fp.close()
    configs = "\n".join(utils.read_lines(fp.name))

    cmd = "{} -i {} {}".format(ansible_exe, fp.name, playbook)
    #print("Executing", cmd)
    proc = subprocess.Popen(cmd,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            shell=True)
    out, err = proc.communicate()
    proc.wait()
    os.unlink(fp.name)
    if proc.returncode != 0:
        msg = [
            "Error: Failed to execute ansible playbook '{}'".format(playbook)
        ]
        msg.append("errcode: {} error: ('{}')".format(proc.returncode,
                                                      err.strip()))
        msg.append("output: {}".format(out))
        msg.append("config: {}".format(configs))
        return "\n".join(msg)
    for line in out.splitlines():
        print(line)
    return out
Esempio n. 4
0
def _parse_args(pre_parse=False):

    # pytest hack to let it wotk with absolute paths for testbed and tclist
    parser = argparse.ArgumentParser(description='Process SpyTest arguments.',
                                     add_help=False)
    if pre_parse:
        parser.add_argument("--args-file",
                            action="store",
                            default=None,
                            help="spytest arguments from file path")
    parser.add_argument("--testbed-file",
                        action="store",
                        default=None,
                        help="testbed file path -- default: ./testbed.yaml")
    parser.add_argument("--test-suite",
                        action="append",
                        default=[],
                        help="test suites")
    parser.add_argument("--tclist-file",
                        action="append",
                        default=None,
                        help="test case list file path")
    parser.add_argument("--logs-path",
                        action="store",
                        default=None,
                        help="logs folder -- default: .")
    parser.add_argument("--logs-level",
                        action="store",
                        default="info",
                        help="logs level -- default: info")
    parser.add_argument("--log-level",
                        action="store",
                        dest="logs_level",
                        default="info",
                        help="logs level -- default: info")
    parser.add_argument("--results-prefix",
                        action="store",
                        default=None,
                        help="Prefix to be used for results.")
    parser.add_argument("--file-mode",
                        action="store_true",
                        default=False,
                        help="Execute in file mode -- default: false")
    parser.add_argument("-n",
                        "--numprocesses",
                        action="store",
                        default=None,
                        type=int,
                        help="number of preocessese")
    parser.add_argument("--tclist-bucket",
                        action="append",
                        default=None,
                        help="use test cases from buckets")
    for bucket in range(1, 9):
        parser.add_argument(
            "--bucket-{}".format(bucket),
            action="store",
            default=None,
            nargs="*",
            help="needed topology for bucket-{}.".format(bucket))
    parser.add_argument("--env",
                        action="append",
                        default=[],
                        nargs=2,
                        help="environment variables")
    parser.add_argument("--exclude-devices",
                        action="store",
                        default=None,
                        help="exclude given duts from testbed")
    parser.add_argument("--include-devices",
                        action="store",
                        default=None,
                        help="include given duts from testbed")
    parser.add_argument(
        "--open-config-api",
        action="store",
        default='GNMI',
        help="specified open-config request API type -- default: gNMI")
    parser.add_argument(
        "--noop",
        action="store_true",
        default=False,
        help="No operation, to be used while using optional arguments")
    parser.add_argument("--augment-modules-csv",
                        action="append",
                        default=[],
                        nargs="*",
                        help="Add additional lines to modules.csv")

    args, unknown = parser.parse_known_args()

    # parse the bucket options
    argsdict = vars(args)
    tclist_bucket = ",".join(argsdict["tclist_bucket"] or "")
    bucket_list = []
    for bucket in range(1, 9):
        value = argsdict["bucket_{}".format(bucket)]
        if value is None: continue
        bucket_list.append(str(bucket))
        tclist_bucket = ",".join(bucket_list)
        if not value: continue
        os.environ["SPYTEST_TOPO_{}".format(bucket)] = " ".join(value)

    # update sys.argv with arguments from suite args
    if args.test_suite:
        addl_args = parse_suite_files(args.test_suite)
        print("\nSuite Arguments {}\n".format(" ".join(addl_args)))
        index = sys.argv.index("--test-suite")
        new_argv = []
        new_argv.extend(sys.argv[:index])
        new_argv.extend(addl_args)
        new_argv.extend(sys.argv[index + 2:])
        sys.argv = new_argv
        #print("\nSuite Arguments {}\n".format(" ".join(sys.argv)))
        os.environ["SPYTEST_SUITE_ARGS"] = " ".join(addl_args)
        return _parse_args(pre_parse=pre_parse)

    if pre_parse and args.args_file:
        # read arguments from file
        user_root = env.get("SPYTEST_USER_ROOT")
        if user_root and not os.path.isabs(args.args_file):
            filepath = os.path.join(user_root, args.args_file)
        else:
            filepath = args.args_file
        file_args = []
        for line in utils.read_lines(filepath):
            file_args.extend(utils.split_with_quoted_strings(line))

        # update sys.argv with arguments from file
        index = sys.argv.index("--args-file")
        new_argv = []
        new_argv.extend(sys.argv[:index])
        new_argv.extend(file_args)
        new_argv.extend(sys.argv[index + 2:])
        sys.argv = new_argv

        # update SPYTEST_CMDLINE_ARGS with arguments from file
        app_cmdline = env.get("SPYTEST_CMDLINE_ARGS", "")
        app_args = utils.split_with_quoted_strings(app_cmdline)
        index = app_args.index("--args-file")
        app_new_args = []
        app_new_args.extend(app_args[:index])
        for arg in file_args:
            app_new_args.append("'{}'".format(arg) if " " in arg else arg)
        app_new_args.extend(app_args[index + 2:])
        os.environ["SPYTEST_CMDLINE_ARGS"] = " ".join(app_new_args)

        return _parse_args()

    sys.argv = [sys.argv[0]]
    sys.argv.extend(unknown)

    for name, value in args.env:
        print("setting environment {} = {}".format(name, value))
        os.environ[name] = value

    if args.exclude_devices:
        os.environ["SPYTEST_TESTBED_EXCLUDE_DEVICES"] = args.exclude_devices
        sys.argv.extend(["--exclude-devices", args.exclude_devices])
    if args.include_devices:
        os.environ["SPYTEST_TESTBED_INCLUDE_DEVICES"] = args.include_devices
        sys.argv.extend(["--include-devices", args.include_devices])
    if args.testbed_file:
        os.environ["SPYTEST_TESTBED_FILE"] = args.testbed_file
    if args.tclist_file:
        os.environ["SPYTEST_TCLIST_FILE"] = ",".join(args.tclist_file)
    if args.logs_path:
        os.environ["SPYTEST_LOGS_PATH"] = args.logs_path
    os.environ["SPYTEST_LOGS_LEVEL"] = args.logs_level

    if args.open_config_api:
        os.environ["SPYTEST_OPENCONFIG_API"] = args.open_config_api

    prefix = ""
    prefix = "results"
    if args.results_prefix:
        file_prefix = args.results_prefix
    elif args.file_mode and prefix:
        file_prefix = prefix
    elif tclist_bucket:
        file_prefix = prefix
    elif prefix:
        file_prefix = "{}_{}".format(prefix,
                                     time.strftime("%Y_%m_%d_%H_%M_%S"))
    else:
        file_prefix = "{}".format(time.strftime("%Y_%m_%d_%H_%M_%S"))
    os.environ["SPYTEST_FILE_PREFIX"] = file_prefix

    # filemode is needed in more places
    if args.file_mode:
        os.environ["SPYTEST_FILE_MODE"] = "1"
        sys.argv.append("--file-mode")

    addl_args = parse_batch_args(args.numprocesses, tclist_bucket,
                                 args.augment_modules_csv)
    sys.argv.extend(addl_args)

    seed = utils.get_random_seed()
    print("SPYTEST_RAMDOM_SEED used = {}".format(seed))
    return args
Esempio n. 5
0
    def pytest_runtestloop(self):
        def search_nodeid(entries, nodeid):
            for ent in entries:
                if nodeid == ent.nodeid:
                    return ent
            return None

        def finish_test(item):
            getattr(conn.root, "finish_test")(item.nodeid)

        def get_test(entries):
            while 1:
                nodeid = getattr(conn.root, "get_test")()
                if not nodeid:
                    break
                item = search_nodeid(entries, nodeid)
                if item:
                    return item
            return None

        # connect to batch server
        conn = None
        for _ in range(0, 10):
            try:
                filename = os.path.join(self.logs_path, "..", "batch.server")
                lines = utils.read_lines(filename)
                port = int(lines[0])
                conn = rpyc.connect("127.0.0.1", port)
                if conn and conn.root:
                    break
                time.sleep(2)
            except Exception as exp:
                print("connect to batch server", exp, filename, port)
                time.sleep(2)

        try:
            item_list = []

            # wait for master ready
            is_ready = getattr(conn.root, "is_ready")
            while not is_ready(os.getpid()):
                trace("slave: waiting for master")
                time.sleep(2)

            # get first item
            item = get_test(self.items)
            if item:
                item_list.append(item)

            while 1:
                # check if there is some thing to do
                if not item_list:
                    break

                # get next item
                item = get_test(self.items)
                if item:
                    item_list.append(item)

                # get the item and next for the current execution
                [item, nextitem] = [item_list.pop(0), None]
                if item_list:
                    nextitem = item_list[-1]

                debug("slave: pytest_runtestloop", item, nextitem)
                self.config.hook.pytest_runtest_protocol(item=item,
                                                         nextitem=nextitem)
                finish_test(item)
        except KeyboardInterrupt:
            trace("slave: interrupted")
        conn.close()
        trace("")
        os._exit(0)
Esempio n. 6
0
def ansible_playbook(playbook,
                     host_list,
                     username,
                     password,
                     logs_path=None,
                     trace=False,
                     verbose="",
                     **kwargs):

    ansible_root = os.path.join(os.path.dirname(__file__), '..', "ansible")
    ansible_cfg = os.path.join(ansible_root, "ansible.cfg")
    ansible_cfg = os.path.abspath(ansible_cfg)
    ansible_dir = os.path.dirname(sys.executable)
    ansible_exe = os.path.join(ansible_dir, "ansible-playbook")

    # check if playbook is present
    if not os.path.exists(playbook):
        msgs = ["Playbook file {} is not present".format(playbook)]
        msgs.append("Trying replative to ansible config")
        playbook = os.path.join(ansible_root, playbook)
        if not os.path.exists(playbook):
            msgs.append("Playbook file {} is not present".format(playbook))
            retval = "\n".join(msgs)
            if trace: print("ERR: {}".format(retval))
            return retval

    if logs_path: os.environ["ANSIBLE_LOCAL_TEMP"] = logs_path
    os.environ["ANSIBLE_CONFIG"] = ansible_cfg
    # added the SSH_ARGS as environment variable to supress host checking as the nodes
    # in the case would be dut's with dynamic inventory.
    ssh_args = ["-o ControlMaster=auto"]
    ssh_args.append("-o ControlPersist=60s")
    ssh_args.append("-o UserKnownHostsFile=/dev/null")
    ssh_args.append("-o StrictHostKeyChecking=no")
    os.environ["ANSIBLE_SSH_ARGS"] = " ".join(ssh_args)
    fp = tempfile.NamedTemporaryFile(delete=False)
    _fp_write(fp, "[hosts]\n")
    for host in host_list:
        _fp_write(fp, "{}\n".format(host))
    _fp_write(fp, "[hosts:vars]\n")
    _fp_write(fp, "ansible_user={}\n".format(username))
    _fp_write(fp, "ansible_password={}\n".format(password))
    _fp_write(fp, "ansible_become_password={}\n".format(password))
    for key, value in kwargs.items():
        _fp_write(fp, "{}={}\n".format(key, value))
    fp.close()
    configs = "\n".join(utils.read_lines(fp.name))

    cmd = "{} {} -i {} {}".format(ansible_exe, verbose, fp.name, playbook)
    if trace: print("Executing", cmd)
    proc = subprocess.Popen(cmd,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            shell=True)
    out, err = proc.communicate()
    proc.wait()
    os.unlink(fp.name)
    if proc.returncode != 0:
        msg = [
            "Error: Failed to execute ansible playbook '{}'".format(playbook)
        ]
        msg.append("errcode: {} error: ('{}')".format(proc.returncode,
                                                      err.strip()))
        msg.append("output: {}".format(out))
        msg.append("config:\n{}".format(configs))
        return "\n".join(msg)
    for line in out.splitlines():
        if trace: print("OUT: {}".format(line))
    for line in err.splitlines():
        if trace: print("ERR: {}".format(line))
    return out
Esempio n. 7
0
def _parse_args(pre_parse=False):
    # pytest hack to let it wotk with absolute paths for testbed and tclist
    parser = argparse.ArgumentParser(description='Process SpyTest arguments.',
                                     add_help=False)
    if pre_parse:
        parser.add_argument("--args-file",
                            action="store",
                            default=None,
                            help="spytest arguments from file path")
    parser.add_argument("--testbed-file",
                        action="store",
                        default=None,
                        help="testbed file path -- default: ./testbed.yaml")
    parser.add_argument("--tclist-file",
                        action="store",
                        default=None,
                        help="test case list file path")
    parser.add_argument("--logs-path",
                        action="store",
                        default=None,
                        help="logs folder -- default: .")
    parser.add_argument("--logs-level",
                        action="store",
                        default="info",
                        help="logs level -- default: info")
    parser.add_argument("--log-level",
                        action="store",
                        dest="logs_level",
                        default="info",
                        help="logs level -- default: info")
    parser.add_argument("--results-prefix",
                        action="store",
                        default=None,
                        help="Prefix to be used for results.")
    parser.add_argument("--file-mode",
                        action="store_true",
                        default=False,
                        help="Execute in file mode -- default: false")
    parser.add_argument("-n",
                        "--numprocesses",
                        action="store",
                        default=None,
                        type=int,
                        help="number of preocessese")
    parser.add_argument("--tclist-bucket",
                        action="append",
                        default=None,
                        help="use test cases from buckets")
    parser.add_argument("--env",
                        action="append",
                        default=[],
                        nargs=2,
                        help="environment variables")

    args, unknown = parser.parse_known_args()
    if pre_parse and args.args_file:
        # read arguments from file
        user_root = os.getenv("SPYTEST_USER_ROOT")
        if user_root and not os.path.isabs(args.args_file):
            filepath = os.path.join(user_root, args.args_file)
        else:
            filepath = args.args_file
        file_args = []
        for line in utils.read_lines(filepath):
            file_args.extend(utils.split_with_quoted_strings(line))

        # update sys.argv with arguments from file
        index = sys.argv.index("--args-file")
        new_argv = []
        new_argv.extend(sys.argv[:index])
        new_argv.extend(file_args)
        new_argv.extend(sys.argv[index + 2:])
        sys.argv = new_argv

        # update SPYTEST_CMDLINE_ARGS with arguments from file
        app_cmdline = os.getenv("SPYTEST_CMDLINE_ARGS", "")
        app_args = utils.split_with_quoted_strings(app_cmdline)
        index = app_args.index("--args-file")
        app_new_args = []
        app_new_args.extend(app_args[:index])
        for arg in file_args:
            app_new_args.append("'{}'".format(arg) if " " in arg else arg)
        app_new_args.extend(app_args[index + 2:])
        os.environ["SPYTEST_CMDLINE_ARGS"] = " ".join(app_new_args)

        return _parse_args()

    sys.argv = [sys.argv[0]]
    sys.argv.extend(unknown)

    for name, value in args.env:
        print("setting environment {} = {}".format(name, value))
        os.environ[name] = value

    if args.testbed_file:
        os.environ["SPYTEST_TESTBED_FILE"] = args.testbed_file
    if args.tclist_file:
        os.environ["SPYTEST_TCLIST_FILE"] = args.tclist_file
    if args.logs_path:
        os.environ["SPYTEST_LOGS_PATH"] = args.logs_path
    os.environ["SPYTEST_LOGS_LEVEL"] = args.logs_level

    prefix = "results"
    if args.results_prefix:
        file_prefix = args.results_prefix
        os.environ["SPYTEST_RESULTS_PREFIX"] = file_prefix
    else:
        file_prefix = "{0}_{1}".format(prefix, time.strftime("%Y_%m_%d_%H_%M"))
    os.environ["SPYTEST_FILE_PREFIX"] = file_prefix

    # filemode is needed in more places
    if args.file_mode:
        os.environ["SPYTEST_FILE_MODE"] = "1"
        sys.argv.append("--file-mode")

    addl_args = parse_batch_args(args.numprocesses, args.tclist_bucket)
    sys.argv.extend(addl_args)

    os.environ["SPYTEST_RAMDOM_SEED"] = str(random.randint(10000, 20000))