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 argparse
24import logging
25import subprocess
26from datetime import datetime
27
28import pytest
29from pathlib2 import Path
30
31import src.testcase_parameters.testcase_parameters as tc_parameters
32from src.helpers.loggen.loggen import Loggen
33from src.message_builder.bsd_format import BSDFormat
34from src.message_builder.log_message import LogMessage
35from src.syslog_ng.syslog_ng import SyslogNg
36from src.syslog_ng.syslog_ng_paths import SyslogNgPaths
37from src.syslog_ng_config.syslog_ng_config import SyslogNgConfig
38from src.syslog_ng_ctl.syslog_ng_ctl import SyslogNgCtl
39from src.testcase_parameters.testcase_parameters import TestcaseParameters
40
41logger = logging.getLogger(__name__)
42
43
44class InstallDirAction(argparse.Action):
45    def __call__(self, parser, namespace, path, option_string=None):
46        install_dir = Path(path)
47
48        if not install_dir.is_dir():
49            raise argparse.ArgumentTypeError("{0} is not a valid directory".format(path))
50
51        binary = Path(install_dir, "sbin/syslog-ng")
52        if not binary.exists():
53            raise argparse.ArgumentTypeError("{0} not exist".format(binary))
54
55        setattr(namespace, self.dest, path)
56
57
58# Command line options
59def pytest_addoption(parser):
60    parser.addoption("--runslow", action="store_true", default=False, help="run slow tests")
61    parser.addoption("--run-under", help="Run syslog-ng under selected tool, example tools: [valgrind, strace]")
62    parser.addoption(
63        "--installdir",
64        action=InstallDirAction,
65        help="Set installdir for installed syslog-ng. Used when installmode is: custom. Example path: '/home/user/syslog-ng/installdir/'",
66    )
67    parser.addoption(
68        "--reports",
69        action="store",
70        default=get_relative_report_dir(),
71        help="Path for report files folder. Default form: 'reports/<current_date>'",
72    )
73
74
75def get_relative_report_dir():
76    return str(Path("reports/", get_current_date()))
77
78
79def get_current_date():
80    return datetime.now().strftime("%Y-%m-%d-%H-%M-%S-%f")
81
82
83# Pytest Hooks
84def pytest_collection_modifyitems(config, items):
85    if config.getoption("--runslow"):
86        return
87    skip_slow = pytest.mark.skip(reason="need --runslow option to run")
88    for item in items:
89        if "slow" in item.keywords:
90            item.add_marker(skip_slow)
91
92
93def pytest_runtest_logreport(report):
94    if report.outcome == "failed":
95        logger.error("\n{}".format(report.longrepr))
96
97
98# Pytest Fixtures
99@pytest.fixture
100def testcase_parameters(request):
101    return TestcaseParameters(request)
102
103
104@pytest.fixture
105def config(request):
106    return SyslogNgConfig(request.getfixturevalue("version"))
107
108
109@pytest.fixture
110def syslog_ng(request, testcase_parameters):
111    tc_parameters.INSTANCE_PATH = SyslogNgPaths(testcase_parameters).set_syslog_ng_paths("server")
112    syslog_ng = SyslogNg(tc_parameters.INSTANCE_PATH, testcase_parameters)
113    request.addfinalizer(lambda: syslog_ng.stop())
114    return syslog_ng
115
116
117@pytest.fixture
118def syslog_ng_ctl(syslog_ng):
119    return SyslogNgCtl(syslog_ng.instance_paths)
120
121
122@pytest.fixture
123def bsd_formatter():
124    return BSDFormat()
125
126
127@pytest.fixture
128def log_message():
129    return LogMessage()
130
131
132@pytest.fixture(scope="session")
133def version(request):
134    installdir = request.config.getoption("--installdir")
135    binary_path = str(Path(installdir, "sbin", "syslog-ng"))
136    version_output = subprocess.check_output([binary_path, "--version"]).decode()
137    return version_output.splitlines()[1].split()[2]
138
139
140@pytest.fixture
141def loggen(testcase_parameters):
142    server = Loggen()
143    yield server
144    server.stop()
145