/** * Copyright (c) 2021 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #include "common/server_framework/ob_net_easy.h" #include "common/server_framework/ob_net_rpc_handler.h" #include "observer/ob_rpc_processor.h" using oceanbase::common::ObNetEasy; using oceanbase::common::ObNetRpcHandler; using oceanbase::common::ObNetOptions; using namespace oceanbase::common; using namespace oceanbase::observer; namespace oceanbase { namespace unittest { namespace pub { template class MockP : public ObRpcProcessor { public: int process() { return ObRpcProcessor::response_result(); } }; class MockPacketHandler : public ObNetRpcHandler { public: int process(easy_request_t *r) { int ret = EASY_OK; if (NULL == r || NULL == r->ipacket) { SERVER_LOG(ERROR, "request is empty", K(r), K(r->ipacket)); ret = EASY_BREAK; } else { ObPacket *pkt = (ObPacket*) r->ipacket; if (NULL == pkt) { SERVER_LOG(ERROR, "receive NULL packet"); } else { pkt->set_request(r); easy_request_sleeping(r); // set alloc lock && inc ref count ret = process_pkt(*pkt); if (OB_SUCC(ret)) { ret = EASY_AGAIN; } else { easy_atomic_dec(&r->ms->c->pool->ref); easy_atomic_dec(&r->ms->pool->ref); if (OB_QUEUE_OVERFLOW == ret) { char buffer[32]; SERVER_LOG(WARN, "can not push packet to packet queue", "src", inet_ntoa_s(buffer, 32, r->ms->c->addr), "pcode", pkt->get_pcode()); } ret = EASY_OK; } } } return ret; } private: #define REG_PKT(pcode) \ case pcode: { \ p = new MockP(); \ break; \ } int process_pkt(ObPacket &pkt) { ObRequestProcessor *p = NULL; switch (pkt.get_pcode()) { REG_PKT(OB_GET_CONFIG); REG_PKT(OB_SET_CONFIG); REG_PKT(OB_BOOTSTRAP); REG_PKT(OB_EXECUTE_BOOTSTRAP); REG_PKT(OB_IS_EMPTY_SERVER); REG_PKT(OB_FETCH_SCHEMA); default: { } } if (NULL != p) { ObDataBuffer buf; alloc_buffer(buf); p->set_buffer(&buf); p->set_ob_packet(&pkt); p->process(); free_buffer(buf); delete p; } return OB_SUCCESS; } void alloc_buffer(ObDataBuffer &buf) { buf.set_data(new char[OB_MAX_PACKET_LENGTH], OB_MAX_PACKET_LENGTH); } void free_buffer(ObDataBuffer &buf) { delete [] buf.get_data(); } }; // end of class MockPacketHandler class MockServer : public ObNetEasy { public: int init(int port) { int ret = OB_SUCCESS; ObNetOptions opts; opts.type_ = ObNetOptions::SERVER; opts.lport_ = port; opts.io_cnt_ = 1; if (OB_SUCCESS != (ret = ObNetEasy::init(phandler_, opts))) { SERVER_LOG(ERROR, "init client network fail", K(ret)); } return ret; } private: MockPacketHandler phandler_; }; // end of class MockServer } // end of namespace public } // end of namespace unittest } // end of namespace oceanbase