# Path: pydnstest/scenario.py
# def str2bool(v):
#     def to_wire(self) -> bytes:
#     def __str__(self) -> str:
#     def __init__(self, message: dns.message.Message) -> None:
#     def to_wire(self) -> bytes:
#     def __str__(self) -> str:
#     def __init__(
#                 self,
#                 message: dns.message.Message,
#                 query: Optional[dns.message.Message] = None,
#                 copy_id: bool = False,
#                 copy_query: bool = False
#             ) -> None:
#     def adjust_reply(
#                 self,
#                 query: dns.message.Message,
#                 copy_id: bool = True,
#                 copy_query: bool = True
#             ) -> None:
#     def __init__(
#                 self,
#                 wire: bytes,
#                 query: Optional[dns.message.Message] = None,
#                 copy_id: bool = False
#             ) -> None:
#     def adjust_reply(
#                 self,
#                 query: dns.message.Message,
#                 raw_id: bool = True
#             ) -> None:
#     def to_wire(self) -> bytes:
#     def __str__(self) -> str:
#     def __init__(self, query: dns.message.Message) -> None:
#     def __init__(self, node):
#     def process_raw(self):
#     def process_match(self):
#     def process_reply_line(self):
#     def process_tsig(self):
#     def process_sections(self):
#     def __str__(self):
#     def get_flags(cls, fields):
#     def get_rcode(cls, fields):
#     def get_opcode(cls, fields):
#     def match(self, msg):
#     def cmp_raw(self, raw_value):
#     def reply(self, query) -> Optional[DNSBlob]:
#     def set_edns(self, fields):
#     def __init__(self, node):
#     def __del__(self):
#     def __str__(self):
#     def eligible(self, ident, address):
#     def reply(self, query: dns.message.Message) -> Optional[DNSBlob]:
#     def process(self, msg, kwargs):
#     def __init__(self, node):
#     def __str__(self):
#     def play(self, ctx):
#     def __check_answer(self, ctx):
#     def __query(self, ctx, tcp=False, choice=None, src_address=None):
#     def __time_passes(self):
#     def __init__(self, node, filename, deckard_address=None):
#     def __str__(self):
#     def reply(self, query: dns.message.Message, address=None) -> Optional[DNSBlob]:
#     def play(self, paddr):
# def get_next(file_in, skip_empty=True):
# def parse_config(scn_cfg, qmin, installdir):  # FIXME: pylint: disable=too-many-statements
# def parse_file(path, deckard_address=None):
# class DNSBlob(ABC):
# class DNSMessage(DNSBlob):
# class DNSReply(DNSMessage):
# class DNSReplyRaw(DNSBlob):
# class DNSReplyServfail(DNSMessage):
# class Entry:
# class Range:
# class StepLogger(logging.LoggerAdapter):  # pylint: disable=too-few-public-methods
# class Step:
# class Scenario:
# 
# Path: pydnstest/testserver.py
# class TestServer:
#     RETRIES_ON_BIND = 3
#     def __init__(self, test_scenario, addr_family,
#                  deckard_address=None, if_manager=None):
#     def __del__(self):
#     def start(self):
#     def stop(self):
#     def address(self):
#     def handle_query(self, client):
#     def query_io(self):
#     def start_srv(self, address, family, proto=socket.IPPROTO_UDP):
#     def _bind_sockets(self):
#     def play(self, subject_addr):
# def empty_test_case():
# def standalone_self_test():
#     def kill(signum, frame):  # pylint: disable=unused-argument


import errno
import logging
import logging.config
import os
import shlex
import shutil
import socket
import subprocess
import time
import jinja2
from datetime import datetime
from typing import Set  # noqa
from pydnstest import scenario, testserver
        server.stop()

        if check_for_reply_steps(case):
            logging.warning("%s has REPLY steps in it. These are known to fail randomly. "
                            "Errors might be false positives.", case.file)

        for daemon in daemons:
            daemon['proc'].terminate()
            daemon['proc'].wait()
            daemon_logger_log = logging.getLogger('deckard.daemon_log.%s' % daemon['cfg']['name'])
            with open(daemon['cfg']['log']) as logf:
                for line in logf:
                    daemon_logger_log.debug(line.strip())
            ignore_exit = daemon["cfg"].get('ignore_exit_code', False)
            if daemon['proc'].returncode != 0 and not ignore_exit:
                raise ValueError('process %s terminated with return code %s'
                                 % (daemon['cfg']['name'], daemon['proc'].returncode))

    if server.undefined_answers > 0:
        raise ValueError('the scenario does not define all necessary answers (see error log)')


def process_file(path, qmin, config):
    """Parse scenario from a file object and create workdir."""

    # Preserve original configuration
    context = config.copy()

    # Parse scenario
    case, case_config_text = scenario.parse_file(os.path.realpath(path))

# Path: pydnstest/scenario.py
# def str2bool(v):
#     def to_wire(self) -> bytes:
#     def __str__(self) -> str:
#     def __init__(self, message: dns.message.Message) -> None:
#     def to_wire(self) -> bytes:
#     def __str__(self) -> str:
#     def __init__(
#                 self,
#                 message: dns.message.Message,
#                 query: Optional[dns.message.Message] = None,
#                 copy_id: bool = False,
#                 copy_query: bool = False
#             ) -> None:
#     def adjust_reply(
#                 self,
#                 query: dns.message.Message,
#                 copy_id: bool = True,
#                 copy_query: bool = True
#             ) -> None:
#     def __init__(
#                 self,
#                 wire: bytes,
#                 query: Optional[dns.message.Message] = None,
#                 copy_id: bool = False
#             ) -> None:
#     def adjust_reply(
#                 self,
#                 query: dns.message.Message,
#                 raw_id: bool = True
#             ) -> None:
#     def to_wire(self) -> bytes:
#     def __str__(self) -> str:
#     def __init__(self, query: dns.message.Message) -> None:
#     def __init__(self, node):
#     def process_raw(self):
#     def process_match(self):
#     def process_reply_line(self):
#     def process_tsig(self):
#     def process_sections(self):
#     def __str__(self):
#     def get_flags(cls, fields):
#     def get_rcode(cls, fields):
#     def get_opcode(cls, fields):
#     def match(self, msg):
#     def cmp_raw(self, raw_value):
#     def reply(self, query) -> Optional[DNSBlob]:
#     def set_edns(self, fields):
#     def __init__(self, node):
#     def __del__(self):
#     def __str__(self):
#     def eligible(self, ident, address):
#     def reply(self, query: dns.message.Message) -> Optional[DNSBlob]:
#     def process(self, msg, kwargs):
#     def __init__(self, node):
#     def __str__(self):
#     def play(self, ctx):
#     def __check_answer(self, ctx):
#     def __query(self, ctx, tcp=False, choice=None, src_address=None):
#     def __time_passes(self):
#     def __init__(self, node, filename, deckard_address=None):
#     def __str__(self):
#     def reply(self, query: dns.message.Message, address=None) -> Optional[DNSBlob]:
#     def play(self, paddr):
# def get_next(file_in, skip_empty=True):
# def parse_config(scn_cfg, qmin, installdir):  # FIXME: pylint: disable=too-many-statements
# def parse_file(path, deckard_address=None):
# class DNSBlob(ABC):
# class DNSMessage(DNSBlob):
# class DNSReply(DNSMessage):
# class DNSReplyRaw(DNSBlob):
# class DNSReplyServfail(DNSMessage):
# class Entry:
# class Range:
# class StepLogger(logging.LoggerAdapter):  # pylint: disable=too-few-public-methods
# class Step:
# class Scenario:
# 
# Path: pydnstest/testserver.py
# class TestServer:
#     RETRIES_ON_BIND = 3
#     def __init__(self, test_scenario, addr_family,
#                  deckard_address=None, if_manager=None):
#     def __del__(self):
#     def start(self):
#     def stop(self):
#     def address(self):
#     def handle_query(self, client):
#     def query_io(self):
#     def start_srv(self, address, family, proto=socket.IPPROTO_UDP):
#     def _bind_sockets(self):
#     def play(self, subject_addr):
# def empty_test_case():
# def standalone_self_test():
#     def kill(signum, frame):  # pylint: disable=unused-argument


# Path: deckard.py
import errno
import logging
import logging.config
import os
import shlex
import shutil
import socket
import subprocess
import time
import jinja2
from datetime import datetime
from typing import Set  # noqa
from pydnstest import scenario, testserver

        server.stop()

        if check_for_reply_steps(case):
            logging.warning("%s has REPLY steps in it. These are known to fail randomly. "
                            "Errors might be false positives.", case.file)

        for daemon in daemons:
            daemon['proc'].terminate()
            daemon['proc'].wait()
            daemon_logger_log = logging.getLogger('deckard.daemon_log.%s' % daemon['cfg']['name'])
            with open(daemon['cfg']['log']) as logf:
                for line in logf:
                    daemon_logger_log.debug(line.strip())
            ignore_exit = daemon["cfg"].get('ignore_exit_code', False)
            if daemon['proc'].returncode != 0 and not ignore_exit:
                raise ValueError('process %s terminated with return code %s'
                                 % (daemon['cfg']['name'], daemon['proc'].returncode))

    if server.undefined_answers > 0:
        raise ValueError('the scenario does not define all necessary answers (see error log)')


def process_file(path, qmin, config):
    """Parse scenario from a file object and create workdir."""

    # Preserve original configuration
    context = config.copy()

    # Parse scenario
    case, case_config_text = scenario.parse_file(os.path.realpath(path))

    case_config = scenario.parse_config(case_config_text, qmin, INSTALLDIR)