手撕基于AMQP協議的簡易消息隊列-8(單元測試的編寫)

在MQTest中編寫模塊的單元測試

在MQTest中編寫makefile文件來編譯客戶端模塊
all:Test_FileHelper Test_Exchange Test_Queue Test_Binding Test_Message Test_VirtualHost Test_Route Test_Consumer Test_Channel Test_Connection Test_VirtualHost:Test_VirtualHost.cpp ../MQCommon/message.pb.ccg++ -g -o $@ $^ -std=c++11 -lgtest -lprotobuf -lsqlite3 -pthreadTest_Binding:Test_Binding.cppg++ -g -o $@ $^ -std=c++11 -lgtest -lprotobuf -lsqlite3 -pthreadTest_Queue:Test_Queue.cppg++ -g -o $@ $^ -std=c++11 -lgtest -lprotobuf -lsqlite3 -pthreadTest_FileHelper:Test_FileHelper.cppg++ -o $@ $^ -std=c++11Test_Exchange:Test_Exchange.cppg++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3Test_Message:Test_Message.cpp ../MQCommon/message.pb.ccg++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3Test_Route:Test_Route.cpp ../MQCommon/message.pb.ccg++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3Test_Consumer:Test_Consumer.cpp ../MQCommon/message.pb.ccg++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3Test_Channel:Test_Channel.cpp ../MQCommon/message.pb.cc ../MQCommon/request.pb.ccg++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3 -I../ThirdLib/lib/includeTest_Connection:Test_Connection.cpp ../MQCommon/message.pb.cc ../MQCommon/request.pb.ccg++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3 -I../ThirdLib/lib/include.PHONY:
clean:rm -rf Test_FileHelper Test_Exchange Test_Queue Test_Binding Test_Message Test_VirtualHost Test_Route Test_Consumer Test_Channel Test_Connection
在MQTest中編寫Test_Exchange.cpp文件來編譯交換機模塊單元測試
#include "../MQServer/Exchange.hpp"
#include <gtest/gtest.h>
#include<unordered_map>
MQ::ExchangeManager::ptr emp;class ExchangeTest : public testing::Environment
{
public:virtual void SetUp() override{emp = std::make_shared<MQ::ExchangeManager>("./data/meta.db");}virtual void TearDown() override{emp->clear();std::cout << "最后的清理!!\n";}
};TEST(exchange_test, insert_test)
{std::unordered_map<std::string, std::string> tmp =  {{"k1","v1"},{"k2","v2"}};std::unordered_map<std::string, std::string> map;map.insert(tmp.begin(),tmp.end());for(auto& a : map){std::cout<<a.first<<' '<<a.second<<std::endl;}emp->declareExchange("exchange1", MQ::ExchangeType::DIRECT, true, false, map);emp->declareExchange("exchange2", MQ::ExchangeType::DIRECT, true, false, map);emp->declareExchange("exchange3", MQ::ExchangeType::DIRECT, true, false, map);emp->declareExchange("exchange4", MQ::ExchangeType::DIRECT, true, false, map);ASSERT_EQ(emp->size(), 4);
}TEST(exchange_test, select_test)
{ASSERT_EQ(emp->exists("exchange1"), false);ASSERT_EQ(emp->exists("exchange2"), true);ASSERT_EQ(emp->exists("exchange3"), true);ASSERT_EQ(emp->exists("exchange4"), true);MQ::Exchange::ptr exp = emp->selectExchange("exchange1");ASSERT_NE(exp.get(), nullptr);ASSERT_EQ(exp->_name, "exchange1");ASSERT_EQ(exp->_durable, true);ASSERT_EQ(exp->_auto_delete, false);ASSERT_EQ(exp->_type, MQ::ExchangeType::DIRECT);ASSERT_EQ(exp->getArgs(), std::string("k1=v1&k2=v2&"));
}TEST(exchange_test, remove_test)
{emp->deleteExchange("exchange2");MQ::Exchange::ptr exp = emp->selectExchange("exchange2");ASSERT_EQ(exp.get(), nullptr);ASSERT_EQ(emp->exists("exchange2"), false);
}int main(int argc, char *argv[])
{testing::InitGoogleTest(&argc, argv);testing::AddGlobalTestEnvironment(new ExchangeTest);RUN_ALL_TESTS();return 0;
}
在MQTest中編寫Test_Binding.cpp文件來編譯綁定模塊單元測試
#include "../MQServer/Binding.hpp"
#include <gtest/gtest.h>MQ::BindingManager::ptr bmp;class QueueTest : public testing::Environment {public:virtual void SetUp() override {bmp = std::make_shared<MQ::BindingManager>("./data/meta.db");}virtual void TearDown() override {// bmp->clear();}
};// TEST(queue_test, insert_test) {
//     bmp->bind("exchange1", "queue1", "news.music.#", true);
//     bmp->bind("exchange1", "queue2", "news.sport.#", true);
//     bmp->bind("exchange1", "queue3", "news.gossip.#", true);
//     bmp->bind("exchange2", "queue1", "news.music.pop", true);
//     bmp->bind("exchange2", "queue2", "news.sport.football", true);
//     bmp->bind("exchange2", "queue3", "news.gossip.#", true);
//     ASSERT_EQ(bmp->size(), 6);
// }TEST(queue_test, recovery_test) {ASSERT_EQ(bmp->exist("exchange1", "queue1"), false);ASSERT_EQ(bmp->exist("exchange1", "queue2"), false);ASSERT_EQ(bmp->exist("exchange1", "queue3"), false);ASSERT_EQ(bmp->exist("exchange2", "queue1"), true);ASSERT_EQ(bmp->exist("exchange2", "queue2"), false);ASSERT_EQ(bmp->exist("exchange2", "queue3"), true);
}TEST(queue_test, select_test) {ASSERT_EQ(bmp->exist("exchange1", "queue1"), false);ASSERT_EQ(bmp->exist("exchange1", "queue2"), false);ASSERT_EQ(bmp->exist("exchange1", "queue3"), false);ASSERT_EQ(bmp->exist("exchange2", "queue1"), true);ASSERT_EQ(bmp->exist("exchange2", "queue2"), false);ASSERT_EQ(bmp->exist("exchange2", "queue3"), true);MQ::Binding::ptr bp = bmp->getBinding("exchange2", "queue1");ASSERT_NE(bp.get(), nullptr);ASSERT_EQ(bp->name_exchange, std::string("exchange2"));ASSERT_EQ(bp->name_queue, std::string("queue1"));ASSERT_EQ(bp->binding_key, std::string("news.music.pop"));
}TEST(queue_test, select_exchange_test) {MQ::QueueBindingMap mqbm = bmp->getExchangeBindings("exchange2");ASSERT_EQ(mqbm.size(), 2);ASSERT_NE(mqbm.find("queue1"), mqbm.end());ASSERT_EQ(mqbm.find("queue2"), mqbm.end());ASSERT_NE(mqbm.find("queue3"), mqbm.end());
}// // e2-q3// TEST(queue_test, remove_exchange_test) {
//     bmp->unbindByExchange("exchange1");
//     ASSERT_EQ(bmp->exist("exchange1", "queue1"), false);
//     ASSERT_EQ(bmp->exist("exchange1", "queue2"), false);
//     ASSERT_EQ(bmp->exist("exchange1", "queue3"), false);
// }// TEST(queue_test, remove_single_test) {
//     ASSERT_EQ(bmp->exist("exchange2", "queue2"), true);
//     bmp->unbind("exchange2", "queue2");
//     ASSERT_EQ(bmp->exist("exchange2", "queue2"), false);
//     ASSERT_EQ(bmp->exist("exchange2", "queue3"), true);
// }int main(int argc,char *argv[])
{testing::InitGoogleTest(&argc, argv);testing::AddGlobalTestEnvironment(new QueueTest);RUN_ALL_TESTS();return 0;
}
在MQTest中編寫Test_Channel.cpp文件來編譯信道模塊單元測試
#include "../MQServer/Channel.hpp"int main()
{MQ::ChannelManager::ptr cmp = std::make_shared<MQ::ChannelManager>();cmp->openChannel("c1", std::make_shared<MQ::VirtualHost>("host1", "./data/host1/message/", "./data/host1/host1.db"),std::make_shared<MQ::ConsumerManager>(),MQ::ProtobufCodecPtr(),muduo::net::TcpConnectionPtr(),MQ::ThreadPool::ptr());return 0;
}
在MQTest中編寫Test_Connection.cpp文件來編譯鏈接模塊單元測試
#include "../MQServer/Connection.hpp"int main()
{MQ::ConnectionManager::ptr cmp = std::make_shared<MQ::ConnectionManager>();cmp->newConnection(std::make_shared<MQ::VirtualHost>("host1", "./data/host1/message/", "./data/host1/host1.db"),std::make_shared<MQ::ConsumerManager>(),MQ::ProtobufCodecPtr(),muduo::net::TcpConnectionPtr(),MQ::ThreadPool::ptr());return 0;
}
在MQTest中編寫Test_Consumer.cpp文件來編譯消費者模塊單元測試
#include "../MQServer/Consumer.hpp"
#include <gtest/gtest.h>MQ::ConsumerManager::ptr cmp;class ConsumerTest : public testing::Environment {public:virtual void SetUp() override {cmp = std::make_shared<MQ::ConsumerManager>();cmp->initQueueConsumer("queue1");}virtual void TearDown() override {cmp->clear();}
};void cb(const std::string &tag, const MQ::BasicProperties *bp, const std::string &body) 
{std::cout << tag << " 消費了消息:" << body << std::endl;
}TEST(consumer_test, insert_test) {cmp->createConsumer("consumer1", "queue1", false, cb);cmp->createConsumer("consumer2", "queue1", false, cb);cmp->createConsumer("consumer3", "queue1", false, cb);ASSERT_EQ(cmp->isExist("consumer1", "queue1"), true);ASSERT_EQ(cmp->isExist("consumer2", "queue1"), true);ASSERT_EQ(cmp->isExist("consumer3", "queue1"), true);
}
TEST(consumer_test, remove_test) {cmp->removeConsumer("consumer1", "queue1");ASSERT_EQ(cmp->isExist("consumer1", "queue1"), false);ASSERT_EQ(cmp->isExist("consumer2", "queue1"), true);ASSERT_EQ(cmp->isExist("consumer3", "queue1"), true);
}TEST(consumer_test, choose_test) {MQ::Consumer::ptr cp = cmp->chooseConsumer("queue1");ASSERT_NE(cp.get(), nullptr);ASSERT_EQ(cp->_consumer_tag, "consumer2");cp = cmp->chooseConsumer("queue1");ASSERT_NE(cp.get(), nullptr);ASSERT_EQ(cp->_consumer_tag, "consumer3");cp = cmp->chooseConsumer("queue1");ASSERT_NE(cp.get(), nullptr);ASSERT_EQ(cp->_consumer_tag, "consumer2");
}int main(int argc,char *argv[])
{testing::InitGoogleTest(&argc, argv);testing::AddGlobalTestEnvironment(new ConsumerTest);RUN_ALL_TESTS();return 0;
}
在MQTest中編寫Test_FileHelper.cpp文件來文件操作類單元測試
#include "../MQCommon/Helper.hpp"int main()
{FileHelper helper("../MQCommon/Helper.hpp");DLOG("是否存在:%d", helper.exists());DLOG("文件大小:%ld", helper.size());FileHelper tmp_helper("./aaa/bbb/ccc/tmp.hpp");if (tmp_helper.exists() == false){std::string path = FileHelper::parentDirectory("./aaa/bbb/ccc/tmp.hpp");DLOG("path:%s",path.c_str());if (FileHelper(path).exists() == false){FileHelper::createDirectory(path);}FileHelper::createFile("./aaa/bbb/ccc/tmp.hpp");}std::string body;helper.read(body);DLOG("讀測試,讀出的內容:%s",body.c_str());tmp_helper.write(body);FileHelper tmp_helper1("./aaa/bbb/ccc/tmp.hpp");char str[16] = {0};tmp_helper.read(str, 8, 11);DLOG("[%s]", str);tmp_helper.write("12345678901", 8, 11);tmp_helper.rename("./aaa/bbb/ccc/test.hpp");FileHelper::removeFile("./aaa/bbb/ccc/test.hpp");FileHelper::removeDirectory("./aaa");return 0;
}
在MQTest中編寫Test_Message.cpp文件來編譯消息模塊單元測試
#include "../MQServer/Message.hpp"
#include <gtest/gtest.h>MQ::MessageManager::ptr mmp;class MessageTest : public testing::Environment {public:virtual void SetUp() override {mmp = std::make_shared<MQ::MessageManager>("./data/message/");mmp->initQueueMessage("queue1");}virtual void TearDown() override {// mmp->clear();}
};//新增消息測試:新增消息,然后觀察可獲取消息數量,以及持久化消息數量
// TEST(message_test, insert_test) 
// {
//   MQ::BasicProperties properties;
//     properties.set_id(UUIDHelper::uuid());
//     properties.set_delivery_mode(MQ::DeliveryMode::DURABLE);
//     properties.set_routing_key("news.music.pop");
//     mmp->insert("queue1", &properties, "Hello World-1", true);
//     mmp->insert("queue1", nullptr, "Hello World-2", true);
//     mmp->insert("queue1", nullptr, "Hello World-3", true);
//     mmp->insert("queue1", nullptr, "Hello World-4", true);
//     mmp->insert("queue1", nullptr, "Hello World-5", false);
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 5);
//     ASSERT_EQ(mmp->getTotalCount("queue1"), 4);
//     ASSERT_EQ(mmp->getDurableCount("queue1"), 4);
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 0);
// }//獲取消息測試:獲取一條消息,然后在不進行確認的情況下,查看可獲取消息數量,待確認消息數量,以及測試消息獲取的順序
// TEST(message_test, select_test) {
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 5);
//     MQ::MessagePtr msg1 = mmp->front("queue1");
//     ASSERT_NE(msg1.get(), nullptr);
//     ASSERT_EQ(msg1->payload().body(), std::string("Hello World-1"));
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 4);
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 1);//     MQ::MessagePtr msg2 = mmp->front("queue1");
//     ASSERT_NE(msg2.get(), nullptr);
//     ASSERT_EQ(msg2->payload().body(), std::string("Hello World-2"));
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 3);
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 2);//     MQ::MessagePtr msg3 = mmp->front("queue1");
//     ASSERT_NE(msg3.get(), nullptr);
//     ASSERT_EQ(msg3->payload().body(), std::string("Hello World-3"));
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 2);
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 3);//     MQ::MessagePtr msg4 = mmp->front("queue1");
//     ASSERT_NE(msg4.get(), nullptr);
//     ASSERT_EQ(msg4->payload().body(), std::string("Hello World-4"));
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 1);
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 4);//     MQ::MessagePtr msg5 = mmp->front("queue1");
//     ASSERT_NE(msg5.get(), nullptr);
//     ASSERT_EQ(msg5->payload().body(), std::string("Hello World-5"));
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 0);
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 5);
// }
//刪除消息測試:確認一條消息,查看持久化消息數量,待確認消息數量
// TEST(message_test, delete_test) {
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 5);
//     MQ::MessagePtr msg1 = mmp->front("queue1");
//     ASSERT_NE(msg1.get(), nullptr);
//     ASSERT_EQ(msg1->payload().body(), std::string("Hello World-1"));
//     ASSERT_EQ(mmp->getAbleCount("queue1"), 4);
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 1);//     mmp->ack("queue1", msg1->payload().properties().id());
//     ASSERT_EQ(mmp->getWaitAckCount("queue1"), 0);
//     ASSERT_EQ(mmp->getDurableCount("queue1"), 3);
//     ASSERT_EQ(mmp->getTotalCount("queue1"), 4);
// }
// 銷毀測試
// TEST(message_test, clear) {
//     mmp->destroyQueueMessage("queue1");
// }//恢復歷史數據測試MQ::MessageManager::ptr mmp1;
class MessageTest2 : public testing::Environment {public:virtual void SetUp() override {mmp1 = std::make_shared<MQ::MessageManager>("./data/message/");}virtual void TearDown() override {//mmp->clear();}
};
TEST(message_test2, recovery_test) {mmp1->initQueueMessage("queue1");ASSERT_EQ(mmp1->getAbleCount("queue1"), 4);MQ::MessagePtr msg1 = mmp1->front("queue1");ASSERT_NE(msg1.get(), nullptr);ASSERT_EQ(msg1->payload().body(), std::string("Hello World-1"));ASSERT_EQ(mmp1->getAbleCount("queue1"), 3);ASSERT_EQ(mmp1->getWaitAckCount("queue1"), 1);MQ::MessagePtr msg2 = mmp1->front("queue1");ASSERT_NE(msg2.get(), nullptr);ASSERT_EQ(msg2->payload().body(), std::string("Hello World-2"));ASSERT_EQ(mmp1->getAbleCount("queue1"), 2);ASSERT_EQ(mmp1->getWaitAckCount("queue1"), 2);MQ::MessagePtr msg3 = mmp1->front("queue1");ASSERT_NE(msg3.get(), nullptr);ASSERT_EQ(msg3->payload().body(), std::string("Hello World-3"));ASSERT_EQ(mmp1->getAbleCount("queue1"), 1);ASSERT_EQ(mmp1->getWaitAckCount("queue1"), 3);MQ::MessagePtr msg4 = mmp1->front("queue1");ASSERT_NE(msg4.get(), nullptr);ASSERT_EQ(msg4->payload().body(), std::string("Hello World-4"));ASSERT_EQ(mmp1->getAbleCount("queue1"), 0);ASSERT_EQ(mmp1->getWaitAckCount("queue1"), 4);
}int main(int argc,char *argv[])
{testing::InitGoogleTest(&argc, argv);//testing::AddGlobalTestEnvironment(new MessageTest);testing::AddGlobalTestEnvironment(new MessageTest2);RUN_ALL_TESTS();return 0;
}
在MQTest中編寫Test_Queue.cpp文件來編譯隊列模塊單元測試
#include "../MQServer/Queue.hpp"
#include <gtest/gtest.h>MQ::QueueManager::ptr mqmp;class QueueTest : public testing::Environment {public:virtual void SetUp() override {mqmp = std::make_shared<MQ::QueueManager>("./data/meta.db");DLOG("創建數據庫文件");}virtual void TearDown() override {// mqmp->clear();}
};// TEST(queue_test, insert_test) {
//     std::unordered_map<std::string, std::string> map = {{"k1", "v1"}};
//     mqmp->declareQueue("queue1", true, false, false, map);
//     mqmp->declareQueue("queue2", true, false, false, map);
//     mqmp->declareQueue("queue3", true, false, false, map);
//     mqmp->declareQueue("queue4", true, false, false, map);
//     ASSERT_EQ(mqmp->size(), 4);
// }TEST(queue_test, select_test) {ASSERT_EQ(mqmp->exist("queue1"), true);ASSERT_EQ(mqmp->exist("queue2"), true);ASSERT_EQ(mqmp->exist("queue3"), false);ASSERT_EQ(mqmp->exist("queue4"), true);MQ::Queue::ptr mqp = mqmp->selectQueue("queue1");ASSERT_NE(mqp.get(), nullptr);ASSERT_EQ(mqp->_name, "queue1");ASSERT_EQ(mqp->_durable, true);ASSERT_EQ(mqp->_exclusive, false);ASSERT_EQ(mqp->_auto_delete, false);ASSERT_EQ(mqp->getArgs(), std::string("k1=v1&"));
}TEST(queue_test, remove_test) {mqmp->deleteQueue("queue3");ASSERT_EQ(mqmp->exist("queue3"), false);
}int main(int argc,char *argv[])
{testing::InitGoogleTest(&argc, argv);testing::AddGlobalTestEnvironment(new QueueTest);RUN_ALL_TESTS();return 0;
}
在MQTest中編寫Test_Route.cpp文件來編譯路由模塊單元測試
#include "../MQServer/Route.hpp"
#include <gtest/gtest.h>class QueueTest : public testing::Environment {public:virtual void SetUp() override {}virtual void TearDown() override {//bmp->clear();}
};TEST(route_test, legal_routing_key) {std::string rkey1 = "news.music.pop";std::string rkey2 = "news..music.pop";std::string rkey3 = "news.,music.pop";std::string rkey4 = "news.music_123.pop";ASSERT_EQ(MQ::RouteManager::isValidRoutingKey(rkey1), true);ASSERT_EQ(MQ::RouteManager::isValidRoutingKey(rkey2), false);ASSERT_EQ(MQ::RouteManager::isValidRoutingKey(rkey3), false);ASSERT_EQ(MQ::RouteManager::isValidRoutingKey(rkey4), true);
}
TEST(route_test, legal_binding_key) {std::string bkey1 = "news.music.pop";std::string bkey2 = "news.#.music.pop";std::string bkey3 = "news.#.*.music.pop";//std::string bkey4 = "news.*.#.music.pop";//std::string bkey5 = "news.#.#.music.pop";//std::string bkey6 = "news.*.*.music.pop";std::string bkey7 = "news.,music_123.pop";//ASSERT_EQ(MQ::RouteManager::isValidBindingKey(bkey1), true);ASSERT_EQ(MQ::RouteManager::isValidBindingKey(bkey2), true);ASSERT_EQ(MQ::RouteManager::isValidBindingKey(bkey3), false);ASSERT_EQ(MQ::RouteManager::isValidBindingKey(bkey4), false);ASSERT_EQ(MQ::RouteManager::isValidBindingKey(bkey5), false);ASSERT_EQ(MQ::RouteManager::isValidBindingKey(bkey6), true);ASSERT_EQ(MQ::RouteManager::isValidBindingKey(bkey7), false);
}
TEST(route_test, route) {
// aaa                  aaa                     true
// aaa.bbb              aaa.bbb                 true
// aaa.bbb              aaa.bbb.ccc             false
// aaa.bbb              aaa.ccc                 false
// aaa.#.bbb            aaa.bbb.ccc             false
// aaa.bbb.#            aaa.ccc.bbb             false
// #.bbb.ccc            aaa.bbb.ccc.ddd         false
// aaa.bbb.ccc          aaa.bbb.ccc             true
// aaa.*                aaa.bbb                 true
// aaa.*.bbb            aaa.bbb.ccc             false
// *.aaa.bbb            aaa.bbb                 false
// #                    aaa.bbb.ccc             true
// aaa.#                aaa.bbb                 true
// aaa.#                aaa.bbb.ccc             true
// aaa.#.ccc            aaa.ccc                 true
// aaa.#.ccc            aaa.bbb.ccc             true
// aaa.#.ccc            aaa.aaa.bbb.ccc         true
// #.ccc                ccc                     true
// #.ccc                aaa.bbb.ccc             true
// aaa.#.ccc.ccc        aaa.bbb.ccc.ccc.ccc     true
// aaa.#.bbb.*.bbb      aaa.ddd.ccc.bbb.eee.bbb truestd::vector<std::string> bkeys = {"aaa","aaa.bbb","aaa.bbb", "aaa.bbb","aaa.#.bbb","aaa.bbb.#","#.bbb.ccc","aaa.bbb.ccc","aaa.*","aaa.*.bbb","*.aaa.bbb", "#",   "aaa.#", "aaa.#",  "aaa.#.ccc","aaa.#.ccc","aaa.#.ccc","#.ccc","#.ccc","aaa.#.ccc.ccc","aaa.#.bbb.*.bbb"};std::vector<std::string> rkeys = {"aaa","aaa.bbb",    "aaa.bbb.ccc",        "aaa.ccc",        "aaa.bbb.ccc",        "aaa.ccc.bbb",        "aaa.bbb.ccc.ddd",    "aaa.bbb.ccc",       "aaa.bbb",         "aaa.bbb.ccc",      "aaa.bbb",         "aaa.bbb.ccc",       "aaa.bbb",        "aaa.bbb.ccc",     "aaa.ccc",        "aaa.bbb.ccc",       "aaa.aaa.bbb.ccc",  "ccc",         "aaa.bbb.ccc",    "aaa.bbb.ccc.ccc.ccc","aaa.ddd.ccc.bbb.eee.bbb"};std::vector<bool> result = {true,true,false,false,false,false,false,true,true,false,false,true,true,true,true,true,true,true,true,true,true};for (int i = 0; i < bkeys.size(); i++) {ASSERT_EQ(MQ::RouteManager::route(MQ::ExchangeType::TOPIC, rkeys[i], bkeys[i]), result[i]);}
}int main(int argc,char *argv[])
{testing::InitGoogleTest(&argc, argv);testing::AddGlobalTestEnvironment(new QueueTest);RUN_ALL_TESTS();return 0;
}
在MQTest中編寫Test_VirtualHost.cpp文件來編譯虛擬機模塊單元測試
#include <gtest/gtest.h>
#include "../MQServer/VirtualHost.hpp"class HostTest : public testing::Test {public:void SetUp() override {std::unordered_map<std::string, std::string> empty_map = std::unordered_map<std::string, std::string>();_host = std::make_shared<MQ::VirtualHost>("host1", "./data/host1/message/", "./data/host1/host1.db");_host->declareExchange("exchange1", MQ::ExchangeType::DIRECT, true, false, empty_map);_host->declareExchange("exchange2", MQ::ExchangeType::DIRECT, true, false, empty_map);_host->declareExchange("exchange3", MQ::ExchangeType::DIRECT, true, false, empty_map);_host->declareQueue("queue1", true, false, false, empty_map);_host->declareQueue("queue2", true, false, false, empty_map);_host->declareQueue("queue3", true, false, false, empty_map);_host->bind("exchange1", "queue1", "news.music.#");_host->bind("exchange1", "queue2", "news.music.#");_host->bind("exchange1", "queue3", "news.music.#");_host->bind("exchange2", "queue1", "news.music.#");_host->bind("exchange2", "queue2", "news.music.#");_host->bind("exchange2", "queue3", "news.music.#");_host->bind("exchange3", "queue1", "news.music.#");_host->bind("exchange3", "queue2", "news.music.#");_host->bind("exchange3", "queue3", "news.music.#");_host->basicPublish("queue1", nullptr, "Hello World-1");_host->basicPublish("queue1", nullptr, "Hello World-2");_host->basicPublish("queue1", nullptr, "Hello World-3");_host->basicPublish("queue2", nullptr, "Hello World-1");_host->basicPublish("queue2", nullptr, "Hello World-2");_host->basicPublish("queue2", nullptr, "Hello World-3");_host->basicPublish("queue3", nullptr, "Hello World-1");_host->basicPublish("queue3", nullptr, "Hello World-2");_host->basicPublish("queue3", nullptr, "Hello World-3");}void TearDown() override {_host->clear();}public:MQ::VirtualHost::ptr _host;
};TEST_F(HostTest, init_test) {ASSERT_EQ(_host->existExchange("exchange1"), true);ASSERT_EQ(_host->existExchange("exchange2"), true);ASSERT_EQ(_host->existExchange("exchange3"), true);ASSERT_EQ(_host->existQueue("queue1"), true);ASSERT_EQ(_host->existQueue("queue2"), true);ASSERT_EQ(_host->existQueue("queue3"), true);ASSERT_EQ(_host->existBinding("exchange1", "queue1"), true);ASSERT_EQ(_host->existBinding("exchange1", "queue2"), true);ASSERT_EQ(_host->existBinding("exchange1", "queue3"), true);ASSERT_EQ(_host->existBinding("exchange2", "queue1"), true);ASSERT_EQ(_host->existBinding("exchange2", "queue2"), true);ASSERT_EQ(_host->existBinding("exchange2", "queue3"), true);ASSERT_EQ(_host->existBinding("exchange3", "queue1"), true);ASSERT_EQ(_host->existBinding("exchange3", "queue2"), true);ASSERT_EQ(_host->existBinding("exchange3", "queue3"), true);MQ::MessagePtr msg1 = _host->basicConsume("queue1");ASSERT_EQ(msg1->payload().body(), std::string("Hello World-1"));MQ::MessagePtr msg2 = _host->basicConsume("queue1");ASSERT_EQ(msg2->payload().body(), std::string("Hello World-2"));MQ::MessagePtr msg3 = _host->basicConsume("queue1");ASSERT_EQ(msg3->payload().body(), std::string("Hello World-3"));MQ::MessagePtr msg4 = _host->basicConsume("queue1");ASSERT_EQ(msg4.get(), nullptr);
}TEST_F(HostTest, remove_exchange) {_host->deleteExchange("exchange1");ASSERT_EQ(_host->existBinding("exchange1", "queue1"), false);ASSERT_EQ(_host->existBinding("exchange1", "queue2"), false);ASSERT_EQ(_host->existBinding("exchange1", "queue3"), false);
}TEST_F(HostTest, remove_queue) {_host->deleteQueue("queue1");ASSERT_EQ(_host->existBinding("exchange1", "queue1"), false);ASSERT_EQ(_host->existBinding("exchange2", "queue1"), false);ASSERT_EQ(_host->existBinding("exchange3", "queue1"), false);MQ::MessagePtr msg1 = _host->basicConsume("queue1");ASSERT_EQ(msg1.get(), nullptr);
}TEST_F(HostTest, ack_message) {MQ::MessagePtr msg1 = _host->basicConsume("queue1");ASSERT_EQ(msg1->payload().body(), std::string("Hello World-1"));_host->basicAck(std::string("queue1"), msg1->payload().properties().id());MQ::MessagePtr msg2 = _host->basicConsume("queue1");ASSERT_EQ(msg2->payload().body(), std::string("Hello World-2"));_host->basicAck(std::string("queue1"), msg2->payload().properties().id());MQ::MessagePtr msg3 = _host->basicConsume("queue1");ASSERT_EQ(msg3->payload().body(), std::string("Hello World-3"));_host->basicAck(std::string("queue1"), msg3->payload().properties().id());}int main(int argc, char *argv[])
{testing::InitGoogleTest(&argc, argv);RUN_ALL_TESTS();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80008.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80008.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80008.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spark 之 metrics

peak memory.//sql/core/src/main/scala/org/apache/spark/sql/execution/aggregate/HashAggregateExec.scala: “peakMemory” -> SQLMetrics.createSizeMetric(sparkContext, “peak memory”), .//sql/core/src/main/scala/org/apache/spark/sql/execution/SortExec.scal…

HTTP/HTTPS協議(請求響應模型、狀態碼)

目錄 HTTP/HTTPS協議簡介 HTTP協議 HTTPS協議 請求 - 響應模型 HTTP請求 &#xff08;二&#xff09;HTTP響應 HTTPS協議與HTTP協議在請求 - 響應模型中的區別 HTTP/HTTPS協議簡介 HTTP協議 定義 HTTP&#xff08;HyperText Transfer Protocol&#xff09;即超文本傳輸…

OpenHarmony 5.0 切換已連接過的wifi切換失敗

目錄 1.背景 2.流程分析 3.方案 1.背景 在OpenHarmony 5.0的設置中,輸入密碼進行wifi連接可以正常連接,然后多個已經連接過的wifi進行切換發現大概率切換失敗 2.流程分析 wifi連接過程其實是先進行斷開當前的wifi連接,然后再連接另一個wifi,如下: 雖然上述流程看起來沒…

【Ollama】docker離線部署Ollama+deepseek

因為要做項目&#xff0c;實驗室的服務器不聯網&#xff0c;所以只能先打包一個基礎的docker環境&#xff0c;然后再在實驗室的服務器上進行解壓和配置環境 參考&#xff1a;https://zhuanlan.zhihu.com/p/23377266873 1.打包基礎的docker環境 這里最好用有cuda的&#xff0c…

如何使用極狐GitLab 軟件包倉庫功能托管 terraform?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 Terraform 模塊庫 (BASIC ALL) 基礎設施倉庫和 Terraform 模塊倉庫合并到單個 Terraform 模塊倉庫功能引入于極狐GitLab 15.1…

【QT】深入理解 Qt 中的對象樹:機制、用途與最佳實踐

深入理解 Qt 中的對象樹&#xff1a;機制、用途與最佳實踐 在使用 Qt 編程時&#xff0c;你是否注意到很多對象可以設置“父對象”&#xff1f;比如&#xff1a; QPushButton* btn new QPushButton(parentWidget);這不是簡單的層級結構&#xff0c;而是 Qt 強大而優雅的 對象…

比較入站和出站防火墻規則

組織需要仔細配置防火墻規則&#xff0c;監控網絡的傳入和傳出流量&#xff0c;從而最大限度降低遭受攻擊的風險。在有效管理入站和出站防火墻規則前&#xff0c;了解入站與出站流量的區別至關重要。 一、什么是入站流量&#xff1f; 入站流量指的是并非源自網絡內部&#xf…

Unity-Shader詳解-其五

關于Unity的Shader部分的基礎知識其實已經講解得差不多了&#xff0c;今天我們來一些實例分享&#xff1a; 溶解 效果如下&#xff1a; 代碼如下&#xff1a; Shader "Chapter8/chapter8_1" {Properties{// 定義屬性[NoScaleOffset]_Albedo("Albedo", 2…

COLT_CMDB_linux_userInfo_20250508.sh修復歷史腳本輸出指標信息中userName與輸出信息不一致問題

#!/bin/bash #IT_BEGIN #IT_TYPE3 #IT SYSTEM_LINUX_AGENTUSERDISCOVER|discovery.user[disc] #原型指標 #IT_RULE SYSTEM_LINUX_AGENTUSERGROUPID|groupId[{#USERNAME}] #IT_RULE SYSTEM_LINUX_AGENTUSERHOME|userHome[{#USERNAME}] #IT_RULE SYSTEM_LINUX_AGENTUSERNAME|user…

TCP 與 UDP報文

** TCP 與 UDP報文** 1. 引言 在網絡通信中&#xff0c;TCP&#xff08;傳輸控制協議&#xff09; 和 UDP&#xff08;用戶數據報協議&#xff09; 是兩種最核心的傳輸層協議。它們各自適用于不同的場景&#xff0c;理解其工作原理對開發高性能網絡應用至關重要。本文將詳細解…

LabVIEW燃氣輪機測控系統

在能源需求不斷增長以及生態環境保護備受重視的背景下&#xff0c;微型燃氣輪機憑借其在經濟性、可靠性、維護性及排放性等方面的顯著優勢&#xff0c;在航空航天、分布式發電等眾多領域得到廣泛應用。隨著計算機技術的快速發展&#xff0c;虛擬儀器應運而生&#xff0c;LabVIE…

基于vueflow可拖拽元素的示例(基于官網示例的單文件示例)

效果圖 代碼 <template><div style"width: 100%;height: calc(100vh - 84px)"><VueFlow :nodes"nodes" :edges"edges" drop"onDrop" dragover"onDragOver" dragleave"onDragLeave"><div cl…

筆試專題(十六)

文章目錄 相差不超過k的最多數題解代碼 最長公共子序列&#xff08;一&#xff09;題解代碼 小紅的口罩題解代碼 春游題解代碼 相差不超過k的最多數 題目鏈接 題解 1. 排序 滑動窗口 2. 為什么使用滑動窗口&#xff1f; 因為max-min < k&#xff0c;求這個區間內的數最…

技術視界 | 青龍機器人訓練地形詳解(三):復雜地形精講之臺階

在前兩篇中&#xff0c;我們依次講解了“如何創建一個地形”以及“如何將地形添加到訓練環境中”。從基礎出發&#xff0c;逐步構建機器人可交互的三維仿真環境。在機器人強化學習訓練中&#xff0c;地形的復雜度決定了策略的泛化能力&#xff0c;僅靠 jump_plat 和 jump_pit 等…

MYSQL之索引結構,為何要用B+樹

索引的目的就是為了提高查詢效率 索引的結構是B樹&#xff0c;那么說到B樹&#xff0c;必須提一下其他三種結構&#xff0c;分別是&#xff1a;二叉查找樹、平衡二叉樹、B樹 我們來看看各自的結構特征 二叉查找樹 特點:任何節點的左子節點的值都小于當前節點的值&#xff0c;右…

3.2.3 掌握RDD轉換算子 - 2. 過濾算子 - filter()

在本節課中&#xff0c;我們深入學習了Spark RDD的過濾算子filter()。filter()算子能夠通過指定的函數對RDD中的元素進行篩選&#xff0c;返回一個滿足條件的新RDD&#xff0c;通常新RDD的元素個數會比源RDD少。通過案例演示&#xff0c;我們掌握了如何使用filter()來過濾列表中…

vue3使用輪播圖組件swiper

一、在swiper的官網源碼下載地址 下載Swiper - Swiper中文網 二、官網瀏覽輪播圖類型地址 Swiper演示 - Swiper中文網 三、swiper配置參數地址 中文api - Swiper中文網 四、在vue3項目引入swiper npm install swiper 五、在vue3中使用 官網vue3中使用&#xff1a;Swiper…

MySQL優化-MySQL故障排查與監控

MySQL優化-MySQL故障排查與監控 一、MySQL監控 實時了解數據庫的運行狀態&#xff0c;通過不同的監控指標&#xff0c;識別潛在問題并進行預防。常見得到MySQL監控指標包括&#xff1a;連接數、緩存池命中率、磁盤I/O、查詢執行情況等。 1、監控數據庫狀態變量 MySQL的狀態…

【MongoDB篇】MongoDB的分片操作!

目錄 引言第一節&#xff1a;分片核心概念&#xff1a;為什么要分片&#xff1f;它是什么&#xff1f; &#x1f914;&#x1f4a5;&#x1f680;第二節&#xff1a;分片架構的“三大金剛”&#xff1a;核心組件解析 &#x1f9f1;&#x1f9e0;&#x1f6e3;?第三節&#xff…

C++ 函數類型及實用例題

請各位大佬一鍵三連支持一下 目錄 請各位大佬一鍵三連支持一下 1. 無參數無返回值函數 2. 有參數無返回值函數 3. 無參數有返回值函數 4. 有參數有返回值函數 5. 函數重載 6. 遞歸函數 7. 帶默認參數的函數 8. 內聯函數 下面我將介紹 C 中不同類型的函數&#xff0c;…