def _call_before_write_log_iterator(self, rpc_request, call_mode=EnumCallMode.Simple, timeout=None, trace_info=None): """ 远程调用前写日志,并返回要调用的iterator对象 """ for _request in rpc_request: # 增加调用链信息 _request.trace_id = trace_info.trace_id _request.parent_id = trace_info.call_id _request.trace_level = trace_info.trace_level if self._logger is not None: # 逐个登记调用日志 _info_dict = self._get_request_info_dict(_request, call_mode=call_mode, timeout=timeout, trace_info=trace_info) _info_dict['api_info_type'] = 'STREAM-SEND' _info_dict['err_log_msg'] = 'api call chain send log error' SimpleGRpcTools.write_api_call_chain_log( self._logger, _info_dict) # 返回调用对象 yield _request
def test(self): """ 检测连接是否有效 @returns {CResult} - 响应对象,判断成功的方法: ret.status == msg_pb2.HealthResponse.SERVING 总共有以下几种状态 health_pb2.HealthResponse.UNKNOWN health_pb2.HealthResponse.SERVICE_UNKNOWN health_pb2.HealthResponse.NOT_SERVING health_pb2.HealthResponse.SERVING """ _check_result = CResult() if self._channel is None: # 没有连接 _check_result.status = msg_pb2.HealthResponse.UNKNOWN elif self._test_use_health_check: # 使用标准健康检查 self._health_stub = SimpleGRpcTools.generate_health_check_stub( self._channel) _check_result = SimpleGRpcTools.health_check_by_stub( self._health_stub, self._servicer_name, timeout=self._timeout) else: # 使用自定义的健康检查 _check_result = SimpleGRpcTools.simple_grpc_health_check_by_stub( self._stub, timeout=self._timeout) # 返回结果 return _check_result
def server_side_stream_call(a, b, *args, **kwargs): """ 服务端流模式,真正调用服务端的函数 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_server_side_stream', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes ) # 发送请求, 默认使用全局的日志对象 _connect_para = SimpleGRpcConnection.generate_connect_para( ip='127.0.0.1', port=50051 ) _connection = SimpleGRpcConnection(_connect_para) _cresult_iterator = _connection.call(_req_obj, call_mode=EnumCallMode.ServerSideStream) _ret = True for _cresult in _cresult_iterator: if not _cresult.is_success(): _ret = False _connection.close() return _ret
def client_simple_call_para_server_tsl(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs): """ 测试简单调用,进行单向认证(客户端验证服务端证书) """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values( is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_simple_call_para', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes) # 发送请求 with open(_TEMP_DIR + '/../../simple_grpc/server.crt', 'rb') as f: _root_certificates = f.read() _connect_para = SimpleGRpcTools.generate_connect_para( ip='localhost', port=50053, is_use_ssl=True, root_certificates=_root_certificates) _cresult = SimpleGRpcTools.grpc_call(_connect_para, _req_obj) _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _cresult.return_json, 'client_simple_call_para') return _cresult
def server_bidirectional_stream_call_one_by_one(): """ 双向流模式,客户端处理,一个请求对应一个响应的情况 通过队列传递交互传递参数 """ # 清空队列 TEMP_QUEUE.queue.clear() # 处理 _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) with SimpleGRpcTools.generate_channel(_connect_para) as channel: # # 注意队列一定要先传入一个值 TEMP_QUEUE.put(None) _cresult_iterator = SimpleGRpcTools.grpc_call_by_channel( channel, bidirectional_stream_one_by_one_generator(), call_mode=EnumCallMode.BidirectionalStream) for _cresult in _cresult_iterator: # 放入队列 s = _cresult.return_json TEMP_QUEUE.put(s) if not _cresult.is_success(): return False return True
def _mutiple_thread_fun(self, i, connect, result: list): """ 多线程处理 """ _i = i + 1 # 参数处理 _para_obj = SimpleGRpcTools.parameters_to_json([['', _i]], is_support_bytes=True) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_mutiple_thread', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes ) # 通知外面执行是否成功 result[i] = False # 访问服务 _cresult: CResult = connect.call(_req_obj) self.assertTrue( _cresult.is_success(), msg='_mutiple_thread_fun [%d] error: %s' % (i, str(_cresult)) ) self.assertTrue( _cresult.return_json == str(_i), msg='_mutiple_thread_fun [%d] return error: %s' % (i, str(_cresult.return_json)) ) # 通知外面执行是否成功 result[i] = True
def client_simple_call_para_double_tsl(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs): """ 测试简单调用,进行双向认证(服务端验证客户端证书,客户端验证服务端证书) """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_simple_call_para', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes ) # 发送请求 with open(_TEMP_DIR + '/../../simple_grpc/client.pem', 'rb') as f: _client_private_key = f.read() with open(_TEMP_DIR + '/../../simple_grpc/client.crt', 'rb') as f: _client_certificate_chain = f.read() with open(_TEMP_DIR + '/../../simple_grpc/server.crt', 'rb') as f: _root_certificates = f.read() # 发送请求, 默认使用全局的日志对象 _connect_para = SimpleGRpcConnection.generate_connect_para( ip='localhost', port=50052, is_use_ssl=True, root_certificates=_root_certificates, private_key=_client_private_key, certificate_chain=_client_certificate_chain ) _connection = SimpleGRpcConnection(_connect_para) _cresult = _connection.call(_req_obj) _connection.close() _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _cresult.return_json, 'client_simple_call_para' ) return _cresult
def test_error(self): """ 测试错误信息 """ if not TEST_FLAG['test_error']: return print("测试错误信息") print("测试错误信息 - 连接失败") _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=60051) _cresult = SimpleGRpcTools.grpc_call( _connect_para, SimpleGRpcTools.generate_request_obj('test')) self.assertTrue( _cresult.code == '20408' and grpc.StatusCode.UNAVAILABLE.name == _cresult.i18n_msg_paras[0], '测试错误信息失败 - 连接失败 ') print("测试错误信息 - 服务名不存在") _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) _cresult = SimpleGRpcTools.grpc_call( _connect_para, SimpleGRpcTools.generate_request_obj('test', '')) self.assertTrue(_cresult.code == '11403', '测试错误信息失败 - 服务名不存在 ') print("测试错误信息 - 超时") _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) _cresult = SimpleGRpcTools.grpc_call( _connect_para, SimpleGRpcTools.generate_request_obj('service_simple_overtime'), timeout=0.1) self.assertTrue(_cresult.code == '30403', '测试错误信息失败 - 超时')
def bidirectional_stream_single_request(a, b, *args, **kwargs): """ 双向流模式,产生请求对象的函数 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_bidirectional_stream', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes ) return _req_obj
def client_side_stream_call(): """ 客户端流模式,真正调用服务端的函数 """ # 发送请求 _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) _cresult = SimpleGRpcTools.grpc_call( _connect_para, client_side_stream_generator(), call_mode=EnumCallMode.ClientSideStream) _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _cresult.return_json, 'service_client_side_stream') return _cresult
def server_bidirectional_stream_call_n_by_one(): """ 双向流模式,客户端处理,多个请求对应一个响应的情况 """ # 处理 _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) with SimpleGRpcTools.generate_channel(_connect_para) as channel: _cresult_iterator = SimpleGRpcTools.grpc_call_by_channel( channel, bidirectional_stream_n_by_one_generator(), call_mode=EnumCallMode.BidirectionalStream) for _cresult in _cresult_iterator: # 打印 print('bidirectional_stream_n_by_one client get: ' + _cresult.return_json) if not _cresult.is_success(): return False return True
def get_client_simple_call_para(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs): """ 测试简单调用,直接返回参数 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values( is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_simple_call_para', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes) return _req_obj
def __init__(self, connect_para): """ 构造函数 @param {NullObj} connect_para - 具体参数见SimpleGRpcConnection.generate_connect_para函数的定义 @throws {ConnectionError} - 如果连接时需要检查有效性,当检查失败时抛出该异常 """ # 内部变量初始化 self._trace_info_dict = dict() # 初始化参数 self._connect_para = connect_para self._fill_connect_para(self._connect_para) self._test_on_connect = connect_para.test_on_connect self._test_use_health_check = connect_para.test_use_health_check self._servicer_name = connect_para.servicer_name self._logger = connect_para.logger self._log_level = connect_para.log_level self._timeout = connect_para.timeout # 日志处理 if self._logger is None and connect_para.is_use_global_logger: # 使用全局logger self._logger = RunTool.get_global_logger() # 进行连接 self._channel = SimpleGRpcTools.generate_channel(self._connect_para) self._stub = SimpleGRpcTools.generate_call_stub(self._channel) # 检查连接有效性 if self._test_on_connect: _check_result = self.test() if _check_result.status != msg_pb2.HealthResponse.SERVING: # 连接失败,打印日志后抛出异常 if self._logger is not None: self._logger.log( self._log_level, '[EX:%s]%s%s\n%s' % (_check_result.error, 'SimpleGRpcConnection init error: ', _check_result.msg, _check_result.trace_str)) raise ConnectionError(_check_result.msg)
def client_simple_throw_excepiton(): """ 测试简单调用,抛出异常 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values( is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_simple_throw_excepiton', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes) # 发送请求 _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) _cresult = SimpleGRpcTools.grpc_call(_connect_para, _req_obj) _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _cresult.return_json, 'client_simple_throw_excepiton') return _cresult
def _call_after_write_log(self, cresult, start_time, call_mode=EnumCallMode.Simple, timeout=None, trace_info=None): """ 登记返回结果日志 """ if self._logger is not None: # 登记返回结果日志 _info_dict = self._get_cresult_info_dict(cresult, start_time, call_mode=call_mode, timeout=timeout, trace_info=trace_info) _info_dict['err_log_msg'] = 'api call chain back log error' SimpleGRpcTools.write_api_call_chain_log(self._logger, _info_dict) return cresult
def client_simple_call_para(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs): """ 测试简单调用,直接返回参数 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values( is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_simple_call_para', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes) # 发送请求 _connect_para = SimpleGRpcTools.generate_connect_para( conn_str='127.0.0.1:50051') _cresult = SimpleGRpcTools.grpc_call(_connect_para, _req_obj) _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _cresult.return_json, 'client_simple_call_para') return _cresult
def _call_after_write_log_iterator(self, cresult_iterator, start_time, call_mode=EnumCallMode.Simple, timeout=None, trace_info=None): for _cresult in cresult_iterator: if self._logger is not None: # 逐个登记返回结果日志 _info_dict = self._get_cresult_info_dict(_cresult, start_time, call_mode=call_mode, timeout=timeout, trace_info=trace_info) _info_dict['err_log_msg'] = 'api call chain back log error' SimpleGRpcTools.write_api_call_chain_log( self._logger, _info_dict) # 返回结果对象 yield _cresult
def client_simple_throw_excepiton(): """ 测试简单调用,抛出异常 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values( is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_simple_throw_excepiton', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes) # 发送请求, 默认使用全局的日志对象 _connect_para = SimpleGRpcConnection.generate_connect_para( conn_str='127.0.0.1:50051') _connection = SimpleGRpcConnection(_connect_para) _cresult = _connection.call(_req_obj) _connection.close() _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _cresult.return_json, 'client_simple_throw_excepiton') return _cresult
def server_side_stream_call(a, b, *args, **kwargs): """ 服务端流模式,真正调用服务端的函数 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values( is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_server_side_stream', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes) _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) with SimpleGRpcTools.generate_channel(_connect_para) as channel: _cresult_iterator = SimpleGRpcTools.grpc_call_by_channel( channel, _req_obj, call_mode=EnumCallMode.ServerSideStream) for _cresult in _cresult_iterator: if not _cresult.is_success(): return False return True
def test_health_check(self): """ 测试服务健康状态 """ if not TEST_FLAG['test_health_check']: return print("测试服务健康状态") _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1', port=50051) print("测试服务健康状态 - 服务中") _resp_obj = SimpleGRpcTools.health_check(_connect_para, 'servicer_simple_call') self.assertTrue( _resp_obj.status == health_pb2.HealthCheckResponse.SERVING, '测试服务健康状态失败 - 服务中') print("测试服务健康状态 - 停止服务") self.server_no_ssl_no_zoo.set_service_status( 'servicer_simple_call', health_pb2.HealthCheckResponse.NOT_SERVING) _resp_obj = SimpleGRpcTools.health_check(_connect_para, 'servicer_simple_call') self.assertTrue( _resp_obj.status == health_pb2.HealthCheckResponse.NOT_SERVING, '测试服务健康状态失败 - 停止服务') # 恢复服务 self.server_no_ssl_no_zoo.set_service_status( 'servicer_simple_call', health_pb2.HealthCheckResponse.SERVING) print("测试服务健康状态 - 服务不存在") _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.2', port=50051) _resp_obj = SimpleGRpcTools.health_check(_connect_para, 'servicer_simple_call') self.assertTrue( _resp_obj.status == health_pb2.HealthCheckResponse.UNKNOWN, '测试服务健康状态失败 - 服务不存在')
def reconnect(self): """ 重新连接 @returns {CResult} - 响应对象,判断成功的方法: ret.status == msg_pb2.HealthResponse.SERVING 总共有以下几种状态 health_pb2.HealthResponse.UNKNOWN health_pb2.HealthResponse.SERVICE_UNKNOWN health_pb2.HealthResponse.NOT_SERVING health_pb2.HealthResponse.SERVING """ # 先关闭连接 self.close() # 进行连接 self._channel = SimpleGRpcTools.generate_channel(self._connect_para) self._stub = SimpleGRpcTools.generate_call_stub(self._channel) # 检查连接有效性 if self._test_on_connect: _check_result = self.test() if not _check_result.is_success( ) or _check_result.status != msg_pb2.HealthResponse.SERVING: # 连接失败,打印日志后抛出异常 if self._logger is not None: self._logger.log( self._log_level, '[EX:%s]%s%s, service status:%s\n%s' % (_check_result.error, 'SimpleGRpcConnection reconnect error: ', _check_result.msg, _check_result.status, _check_result.trace_str)) return _check_result else: # 不检查的情况,直接返回成功,连接状态为SERVING _check_result = CResult('00000') _check_result.status = msg_pb2.HealthResponse.SERVING return _check_result
def _call_before_write_log(self, rpc_request, call_mode=EnumCallMode.Simple, timeout=None, trace_info=None): """ 远程调用前写日志,并返回要调用的参数 """ # 增加调用链信息 rpc_request.trace_id = trace_info.trace_id rpc_request.parent_id = trace_info.call_id rpc_request.trace_level = trace_info.trace_level if self._logger is not None: # 登记调用日志 _info_dict = self._get_request_info_dict(rpc_request, call_mode=call_mode, timeout=timeout, trace_info=trace_info) _info_dict['err_log_msg'] = 'api call chain send log error' SimpleGRpcTools.write_api_call_chain_log(self._logger, _info_dict) return rpc_request
def client_simple_call_para(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs): """ 测试简单调用,直接返回参数 """ # 转换参数 _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True) _para_obj = SimpleGRpcTools.parameters_to_json(_para_values) _req_obj = SimpleGRpcTools.generate_request_obj( service_name='service_simple_call_para', para_json=_para_obj.para_json, has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes ) # 发送请求, 默认使用全局的日志对象 _connect_para = SimpleGRpcConnection.generate_connect_para( conn_str='127.0.0.1:50051', servicer_name='servicer_simple_call', test_on_connect=True, test_use_health_check=False ) _connection = SimpleGRpcConnection(_connect_para) _cresult = _connection.call(_req_obj) _connection.close() _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _cresult.return_json, 'client_simple_call_para' ) return _cresult
def call(self, rpc_request, call_mode=EnumCallMode.Simple, timeout=None, metadata=None, credentials=None, wait_for_ready=None, compression=None, **kwargs): """ 执行gRPC远程调用 @param {msg_pb2.RpcRequest|request_iterator} rpc_request - 请求对象或产生请求对象的迭代器(iterator),应与call_mode匹配 @param {EnumCallMode} call_mode=EnumCallMode.Simple - 调用服务端的模式 @param {number} timeout=None - 超时时间,单位为秒 @param {object} metadata=None - Optional :term:`metadata` to be transmitted to the service-side of the RPC. @param {object} credentials=None - An optional CallCredentials for the RPC. Only valid for secure Channel. @param {object} wait_for_ready=None - This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism @param {object} compression=None - An element of grpc.compression, e.g. grpc.compression.Gzip. This is an EXPERIMENTAL option. @param {**kwargs} kwargs - 动态参数,用于支持调用链信息 @returns {CResult|iterator} - 执行结果CResult或执行结果的迭代器(iterator),与call_mode匹配 CResult对象有以下3个属性: return_json - 返回值的json字符串 has_return_bytes - 是否有返回字节数组 return_bytes - 返回的字节数组 """ _start_time = datetime.datetime.now() # 开始处理时间 _trace_info = self._get_trace_info(**kwargs) # 获取调用链信息 _request = None _timeout = timeout if timeout is None or timeout <= 0: _timeout = self._connect_para.timeout # 发送之前记录日 if call_mode in [EnumCallMode.Simple, EnumCallMode.ServerSideStream]: _request = self._call_before_write_log(rpc_request=rpc_request, call_mode=call_mode, timeout=_timeout, trace_info=_trace_info) else: _request = self._call_before_write_log_iterator( rpc_request=rpc_request, call_mode=call_mode, timeout=_timeout, trace_info=_trace_info) # 执行调用 _cresult_call = SimpleGRpcTools.grpc_call_by_stub( self._stub, rpc_request=_request, call_mode=call_mode, timeout=_timeout, metadata=metadata, credentials=credentials, wait_for_ready=wait_for_ready, compression=compression) # 接收响应后记录日志 if call_mode in [EnumCallMode.Simple, EnumCallMode.ClientSideStream]: _cresult = self._call_after_write_log(_cresult_call, _start_time, call_mode=call_mode, timeout=_timeout, trace_info=_trace_info) else: _cresult = self._call_after_write_log_iterator( _cresult_call, _start_time, call_mode=call_mode, timeout=_timeout, trace_info=_trace_info) # 返回结果 return _cresult
def setUpClass(cls): """ 启动测试类执行的初始化,只执行一次 """ # 初始化日志类 DebugTool.set_debug(False) try: # 删除临时日志 FileTool.remove_files(path=_TEMP_DIR + '/log/', regex_str='test_case*') except: pass cls.logger = simple_log.Logger( conf_file_name=_TEMP_DIR + '/../../simple_grpc/test_simple_grpc.json', logger_name=simple_log.EnumLoggerName.ConsoleAndFile, config_type=simple_log.EnumLoggerConfigType.JSON_FILE, logfile_path=_TEMP_DIR + '/log/test_case_asyn.log', is_create_logfile_by_day=True, ) cls.logger.setLevelWithHandler(simple_log.DEBUG) # 设置json转换对象的参数映射 # 日志处理函数 def _asyn_logging_fun(levelno, topic_name, msg): print('haha:%s, %s, %s' % (str(levelno), topic_name, msg)) # 异步日志 cls._asyn_logger = CallChainTool.create_call_chain_logger( logger=cls.logger, asyn_logging=True, asyn_logging_fun=_asyn_logging_fun, asyn_deal_msg_fun=SimpleGRpcTools.api_call_chain_asyn_deal_msg_fun) # 服务端处理类,可以多个服务公用 cls.servicer_simple_call = SimpleGRpcServicer(logger=cls._asyn_logger) cls.servicer_simple_call.add_service(EnumCallMode.Simple, 'service_simple_call_para', service_simple_call_para) cls.servicer_simple_call.add_service( EnumCallMode.Simple, 'service_simple_call_no_para_no_return', service_simple_call_no_para_no_return) cls.servicer_simple_call.add_service(EnumCallMode.Simple, 'service_simple_call_return', service_simple_call_return) cls.servicer_simple_call.add_service(EnumCallMode.Simple, 'service_simple_throw_excepiton', service_simple_throw_excepiton) cls.servicer_simple_call.add_service(EnumCallMode.Simple, 'service_simple_overtime', service_simple_overtime) cls.servicer_simple_call.add_service(EnumCallMode.ClientSideStream, 'service_client_side_stream', service_client_side_stream) cls.servicer_simple_call.add_service(EnumCallMode.ServerSideStream, 'service_server_side_stream', service_server_side_stream) cls.servicer_simple_call.add_service(EnumCallMode.BidirectionalStream, 'service_bidirectional_stream', service_bidirectional_stream) # 初始化并启动服务,简单服务,无SSL,无服务发现 cls.server_no_ssl_no_zoo_opts = SimpleGRpcServer.generate_server_opts( ip='127.0.0.1', port=50051, max_workers=10, max_connect=100, is_health_check=True) cls.server_no_ssl_no_zoo = SimpleGRpcServer( server_name='ServerNoSslNoZoo', logger=cls.logger, log_level=simple_log.INFO) cls.server_no_ssl_no_zoo.start_server( server_opts=cls.server_no_ssl_no_zoo_opts, servicer_list={'servicer_simple_call': cls.servicer_simple_call}, is_wait=True) # 初始化并启动服务,简单服务,无服务发现,TSL双向认证模式 _private_key_certificate_chain_pair = SimpleGRpcTools.get_private_key_certificate_chain_pair( _TEMP_DIR + '/../../simple_grpc/server.pem', _TEMP_DIR + '/../../simple_grpc/server.crt') with open(_TEMP_DIR + '/../../simple_grpc/client.crt', 'rb') as f: # 根证书 _root_certificates = f.read() cls.server_double_ssl_no_zoo_opts = SimpleGRpcServer.generate_server_opts( ip='localhost', port=50052, max_workers=10, max_connect=100, is_use_ssl=True, private_key_certificate_chain_pairs=( _private_key_certificate_chain_pair, ), root_certificates=_root_certificates) cls.server_double_ssl_no_zoo = SimpleGRpcServer( server_name='ServerDoubleSslNoZoo', logger=cls.logger, log_level=simple_log.INFO) cls.server_double_ssl_no_zoo.start_server( server_opts=cls.server_double_ssl_no_zoo_opts, servicer_list={'servicer_simple_call': cls.servicer_simple_call}, is_wait=True) # 初始化并启动服务,简单服务,无服务发现,TSL单向认证模式(仅验证服务端证书) cls.server_server_ssl_no_zoo_opts = SimpleGRpcServer.generate_server_opts( ip='localhost', port=50053, max_workers=10, max_connect=100, is_use_ssl=True, private_key_certificate_chain_pairs=( _private_key_certificate_chain_pair, ), root_certificates=None) cls.server_server_ssl_no_zoo = SimpleGRpcServer( server_name='ServerServerSslNoZoo', logger=cls.logger, log_level=simple_log.INFO) cls.server_server_ssl_no_zoo.start_server( server_opts=cls.server_server_ssl_no_zoo_opts, servicer_list={'servicer_simple_call': cls.servicer_simple_call}, is_wait=True)
def test_connect_pool(self): """ 测试连接池 """ print("开始测试连接池") _connect_para = SimpleGRpcConnection.generate_connect_para( conn_str='127.0.0.1:50051', servicer_name='servicer_simple_call', test_on_connect=False, test_use_health_check=False) # 建立连接池 _pool = SimpleGRpcConnectionPool(_connect_para, name='ConnectionPool', maxsize=3, minsize=0, realse_free_time=5, test_on_get=True, test_on_free=True, test_while_idle=True, test_idle_time=5, validation_query='', get_connection_timeout=1, logger=self._asyn_logger, init_break_if_connect_error=True) print("测试连接池-获取连接并执行") # 尝试获取连接 _connection = _pool.get_connection() _back_server = service_simple_call_para('a1', 'b1') _req_obj = get_client_simple_call_para('a1', 'b1') _back_client = _connection.call(_req_obj) _back_client.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping( _back_client.return_json, 'client_simple_call_para') self.assertTrue( _back_client.is_success(), msg= '测试连接池-获取连接并执行失败,执行RPC失败: code=%s, msg=%s, error=%s, i18n_msg_paras=%s' % (_back_client.code, _back_client.msg, _back_client.error, str(_back_client.i18n_msg_paras))) self.assertTrue(compare_object_by_json(_back_server, _back_client.return_obj), msg='测试连接池-获取连接并执行, 执行参数不一致') print('测试连接池-获取连接超时') _c1 = _pool.get_connection() _c2 = _pool.get_connection() try: _c3 = _pool.get_connection() self.assertTrue(False, msg='测试连接池-获取连接超时失败,应抛出超时') except TimeoutError: pass except Exception as e: self.assertTrue(False, msg='测试连接池-获取连接超时失败,未期望的异常:%s' % str(e)) self.assertTrue(3 == _pool.current_size, msg='测试连接池-获取连接超时-当前连接池大小错误:%d' % _pool.current_size) print('测试连接池-释放连接') _pool.free_connection(_connection) _c3 = _pool.get_connection() # 这样c3可用获取连接并使用 self.assertTrue(3 == _pool.current_size, msg='测试连接池-释放连接-当前连接池大小错误:%d' % _pool.current_size) print('测试连接池-自动释放连接') _pool.free_connection(_c1) _pool.free_connection(_c2) _pool.free_connection(_c3) time.sleep(10) self.assertTrue(0 == _pool.current_size, msg='测试连接池-自动释放连接-当前连接池大小错误:%d' % _pool.current_size)