| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to You under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <gtest/gtest.h> |
| #include <cstring> |
| #include <string> |
| #include "butil/macros.h" |
| #include "butil/sys_byteorder.h" |
| #include "brpc/socket.h" |
| |
| #if BRPC_WITH_UBRING |
| #include "brpc/ubshm/ub_endpoint.h" |
| #include "brpc/ubshm/shm/shm_def.h" |
| #include "brpc/ubshm/shm/shm_mgr.h" |
| #include "brpc/ubshm/ub_ring_manager.h" |
| |
| namespace brpc { |
| namespace ubring { |
| extern bool g_skip_ub_init; |
| } // namespace ubring |
| } // namespace brpc |
| |
| namespace { |
| struct __attribute__((packed)) HelloMessageLayout { |
| uint16_t msg_len; |
| uint16_t hello_ver; |
| uint16_t impl_ver; |
| uint64_t len; |
| char shm_name[SHM_MAX_NAME_BUFF_LEN]; |
| }; |
| } |
| |
| class HelloMessageTest : public ::testing::Test { |
| protected: |
| void SetUp() override { |
| memset(&msg, 0, sizeof(msg)); |
| buffer.resize(256, 0); |
| } |
| |
| brpc::ubring::HelloMessage msg; |
| std::string buffer; |
| }; |
| |
| TEST_F(HelloMessageTest, serialize_deserialize_roundtrip) { |
| msg.msg_len = 64; |
| msg.hello_ver = 2; |
| msg.impl_ver = 1; |
| msg.len = 4 * 1024 * 1024; |
| memcpy(msg.shm_name, "UBRING_test_C", 14); |
| |
| msg.Serialize(&buffer[0]); |
| |
| brpc::ubring::HelloMessage decoded; |
| memset(&decoded, 0, sizeof(decoded)); |
| decoded.Deserialize(&buffer[0]); |
| |
| EXPECT_EQ(msg.msg_len, decoded.msg_len); |
| EXPECT_EQ(msg.hello_ver, decoded.hello_ver); |
| EXPECT_EQ(msg.impl_ver, decoded.impl_ver); |
| EXPECT_EQ(msg.len, decoded.len); |
| EXPECT_EQ(0, memcmp(msg.shm_name, decoded.shm_name, SHM_MAX_NAME_BUFF_LEN)); |
| } |
| |
| TEST_F(HelloMessageTest, serialize_uses_network_byte_order) { |
| msg.msg_len = 0x0102; |
| msg.hello_ver = 0x0304; |
| msg.impl_ver = 0x0506; |
| msg.len = 0x0102030405060708ULL; |
| memset(msg.shm_name, 0, SHM_MAX_NAME_BUFF_LEN); |
| |
| msg.Serialize(&buffer[0]); |
| |
| HelloMessageLayout* raw = reinterpret_cast<HelloMessageLayout*>(&buffer[0]); |
| EXPECT_EQ(butil::HostToNet16(0x0102), raw->msg_len); |
| EXPECT_EQ(butil::HostToNet16(0x0304), raw->hello_ver); |
| EXPECT_EQ(butil::HostToNet16(0x0506), raw->impl_ver); |
| EXPECT_EQ(butil::HostToNet64(0x0102030405060708ULL), raw->len); |
| } |
| |
| TEST_F(HelloMessageTest, large_len_value) { |
| msg.msg_len = 64; |
| msg.hello_ver = 2; |
| msg.impl_ver = 1; |
| msg.len = 0xFFFFFFFFFFFFFFFFULL; |
| memset(msg.shm_name, 0, SHM_MAX_NAME_BUFF_LEN); |
| |
| msg.Serialize(&buffer[0]); |
| |
| brpc::ubring::HelloMessage decoded; |
| memset(&decoded, 0, sizeof(decoded)); |
| decoded.Deserialize(&buffer[0]); |
| |
| EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, decoded.len); |
| } |
| |
| TEST_F(HelloMessageTest, full_shm_name) { |
| memset(msg.shm_name, 'A', SHM_MAX_NAME_BUFF_LEN); |
| msg.msg_len = 64; |
| msg.hello_ver = 2; |
| msg.impl_ver = 1; |
| msg.len = 0; |
| msg.Serialize(&buffer[0]); |
| |
| brpc::ubring::HelloMessage decoded; |
| memset(&decoded, 0, sizeof(decoded)); |
| decoded.Deserialize(&buffer[0]); |
| |
| EXPECT_EQ(0, memcmp(msg.shm_name, decoded.shm_name, SHM_MAX_NAME_BUFF_LEN)); |
| } |
| |
| TEST_F(HelloMessageTest, toString_contains_fields) { |
| msg.msg_len = 64; |
| msg.hello_ver = 2; |
| msg.impl_ver = 1; |
| msg.len = 4194304; |
| memcpy(msg.shm_name, "UBRING_test", 12); |
| |
| std::string s = msg.toString(); |
| EXPECT_NE(std::string::npos, s.find("msg_len=64")); |
| EXPECT_NE(std::string::npos, s.find("hello_ver=2")); |
| EXPECT_NE(std::string::npos, s.find("impl_ver=1")); |
| EXPECT_NE(std::string::npos, s.find("UBRING_test")); |
| } |
| |
| namespace brpc { |
| namespace ubring { |
| class UBShmEndpointTest : public ::testing::Test { |
| protected: |
| void SetUp() override { |
| _saved_skip = g_skip_ub_init; |
| g_skip_ub_init = false; |
| ShmMgrInit(); |
| UBRingManager::UbrMgrInit(); |
| UBShmEndpoint::GlobalInitialize(); |
| |
| brpc::SocketOptions options; |
| ASSERT_EQ(0, brpc::Socket::Create(options, &_socket_id)); |
| brpc::SocketUniquePtr s; |
| ASSERT_EQ(0, brpc::Socket::Address(_socket_id, &s)); |
| _socket = s.get(); |
| _ep = new UBShmEndpoint(_socket); |
| } |
| |
| void TearDown() override { |
| delete _ep; |
| brpc::SocketUniquePtr s; |
| if (brpc::Socket::Address(_socket_id, &s) == 0) { |
| s->SetFailed(); |
| } |
| UBShmEndpoint::GlobalRelease(); |
| UBRingManager::UbrMgrFini(); |
| ShmMgrFini(); |
| g_skip_ub_init = _saved_skip; |
| } |
| |
| brpc::SocketId _socket_id = brpc::INVALID_SOCKET_ID; |
| brpc::Socket* _socket = nullptr; |
| UBShmEndpoint* _ep = nullptr; |
| bool _saved_skip = false; |
| }; |
| } // namespace ubring |
| } // namespace brpc |
| |
| using brpc::ubring::UBShmEndpointTest; |
| |
| TEST_F(UBShmEndpointTest, construct_initial_state) { |
| ASSERT_NE(nullptr, _ep); |
| } |
| |
| TEST_F(UBShmEndpointTest, allocate_client_resources_real_shm) { |
| brpc::ubring::SHM local_trx_shm = |
| {NULL, 4 * 1024 * 1024, 0, {0}, (uint32_t)_socket->fd()}; |
| int ret = _ep->AllocateClientResources(&local_trx_shm, "UBRING_ut_client"); |
| EXPECT_EQ(0, ret); |
| } |
| |
| TEST_F(UBShmEndpointTest, reset_cleans_up_resources) { |
| brpc::ubring::SHM local_trx_shm = |
| {NULL, 4 * 1024 * 1024, 0, {0}, (uint32_t)_socket->fd()}; |
| _ep->AllocateClientResources(&local_trx_shm, "UBRING_ut_reset"); |
| _ep->Reset(); |
| } |
| |
| TEST_F(UBShmEndpointTest, reset_is_idempotent) { |
| _ep->Reset(); |
| _ep->Reset(); |
| } |
| |
| #else |
| |
| TEST(UbringDisabledTest, skip) { |
| SUCCEED() << "BRPC_WITH_UBRING is not enabled, skip."; |
| } |
| |
| #endif // BRPC_WITH_UBRING |