Beispiel #1
0
    def test_open_missing_file(self, tail_engine):
        lines = []

        listener = FileListener("/tmp/does/not/exist", lines.append)
        listener.use_tail_command = tail_engine != "tailer"

        with pytest.raises(FileNotFoundError):
            listener.start()
Beispiel #2
0
def cmd_logs(follow: bool):
    from localstack import config
    from localstack.utils.bootstrap import LocalstackContainer
    from localstack.utils.common import FileListener
    from localstack.utils.docker_utils import DOCKER_CLIENT

    container_name = config.MAIN_CONTAINER_NAME
    logfile = LocalstackContainer(container_name).logfile

    if not DOCKER_CLIENT.is_container_running(container_name):
        console.print("localstack container not running")
        sys.exit(1)

    if not os.path.exists(logfile):
        console.print("localstack container logfile not found at %s" % logfile)
        sys.exit(1)

    if follow:
        listener = FileListener(logfile, print)
        listener.start()
        try:
            listener.join()
        except KeyboardInterrupt:
            pass
        finally:
            listener.close()
    else:
        with open(logfile) as fd:
            for line in fd:
                print(line.rstrip("\n\r"))
Beispiel #3
0
    def test_basic_usage(self, tail_engine, tmp_path):
        lines = []

        file = tmp_path / "log.txt"
        file.touch()
        fd = open(file, "a")
        listener = FileListener(str(file), lines.append)
        listener.use_tail_command = tail_engine != "tailer"

        try:
            listener.start()
            assert listener.started.is_set()
            fd.write("hello" + os.linesep)
            fd.write("pytest" + os.linesep)
            fd.flush()

            assert poll_condition(
                lambda: len(lines) == 2,
                timeout=3), ("expected two lines to appear. %s" % lines)

            assert lines[0] == "hello"
            assert lines[1] == "pytest"
        finally:
            listener.close()

        try:
            fd.write("foobar" + os.linesep)
            time.sleep(0.5)
            assert len(
                lines
            ) == 2, "expected listener.stop() to stop listening on new "
        finally:
            fd.close()
Beispiel #4
0
    def test_callback_exception_ignored(self, tail_engine, tmp_path):
        lines = []

        def callback(line):
            if "throw" in line:
                raise ValueError("oh noes")

            lines.append(line)

        file = tmp_path / "log.txt"
        file.touch()
        fd = open(file, "a")
        listener = FileListener(str(file), callback)
        listener.use_tail_command = tail_engine != "tailer"

        try:
            listener.start()
            assert listener.started.is_set()
            fd.write("hello" + os.linesep)
            fd.flush()
            fd.write("throw" + os.linesep)
            fd.write("pytest" + os.linesep)
            fd.flush()

            assert poll_condition(
                lambda: len(lines) == 2,
                timeout=3), ("expected two lines to appear. %s" % lines)

            assert lines[0] == "hello"
            assert lines[1] == "pytest"
        finally:
            fd.close()
            listener.close()
Beispiel #5
0
def start_infra_in_docker():
    prepare_docker_start()

    container = LocalstackContainer()

    # create and prepare container
    configure_container(container)

    container.truncate_log()

    # printing the container log is the current way we're occupying the terminal
    log_printer = FileListener(container.logfile, print)
    log_printer.start()

    # Set up signal handler, to enable clean shutdown across different operating systems.
    #  There are subtle differences across operating systems and terminal emulators when it
    #  comes to handling of CTRL-C - in particular, Linux sends SIGINT to the parent process,
    #  whereas MacOS sends SIGINT to the process group, which can result in multiple SIGINT signals
    #  being received (e.g., when running the localstack CLI as part of an "npm run .." script).
    #  Hence, using a shutdown handler and synchronization event here, to avoid inconsistencies.
    def shutdown_handler(*args):
        with shutdown_event_lock:
            if shutdown_event.is_set():
                return
            shutdown_event.set()
        print("Shutting down...")
        server.shutdown()
        log_printer.close()

    shutdown_event = threading.Event()
    shutdown_event_lock = threading.RLock()
    signal.signal(signal.SIGINT, shutdown_handler)

    # start the Localstack container as a Server
    server = LocalstackContainerServer(container)
    try:
        server.start()
        server.join()
    except KeyboardInterrupt:
        print("ok, bye!")
        shutdown_handler()
Beispiel #6
0
def wait_container_is_ready(timeout: Optional[float] = None):
    """Blocks until the localstack main container is running and the ready marker has been printed."""
    container_name = config.MAIN_CONTAINER_NAME

    def is_container_running():
        return DOCKER_CLIENT.is_container_running(container_name)

    if not poll_condition(is_container_running, timeout=timeout):
        return False

    logfile = LocalstackContainer(container_name).logfile

    ready = threading.Event()

    def set_ready_if_marker_found(_line: str):
        if _line == constants.READY_MARKER_OUTPUT:
            ready.set()

    # start a tail on the logfile
    listener = FileListener(logfile, set_ready_if_marker_found)
    listener.start()

    try:
        # but also check the existing log in case the container has been running longer
        with open(logfile, "r") as fd:
            for line in fd:
                if constants.READY_MARKER_OUTPUT == line.strip():
                    return True

        # TODO: calculate remaining timeout
        return ready.wait(timeout)
    finally:
        listener.close()
Beispiel #7
0
def start_infra_in_docker():
    prepare_docker_start()

    container = LocalstackContainer()

    # create and prepare container
    configure_container(container)

    container.truncate_log()

    # printing the container log is the current way we're occupying the terminal
    log_printer = FileListener(container.logfile, print)
    log_printer.start()

    # start the Localstack container as a Server
    server = LocalstackContainerServer(container)
    try:
        server.start()
        server.join()
    except KeyboardInterrupt:
        print("ok, bye!")
    finally:
        server.shutdown()
        log_printer.close()