예제 #1
0
def process_file(path, qmin, prog_cfgs):
    """Parse scenario from a file object and create workdir."""
    # Parse scenario
    case, cfg_text = scenario.parse_file(os.path.realpath(path))
    cfg_ctx, ta_files = scenario.parse_config(cfg_text, qmin, INSTALLDIR)
    template_ctx = setup_network(cfg_ctx['_SOCKET_FAMILY'], prog_cfgs)
    # merge variables from scenario with generated network variables (scenario has priority)
    template_ctx.update(cfg_ctx)
    # Deckard will communicate with first program
    prog_under_test = prog_cfgs['programs'][0]['name']
    prog_under_test_ip = template_ctx['IPADDRS'][prog_under_test]

    # get working directory and environment variables
    tmpdir = setup_common_env(cfg_ctx)
    shutil.copy2(path, os.path.join(tmpdir))
    try:
        daemons = setup_daemons(tmpdir, prog_cfgs, template_ctx, ta_files)
        run_testcase(daemons,
                     case,
                     template_ctx['ROOT_ADDR'],
                     template_ctx['_SOCKET_FAMILY'],
                     prog_under_test_ip)
        if prog_cfgs.get('noclean'):
            logging.getLogger('deckard.hint').info(
                'test working directory %s', tmpdir)
        else:
            shutil.rmtree(tmpdir)
    except:
        logging.getLogger('deckard.hint').info(
            'test failed, inspect working directory %s', tmpdir)
        raise
예제 #2
0
def play_object(path, binary_name, config_name, j2template,
                binary_additional_pars):
    """ Play scenario from a file object. """

    # Parse scenario
    case, config = scenario.parse_file(fileinput.input(path))

    # Setup daemon environment
    daemon_env = os.environ.copy()
    setup_env(case, daemon_env, config, config_name, j2template)

    server = testserver.TestServer(case, config, DEFAULT_IFACE)
    server.start()

    # Start binary
    daemon_proc = None
    daemon_log = open('%s/server.log' % TMPDIR, 'w')
    daemon_args = [binary_name] + binary_additional_pars
    try:
        daemon_proc = subprocess.Popen(daemon_args,
                                       stdout=daemon_log,
                                       stderr=daemon_log,
                                       cwd=TMPDIR,
                                       preexec_fn=os.setsid,
                                       env=daemon_env)
    except Exception as e:
        server.stop()
        raise Exception("Can't start '%s': %s" % (daemon_args, str(e)))

    # Wait until the server accepts TCP clients
    sockfamily = socket.AF_INET
    if case.force_ipv6 == True:
        sockfamily = socket.AF_INET6
예제 #3
0
def empty_test_case():
    """
    Return (scenario, config) pair which answers to any query on 127.0.0.10.
    """
    # Mirror server
    empty_test_path = os.path.dirname(os.path.realpath(__file__)) + "/empty.rpl"
    test_config = {'ROOT_ADDR': '127.0.0.10',
                   '_SOCKET_FAMILY': socket.AF_INET}
    return scenario.parse_file(empty_test_path)[0], test_config
예제 #4
0
def standalone_self_test():
    """
    Self-test code

    Usage:
    unshare -rn $PYTHON -m pydnstest.testserver --help
    """
    logging.basicConfig(level=logging.DEBUG)
    argparser = argparse.ArgumentParser()
    argparser.add_argument('--scenario', help='absolute path to test scenario',
                           required=False)
    argparser.add_argument('--step', help='step # in the scenario (default: first)',
                           required=False, type=int)
    args = argparser.parse_args()
    if args.scenario:
        test_scenario, test_config_text = scenario.parse_file(args.scenario)
        test_config = scenario.parse_config(test_config_text, True, os.getcwd())
    else:
        test_scenario, test_config = empty_test_case()

    if args.step:
        for step in test_scenario.steps:
            if step.id == args.step:
                test_scenario.current_step = step
        if not test_scenario.current_step:
            raise ValueError('step ID %s not found in scenario' % args.step)
    else:
        test_scenario.current_step = test_scenario.steps[0]

    if_manager = InterfaceManager(interface="testserver")
    server = TestServer(test_scenario, test_config['_SOCKET_FAMILY'], if_manager=if_manager)
    server.start()

    logging.info("[==========] Mirror server running at %s", server.address())

    def kill(signum, frame):  # pylint: disable=unused-argument
        logging.info("[==========] Shutdown.")
        server.stop()
        sys.exit(128 + signum)

    signal.signal(signal.SIGINT, kill)
    signal.signal(signal.SIGTERM, kill)

    while True:
        time.sleep(0.5)
예제 #5
0
def standalone_self_test():
    """
    Self-test code

    Usage:
    LD_PRELOAD=libsocket_wrapper.so SOCKET_WRAPPER_DIR=/tmp $PYTHON -m pydnstest.testserver --help
    """
    logging.basicConfig(level=logging.DEBUG)
    argparser = argparse.ArgumentParser()
    argparser.add_argument('--scenario', help='absolute path to test scenario',
                           required=False)
    argparser.add_argument('--step', help='step # in the scenario (default: first)',
                           required=False, type=int)
    args = argparser.parse_args()
    if args.scenario:
        test_scenario, test_config_text = scenario.parse_file(args.scenario)
        test_config, _ = scenario.parse_config(test_config_text, True, os.getcwd())
    else:
        test_scenario, test_config = empty_test_case()

    if args.step:
        for step in test_scenario.steps:
            if step.id == args.step:
                test_scenario.current_step = step
        if not test_scenario.current_step:
            raise ValueError('step ID %s not found in scenario' % args.step)
    else:
        test_scenario.current_step = test_scenario.steps[0]

    server = TestServer(test_scenario, test_config['ROOT_ADDR'], test_config['_SOCKET_FAMILY'])
    server.start()

    logging.info("[==========] Mirror server running at %s", server.address())

    def exit(signum, frame):
        logging.info("[==========] Shutdown.")
        server.stop()
        sys.exit(128 + signum)

    signal.signal(signal.SIGINT, exit)
    signal.signal(signal.SIGTERM, exit)

    while True:
        time.sleep(0.5)
예제 #6
0
파일: deckard.py 프로젝트: CZ-NIC/deckard
def play_object(path, binary_name, config_name, j2template, binary_additional_pars):
    """ Play scenario from a file object. """

    # Parse scenario
    case, config = scenario.parse_file(fileinput.input(path))

    # Setup daemon environment
    daemon_env = os.environ.copy()
    setup_env(case, daemon_env, config, config_name, j2template)

    server = testserver.TestServer(case, config, DEFAULT_IFACE)
    server.start()

    # Start binary
    daemon_proc = None
    daemon_log = open('%s/server.log' % TMPDIR, 'w')
    daemon_args = [binary_name] + binary_additional_pars
    try :
      daemon_proc = subprocess.Popen(daemon_args, stdout=daemon_log, stderr=daemon_log,
                                     cwd=TMPDIR, preexec_fn=os.setsid, env=daemon_env)
    except Exception as e:
        server.stop()
        raise Exception("Can't start '%s': %s" % (daemon_args, str(e)))

    # Wait until the server accepts TCP clients
    sockfamily = socket.AF_INET
    if case.force_ipv6 == True:
        sockfamily = socket.AF_INET6
    sock = socket.socket(sockfamily, socket.SOCK_STREAM)
    while True:
        time.sleep(0.1)
        if daemon_proc.poll() != None:
            server.stop()
            print(open('%s/server.log' % TMPDIR).read())
            raise Exception('process died "%s", logs in "%s"' % (os.path.basename(binary_name), TMPDIR))
        try:
            sock.connect((testserver.get_local_addr_str(sockfamily, CHILD_IFACE), 53))
        except: continue
        break
    sock.close()

    # Bind to test servers
    for r in case.ranges:
        family = socket.AF_INET6 if ':' in r.address else socket.AF_INET
        server.start_srv((r.address, 53), family)
    # Bind addresses in ad-hoc REPLYs
    for s in case.steps:
        if s.type == 'REPLY':
            reply = s.data[0].message
            for rr in itertools.chain(reply.answer,reply.additional,reply.question,reply.authority):
                for rd in rr:
                    if rd.rdtype == dns.rdatatype.A:
                        server.start_srv((rd.address, 53), socket.AF_INET)
                    elif rd.rdtype == dns.rdatatype.AAAA:
                        server.start_srv((rd.address, 53), socket.AF_INET6)

    # Play test scenario
    try:
        server.play(CHILD_IFACE)
        if VERBOSE:
            print(open('%s/server.log' % TMPDIR).read())
    except:
        print(open('%s/server.log' % TMPDIR).read())
        raise
    finally:
        server.stop()
        daemon_proc.terminate()
        daemon_proc.wait()
    # Do not clear files if the server crashed (for analysis)
    del_files(TMPDIR, OWN_TMPDIR)
예제 #7
0
def play_object(path, binary_name, config_name, j2template,
                binary_additional_pars):
    """ Play scenario from a file object. """

    # Parse scenario
    case, config = scenario.parse_file(fileinput.input(path))

    # Setup daemon environment
    daemon_env = os.environ.copy()
    setup_env(case, daemon_env, config, config_name, j2template)

    server = testserver.TestServer(case, config, DEFAULT_IFACE)
    server.start()

    ignore_exit = bool(os.environ.get('IGNORE_EXIT_CODE', 0))
    # Start binary
    daemon_proc = None
    daemon_log = open('%s/server.log' % TMPDIR, 'w')
    daemon_args = [binary_name] + binary_additional_pars
    try:
        daemon_proc = subprocess.Popen(daemon_args,
                                       stdout=daemon_log,
                                       stderr=daemon_log,
                                       cwd=TMPDIR,
                                       preexec_fn=os.setsid,
                                       env=daemon_env)
    except Exception as e:
        server.stop()
        raise Exception("Can't start '%s': %s" % (daemon_args, str(e)))

    # Wait until the server accepts TCP clients
    sock = socket.socket(case.sockfamily, socket.SOCK_STREAM)
    while True:
        time.sleep(0.1)
        if daemon_proc.poll():
            server.stop()
            print(open('%s/server.log' % TMPDIR).read())
            raise Exception('process died "%s", logs in "%s"' %
                            (os.path.basename(binary_name), TMPDIR))
        try:
            sock.connect(
                (testserver.get_local_addr_str(case.sockfamily,
                                               CHILD_IFACE), 53))
        except:
            continue
        break
    sock.close()

    # Bind to test servers
    for r in case.ranges:
        for addr in r.addresses:
            family = socket.AF_INET6 if ':' in addr else socket.AF_INET
            server.start_srv((addr, 53), family)
    # Bind addresses in ad-hoc REPLYs
    for s in case.steps:
        if s.type == 'REPLY':
            reply = s.data[0].message
            for rr in itertools.chain(reply.answer, reply.additional,
                                      reply.question, reply.authority):
                for rd in rr:
                    if rd.rdtype == dns.rdatatype.A:
                        server.start_srv((rd.address, 53), socket.AF_INET)
                    elif rd.rdtype == dns.rdatatype.AAAA:
                        server.start_srv((rd.address, 53), socket.AF_INET6)

    # Play test scenario
    try:
        server.play(CHILD_IFACE)
    except Exception as exc:
        ex = exc
        raise
    else:
        ex = None
    finally:
        server.stop()
        daemon_proc.terminate()
        daemon_proc.wait()
        if VERBOSE or ex or (daemon_proc.returncode and not ignore_exit):
            print(open('%s/server.log' % TMPDIR).read())
        if daemon_proc.returncode != 0 and not ignore_exit:
            raise ValueError('process terminated with return code %s' %
                             daemon_proc.returncode)
    # Do not clear files if the server crashed (for analysis)
    del_files(TMPDIR, OWN_TMPDIR)