手撕基于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.cc
	g++ -g -o $@ $^ -std=c++11 -lgtest -lprotobuf -lsqlite3 -pthread

Test_Binding:Test_Binding.cpp
	g++ -g -o $@ $^ -std=c++11 -lgtest -lprotobuf -lsqlite3 -pthread

Test_Queue:Test_Queue.cpp
	g++ -g -o $@ $^ -std=c++11 -lgtest -lprotobuf -lsqlite3 -pthread

Test_FileHelper:Test_FileHelper.cpp
	g++ -o $@ $^ -std=c++11

Test_Exchange:Test_Exchange.cpp
	g++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3

Test_Message:Test_Message.cpp ../MQCommon/message.pb.cc
	g++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3

Test_Route:Test_Route.cpp ../MQCommon/message.pb.cc
	g++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3

Test_Consumer:Test_Consumer.cpp ../MQCommon/message.pb.cc
	g++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3

Test_Channel:Test_Channel.cpp ../MQCommon/message.pb.cc ../MQCommon/request.pb.cc
	g++ -g -std=c++11 $^ -o $@ -lgtest -lprotobuf -lsqlite3 -I../ThirdLib/lib/include

Test_Connection:Test_Connection.cpp ../MQCommon/message.pb.cc ../MQCommon/request.pb.cc
	g++ -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 true
    std::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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值