Пример #1
0
class NodeTargetLibFactory(TestCase):
    def setUp(self):
        self.known_hosts = {
            "host{}".format(i):
            PcsKnownHost("host{}".format(i), "token{}".format(i), [
                Destination("addr{}{}".format(i, j), "port{}{}".format(i, j))
                for j in range(2)
            ])
            for i in range(2)
        }
        self.report_processor = MockLibraryReportProcessor()
        self.factory = lib.NodeTargetLibFactory(self.known_hosts,
                                                self.report_processor)

    def assert_equal_known_host_target(self, known_host, target):
        self.assertEqual(known_host.name, target.label)
        self.assertEqual(known_host.token, target.token)
        self.assertEqual(known_host.dest_list, target.dest_list)

    def test_one_host(self):
        host = "host0"
        self.assert_equal_known_host_target(
            self.known_hosts[host],
            self.factory.get_target_list([host])[0])
        self.report_processor.assert_reports([])

    def test_multiple_hosts(self):
        host_list = ["host0", "host1"]
        target_list = self.factory.get_target_list(host_list)
        for i, host in enumerate(host_list):
            self.assert_equal_known_host_target(self.known_hosts[host],
                                                target_list[i])
        self.report_processor.assert_reports([])

    def test_multiple_not_found(self):
        host = "host0"
        unknown_hosts = ["node0", "node1"]
        report = fixture.error(report_codes.HOST_NOT_FOUND,
                               force_code=report_codes.SKIP_OFFLINE_NODES,
                               host_list=unknown_hosts)
        assert_raise_library_error(
            lambda: self.factory.get_target_list([host] + unknown_hosts),
            report)
        self.report_processor.assert_reports([report])

    def test_multiple_skip_not_allowed(self):
        host = "host0"
        unknown_hosts = ["node0", "node1"]
        report = fixture.error(report_codes.HOST_NOT_FOUND,
                               host_list=unknown_hosts)
        assert_raise_library_error(
            lambda: self.factory.get_target_list(
                [host] + unknown_hosts,
                allow_skip=False,
            ), report)
        self.report_processor.assert_reports([report])

    def test_multiple_not_found_skip_offline(self):
        host = "host0"
        unknown_hosts = ["node0", "node1"]
        target_list = self.factory.get_target_list([host] + unknown_hosts,
                                                   skip_non_existing=True)
        self.assert_equal_known_host_target(self.known_hosts[host],
                                            target_list[0])
        self.report_processor.assert_reports([
            fixture.warn(report_codes.HOST_NOT_FOUND, host_list=unknown_hosts)
        ])

    def test_no_host_found(self):
        unknown_hosts = ["node0", "node1"]
        report_list = [
            fixture.error(report_codes.HOST_NOT_FOUND,
                          force_code=report_codes.SKIP_OFFLINE_NODES,
                          host_list=unknown_hosts),
            fixture.error(report_codes.NONE_HOST_FOUND)
        ]
        assert_raise_library_error(
            lambda: self.factory.get_target_list(unknown_hosts), *report_list)
        self.report_processor.assert_reports(report_list)

    def test_no_host_found_skip_offline(self):
        unknown_hosts = ["node0", "node1"]
        report_list = [
            fixture.warn(report_codes.HOST_NOT_FOUND, host_list=unknown_hosts),
            fixture.error(report_codes.NONE_HOST_FOUND)
        ]
        assert_raise_library_error(
            lambda: self.factory.get_target_list(unknown_hosts,
                                                 skip_non_existing=True),
            report_list[1])
        self.report_processor.assert_reports(report_list)

    def test_empty_host_list(self):
        self.assertEqual([], self.factory.get_target_list([]))
        self.report_processor.assert_reports([])
Пример #2
0
class CommunicatorLoggerTest(TestCase):
    def setUp(self):
        self.logger = mock.MagicMock(spec_set=logging.Logger)
        self.reporter = MockLibraryReportProcessor()
        self.com_logger = lib.LibCommunicatorLogger(self.logger, self.reporter)

    def test_log_request_start(self):
        request = fixture_request()
        self.com_logger.log_request_start(request)
        self.reporter.assert_reports(
            fixture_report_item_list_send(request.url, request.data))
        self.assertEqual([fixture_logger_call_send(request.url, request.data)],
                         self.logger.mock_calls)

    def test_log_response_connected(self):
        expected_code = 200
        expected_data = "data"
        expected_debug_data = "* text\n>> data out\n"
        response = Response.connection_successful(
            MockCurlSimple(
                info={pycurl.RESPONSE_CODE: expected_code},
                output=expected_data.encode("utf-8"),
                debug_output=expected_debug_data.encode("utf-8"),
                request=fixture_request(),
            ))
        self.com_logger.log_response(response)
        self.reporter.assert_reports(
            fixture_report_item_list_on_success(response.request.url,
                                                expected_code, expected_data,
                                                expected_debug_data))
        logger_calls = fixture_logger_calls_on_success(response.request.url,
                                                       expected_code,
                                                       expected_data,
                                                       expected_debug_data)
        self.assertEqual(logger_calls, self.logger.mock_calls)

    @mock.patch("pcs.lib.node_communication.is_proxy_set")
    def test_log_response_not_connected(self, mock_proxy):
        mock_proxy.return_value = False
        expected_debug_data = "* text\n>> data out\n"
        error_msg = "error"
        response = Response.connection_failure(
            MockCurlSimple(
                debug_output=expected_debug_data.encode("utf-8"),
                request=fixture_request(),
            ),
            pycurl.E_HTTP_POST_ERROR,
            error_msg,
        )
        self.com_logger.log_response(response)
        self.reporter.assert_reports(
            fixture_report_item_list_not_connected(response.request.host_label,
                                                   error_msg) +
            fixture_report_item_list_debug(response.request.url,
                                           expected_debug_data))
        logger_calls = [
            fixture_logger_call_not_connected(response.request.host_label,
                                              error_msg),
            fixture_logger_call_debug_data(response.request.url,
                                           expected_debug_data)
        ]
        self.assertEqual(logger_calls, self.logger.mock_calls)

    @mock.patch("pcs.lib.node_communication.is_proxy_set")
    def test_log_response_not_connected_with_proxy(self, mock_proxy):
        mock_proxy.return_value = True
        expected_debug_data = "* text\n>> data out\n"
        error_msg = "error"
        response = Response.connection_failure(
            MockCurlSimple(
                debug_output=expected_debug_data.encode("utf-8"),
                request=fixture_request(),
            ),
            pycurl.E_HTTP_POST_ERROR,
            error_msg,
        )
        self.com_logger.log_response(response)
        self.reporter.assert_reports(
            fixture_report_item_list_not_connected(response.request.host_label,
                                                   error_msg) +
            fixture_report_item_list_proxy_set(response.request.host_label,
                                               response.request.host_label) +
            fixture_report_item_list_debug(response.request.url,
                                           expected_debug_data))
        logger_calls = [
            fixture_logger_call_not_connected(response.request.host_label,
                                              error_msg),
            fixture_logger_call_proxy_set(),
            fixture_logger_call_debug_data(response.request.url,
                                           expected_debug_data)
        ]
        self.assertEqual(logger_calls, self.logger.mock_calls)

    def test_log_retry(self):
        prev_addr = "addr"
        prev_port = 2225
        prev_host = Destination(prev_addr, prev_port)
        response = Response.connection_failure(
            MockCurlSimple(request=fixture_request()),
            pycurl.E_HTTP_POST_ERROR,
            "e",
        )
        self.com_logger.log_retry(response, prev_host)
        self.reporter.assert_reports([
            (severity.WARNING, report_codes.NODE_COMMUNICATION_RETRYING, {
                "node": response.request.host_label,
                "failed_address": prev_addr,
                "failed_port": prev_port,
                "next_address": response.request.dest.addr,
                "next_port": settings.pcsd_default_port,
                "request": response.request.url,
            }, None)
        ])
        logger_call = mock.call.warning(
            ("Unable to connect to '{label}' via address '{old_addr}' and "
             "port '{old_port}'. Retrying request '{req}' via address "
             "'{new_addr}' and port '{new_port}'").format(
                 label=response.request.host_label,
                 old_addr=prev_addr,
                 old_port=prev_port,
                 new_addr=response.request.dest.addr,
                 new_port=settings.pcsd_default_port,
                 req=response.request.url,
             ))
        self.assertEqual([logger_call], self.logger.mock_calls)

    def test_log_no_more_addresses(self):
        response = Response.connection_failure(
            MockCurlSimple(request=fixture_request()),
            pycurl.E_HTTP_POST_ERROR, "e")
        self.com_logger.log_no_more_addresses(response)
        self.reporter.assert_reports([
            (severity.WARNING,
             report_codes.NODE_COMMUNICATION_NO_MORE_ADDRESSES, {
                 "node": response.request.host_label,
                 "request": response.request.url,
             }, None)
        ])
        logger_call = mock.call.warning(
            "No more addresses for node {label} to run '{req}'".format(
                label=response.request.host_label,
                req=response.request.url,
            ))
        self.assertEqual([logger_call], self.logger.mock_calls)
Пример #3
0
class EnsureResourceState(TestCase):
    resource_id = "R"
    def setUp(self):
        self.report_processor = MockLibraryReportProcessor(
            raise_on_errors=False
        )
        self.cluster_state = "state"

        patcher = mock.patch(
            "pcs.lib.pacemaker.state.get_resource_roles_with_nodes"
        )
        self.addCleanup(patcher.stop)
        self.get_resource_roles_with_nodes = patcher.start()

    def fixture_running_state_info(self):
        return {
            "Started": ["node1"],
            "Master": ["node2"],
            "Slave": ["node3", "node4"],
        }

    def fixture_running_report(self, severity):
        return (severity, report_codes.RESOURCE_RUNNING_ON_NODES, {
            "resource_id": self.resource_id,
            "roles_with_nodes": self.fixture_running_state_info(),
        })

    def fixture_not_running_report(self, severity):
        return (severity, report_codes.RESOURCE_DOES_NOT_RUN, {
            "resource_id": self.resource_id
        })

    def assert_running_info_transform(self, run_info, report, expected_running):
        self.get_resource_roles_with_nodes.return_value = run_info
        state.ensure_resource_state(
            expected_running,
            self.report_processor,
            self.cluster_state,
            self.resource_id
        )
        self.report_processor.assert_reports([report])
        self.get_resource_roles_with_nodes.assert_called_once_with(
            self.cluster_state,
            self.resource_id
        )

    def test_report_info_running(self):
        self.assert_running_info_transform(
            self.fixture_running_state_info(),
            self.fixture_running_report(severities.INFO),
            expected_running=True,
        )

    def test_report_error_running(self):
        self.assert_running_info_transform(
            self.fixture_running_state_info(),
            self.fixture_running_report(severities.ERROR),
            expected_running=False,
        )

    def test_report_error_not_running(self):
        self.assert_running_info_transform(
            [],
            self.fixture_not_running_report(severities.ERROR),
            expected_running=True,
        )

    def test_report_info_not_running(self):
        self.assert_running_info_transform(
            [],
            self.fixture_not_running_report(severities.INFO),
            expected_running=False,
        )