def test_success(self, mock_create_handle, _, mock_con_successful, mock_con_failure): com = self.get_multiaddress_communicator() counter = {"counter": 0} expected_response_list = [] def _con_successful(handle): response = lib.Response(handle, True) expected_response_list.append(response) return response def _con_failure(handle, errno, err_msg): response = lib.Response(handle, False, errno, err_msg) expected_response_list.append(response) return response def _mock_create_request_handle(request, _, __): counter["counter"] += 1 return (MockCurl( request=request) if counter["counter"] > 2 else MockCurl( error=(pycurl.E_SEND_ERROR, "reason"), request=request, )) mock_con_successful.side_effect = _con_successful mock_con_failure.side_effect = _con_failure mock_create_handle.side_effect = _mock_create_request_handle request = lib.Request( lib.RequestTarget( "label", dest_list=_addr_list_to_dest( ["host{0}".format(i) for i in range(4)]), ), lib.RequestData("action"), ) com.add_requests([request]) response_list = list(com.start_loop()) self.assertEqual(1, len(response_list)) response = response_list[0] self.assertIs(response, expected_response_list[-1]) self.assertTrue(response.was_connected) self.assertIs(request, response.request) self.assertEqual(Destination("host2", None), request.dest) self.assertEqual(3, mock_create_handle.call_count) self.assertEqual(3, len(expected_response_list)) mock_create_handle.assert_has_calls([ mock.call(request, {}, settings.default_request_timeout) for _ in range(3) ]) logger_calls = ( fixture_logger_request_retry_calls(expected_response_list[0], Destination("host0", None)) + fixture_logger_request_retry_calls( expected_response_list[1], Destination("host1", None)) + [ mock.call.log_request_start(request), mock.call.log_response(response), ]) self.assertEqual(logger_calls, self.mock_com_log.mock_calls) # pylint: disable=no-member, protected-access com._multi_handle.assert_no_handle_left()
def test_some_node_names_missing(self): self._config_success_base() (self.config.env.set_known_hosts_dests({ "rh7-1": [Destination("rh7-1", 2224)], "rh7-2": [Destination("rh7-2", 2224)], NODE_NAME: NODE_DEST_LIST, }).corosync_conf.load(filename="corosync-some-node-names.conf", instead="corosync_conf.load")) node_add_remote(self.env_assist.get_env()) self.env_assist.assert_reports( REPORTS.warn("missing_node_names_in_corosync", report_codes.COROSYNC_CONFIG_MISSING_NAMES_OF_NODES, fatal=False))
def test_failure(self, mock_create_handle, _, mock_con_successful, mock_con_failure): expected_response_list = [] def _con_failure(handle, errno, err_msg): response = lib.Response(handle, False, errno, err_msg) expected_response_list.append(response) return response mock_con_failure.side_effect = _con_failure com = self.get_multiaddress_communicator() mock_create_handle.side_effect = lambda request, _, __: MockCurl( error=(pycurl.E_SEND_ERROR, "reason"), request=request, ) request = lib.Request( lib.RequestTarget( "label", dest_list=_addr_list_to_dest( ["host{0}".format(i) for i in range(4)]), ), lib.RequestData("action")) com.add_requests([request]) response_list = list(com.start_loop()) self.assertEqual(1, len(response_list)) response = response_list[0] self.assertFalse(response.was_connected) self.assertIs(request, response.request) self.assertEqual(Destination("host3", None), request.dest) self.assertEqual(4, mock_create_handle.call_count) mock_con_successful.assert_not_called() self.assertEqual(4, len(expected_response_list)) mock_create_handle.assert_has_calls([ mock.call(request, {}, settings.default_request_timeout) for _ in range(3) ]) logger_calls = ( fixture_logger_request_retry_calls(expected_response_list[0], Destination("host0", None)) + fixture_logger_request_retry_calls(expected_response_list[1], Destination("host1", None)) + fixture_logger_request_retry_calls( expected_response_list[2], Destination("host2", None)) + [ mock.call.log_request_start(request), mock.call.log_response(response), mock.call.log_no_more_addresses(response) ]) self.assertEqual(logger_calls, self.mock_com_log.mock_calls) com._multi_handle.assert_no_handle_left()
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 setUp(self): self.env_assist, self.config = get_env_tools(self) self.config.runner.cib.load(resources=self.fixture_multi_resources) self.multiple_result_reports = ( fixture.ReportStore() .error( "multiple_result_found", report_codes.MULTIPLE_RESULTS_FOUND, result_identifier_list=[ VIRTUAL_MACHINE_ID, REMOTE_HOST, "C", ], result_type="resource", search_description=REMOTE_HOST, force_code=report_codes.FORCE, ) .as_warn( "multiple_result_found", "multiple_result_found_warn", ) ) self.dest_list_b = [Destination("B-ADDR", 2224)] self.config.env.set_known_hosts_dests( { NODE_NAME: NODE_DEST_LIST, REMOTE_HOST: REMOTE_DEST_LIST, "B-NAME": self.dest_list_b, } )
def log_response(response, indent=0): label_data = [ ("action", response.request.action), ("label", response.request.target.label), ] if (response.request.target.dest_list != [ Destination(response.request.target.label, settings.pcsd_default_port), ]): label_data.append(("dest_list", response.request.target.dest_list)) label_data.append(("was_connected", response.was_connected)) if response.was_connected: label_data.append(("respose_code", response.response_code)) else: label_data.extend([ ("errno", response.errno), ("error_msg", response.error_msg), ]) label_data.append(("data", parse_qs(response.request.data))) return "{0}{1}".format( " " * indent, " ".join( ["{0}:'{1}'".format(key, value) for key, value in label_data]), )
def create_communication(communication_list, action="", param_list=None, response_code=200, output="", debug_output="", was_connected=True, errno=0, error_msg=None): """ list of dict communication_list -- each dict describes one request-response it accepts keys: string label -- required, the label of a node to talk with dest_list -- list of pcs.common.host.Destination where to send a request, defaults to [(label, default_pcsd_port)] string action -- pcsd url, see RequestData list of pairs param_list -- see RequestData int response_code -- http response code string output -- http response output string debug_output -- pycurl debug output bool was_connected -- see Response int errno -- see Response string error_msg -- see Response if some key is not present, it is put here from common values - rest args of this fuction(except name, communication_list, error_msg_template) string action -- pcsd url, see RequestData list of pairs (tuple) param_list -- see RequestData string response_code -- http response code string output -- http response output string debug_output -- pycurl debug output bool was_connected -- see Response int errno -- see Response string error_msg -- see Response """ # We don't care about tokens, see _communication_to_response. common = dict( action=action, param_list=param_list if param_list else (), response_code=response_code, output=output, debug_output=debug_output, was_connected=was_connected, errno=errno, error_msg=error_msg, ) response_list = [] for communication in communication_list: if "dest_list" not in communication: communication["dest_list"] = [ Destination(communication["label"], settings.pcsd_default_port) ] full = common.copy() full.update(communication) response_list.append(_communication_to_response(**full)) request_list = [response.request for response in response_list] return request_list, response_list
def __new__(cls, label, token=None, dest_list=()): if not dest_list: dest_list = [ Destination(label, settings.pcsd_default_port) ] return super(RequestTarget, cls).__new__( cls, label, token=token, dest_list=list(dest_list), )
def test_multiple_hosts(self): hosts = ["host1", "host2", "host3"] request = self._get_request( lib.RequestTarget("label", dest_list=_addr_list_to_dest(hosts))) for hostname in hosts: self.assertEqual(Destination(hostname, None), request.dest) if hostname == hosts[-1]: self.assertRaises(StopIteration, request.next_dest) else: request.next_dest()
def test_url_with_port(self): hostname = "host" port = 1234 self.assert_url( self._get_request( lib.RequestTarget( hostname, dest_list=[Destination(hostname, port)] ) ).url, hostname, self.action, port=port, )
def set_known_nodes(self, host_name_list): """ Set known hosts so that each host's address equals to the host's name list host_name_list -- list of host names """ self.__known_hosts_getter = lambda: { name: PcsKnownHost(name, token=None, dest_list= [Destination(name, settings.pcsd_default_port)]) for name in host_name_list }
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 log_request(request): label_data = [ ("action", request.action), ("label", request.target.label), ("data", parse_qs(request.data)), ] if (request.target.dest_list != [Destination(request.target.label, settings.pcsd_default_port)]): label_data.append(("dest_list", request.target.dest_list)) return " ".join( ["{0}:'{1}'".format(key, value) for key, value in label_data])
fixture_reports_not_live_cib, fixture_reports_new_node_unreachable, ) from pcs_test.tools import fixture from pcs_test.tools.command_env import get_env_tools from pcs_test.tools.misc import get_test_resource as rc from pcs_test.tools.xml import XmlManipulation from pcs import settings from pcs.common import reports from pcs.common.host import Destination from pcs.lib.commands.remote_node import node_add_guest as node_add_guest_orig NODE_NAME = "node-name" NODE_ADDR_PCSD = "node-addr" NODE_DEST_LIST = [Destination(NODE_ADDR_PCSD, 2224)] REMOTE_HOST = "remote-host" VIRTUAL_MACHINE_ID = "virtual_machine_id" NODE_1 = "node-1" NODE_1_DEST_LIST = [Destination("node-1-addr", 2224)] NODE_2 = "node-2" NODE_2_DEST_LIST = [Destination("node-2-addr", 2224)] KNOWN_HOSTS_DESTS = { NODE_NAME: NODE_DEST_LIST, NODE_1: NODE_1_DEST_LIST, NODE_2: NODE_2_DEST_LIST, } def node_add_guest( env,
FAIL_HTTP_KWARGS, ) from pcs_test.tier0.lib.commands.remote_node.fixtures_remove import ( EnvConfigMixin, REPORTS as FIXTURE_REPORTS, EXTRA_REPORTS as FIXTURE_EXTRA_REPORTS, ) from pcs_test.tools import fixture from pcs_test.tools.command_env import get_env_tools from pcs.common.reports import codes as report_codes from pcs.common.host import Destination from pcs.lib.commands.remote_node import ( node_remove_guest as node_remove_guest_orig, ) REMOTE_HOST = "remote-host" REMOTE_DEST_LIST = [Destination("remote-addr", 2224)] NODE_NAME = "node-name" NODE_DEST_LIST = [Destination("node-addr", 2224)] VIRTUAL_MACHINE_ID = "virtual_machine_id" def node_remove_guest(env, node_identifier=REMOTE_HOST, **kwargs): node_remove_guest_orig(env, node_identifier, **kwargs) REPORTS = (FIXTURE_REPORTS.adapt( "pcmk_remote_disable_stop_started", node_list=[NODE_NAME]).adapt( "pcmk_remote_disable_success", node=NODE_NAME).adapt( "pcmk_remote_stop_success", node=NODE_NAME).adapt("authkey_remove_started", node_list=[NODE_NAME
sys.path.insert(0, PACKAGE_DIR) from pcs.common.host import Destination from pcs.common.node_communicator import Request, RequestData, RequestTarget from pcs import utils logger_handler = logging.StreamHandler() logger_handler.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) logger = logging.getLogger("pcs") logger.setLevel(logging.DEBUG) logger.addHandler(logger_handler) global_target = RequestTarget( "TestServer", dest_list=[ Destination("httpbin.org2", 433), Destination("httpbin.org", 443), ] ) pprint.pprint(global_target) def get_request(timeout): return Request(global_target, RequestData("delay/{0}".format(timeout))) lib_env = utils.get_lib_env() # utils.pcs_options["--debug"] = True request_list = [get_request((i + 1) * 2) for i in range(6)] factory = lib_env.get_node_communicator_factory() factory._request_timeout = 10 communicator = factory.get_multiring_communicator()
def _addr_list_to_dest(addr_list, port=None): return [Destination(addr, port) for addr in addr_list]
def test_one_host(self): hostname = "host" request = self._get_request(lib.RequestTarget(hostname)) self.assertEqual(Destination(hostname, PORT), request.dest) self.assertRaises(StopIteration, request.next_dest)