1#!/usr/bin/env python
2#############################################################################
3# Copyright (c) 2015-2018 Balabit
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 2 as published
7# by the Free Software Foundation, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17#
18# As an additional exemption you are allowed to compile & link against the
19# OpenSSL libraries as published by the OpenSSL project. See the file
20# COPYING for details.
21#
22#############################################################################
23import logging
24
25from src.common.file import File
26
27logger = logging.getLogger(__name__)
28
29
30class ConsoleLogReader(object):
31    def __init__(self, instance_paths):
32        self.__stderr_path = instance_paths.get_stderr_path()
33        self.__stderr_file = File(self.__stderr_path)
34
35    def wait_for_start_message(self):
36        syslog_ng_start_message = ["syslog-ng starting up;"]
37        return self.wait_for_messages_in_console_log(syslog_ng_start_message)
38
39    def wait_for_stop_message(self):
40        syslog_ng_stop_message = ["syslog-ng shutting down"]
41        return self.wait_for_messages_in_console_log(syslog_ng_stop_message)
42
43    def wait_for_reload_message(self):
44        syslog_ng_reload_messages = [
45            "New configuration initialized",
46            "Configuration reload request received, reloading configuration",
47            "Configuration reload finished",
48        ]
49        return self.wait_for_messages_in_console_log(syslog_ng_reload_messages)
50
51    def wait_for_message_in_console_log(self, expected_message):
52        return self.wait_for_messages_in_console_log(self, [expected_message])
53
54    def wait_for_messages_in_console_log(self, expected_messages):
55        if not self.__stderr_file.is_opened():
56            self.__stderr_file.wait_for_creation()
57            self.__stderr_file.open("r")
58        return self.__stderr_file.wait_for_lines(expected_messages, timeout=5)
59
60    def check_for_unexpected_messages(self, unexpected_messages=None):
61        unexpected_patterns = ["Plugin module not found", "assertion"]
62        if unexpected_messages is not None:
63            unexpected_patterns.extend(unexpected_messages)
64
65        stderr = self.__read_all_from_stderr_file()
66
67        for unexpected_pattern in unexpected_patterns:
68            for console_log_message in stderr.split("\n"):
69                if unexpected_pattern in console_log_message:
70                    logger.error("Found unexpected message in console log: {}".format(console_log_message))
71                    raise Exception("Unexpected error log in console", console_log_message)
72
73    def dump_stderr(self, last_n_lines=10):
74        stderr = self.__read_all_from_stderr_file()
75        logger.error("\n".join(stderr.split("\n")[-last_n_lines:]))
76
77    def __read_all_from_stderr_file(self):
78        stderr_file_from_the_beginning = File(self.__stderr_path)
79        stderr_file_from_the_beginning.open("r")
80        stderr = stderr_file_from_the_beginning.read()
81        stderr_file_from_the_beginning.close()
82        return stderr
83
84    @staticmethod
85    def handle_valgrind_log(valgrind_log_path):
86        with open(valgrind_log_path, "r") as valgrind_log:
87            valgrind_content = valgrind_log.read()
88            assert "Invalid read" not in valgrind_content
89            assert "Invalid write" not in valgrind_content
90            assert "blocks are definitely lost in loss record" not in valgrind_content
91            assert "Uninitialised value was created by a heap allocation" not in valgrind_content
92