如何在没有实际硬件的情况下测试RDMA代码?

问题描述 投票:0回答:1

我有一段C++代码,它利用Infiniband动词进行RDMA通信。我需要对这段代码进行单元测试,从而测试与RDMA相关的函数调用,如 ibv_get_device_list() 需要在没有任何实际硬件的情况下成功。根据我的理解,我可以做到以下几点。

  1. 为每个函数创建自己的定义来返回所需的值 然后链接到这个自定义的定义,而不是... ... infinband/verbs.h 在测试过程中。- 原来是非常繁琐的
  2. 创建一个接口,提供每个函数的真假实现。真正的会简单的调用infiniband动词。- 不能这样做,因为这需要对原代码进行太多修改。
  3. 使用Soft-RoCE - 我需要使用同一台机器作为客户端和服务器,但我一直无法做到。

能否使用gmock来模拟这些功能?我还可以考虑哪些其他的方案?

c++ unit-testing gmock infiniband rdma
1个回答
0
投票

第2条是要走的路。 我要对这个说法提出质疑。

不能这么做,因为这需要对原始代码做太多的修改。

如果一切顺利,你的IDE有一个 "全局搜索和替换 "可以使用。

让我们用最小的破坏性变化来细化抽象出你的代码的最简单方法。

首先定义一个类,简单地封装那些C库函数调用。

 class RDMA
 {
 public:
     virtual struct ibv_device **ibv_get_device_list(int *num_devices)
     {
          return ::ibv_get_device_list(num_devices);
     }

     virtual void ibv_free_device_list(struct ibv_device **list)
     {
           return ::ibv_free_device_list(list);
     }


     virtual uint64_t ibv_get_device_guid(struct ibv_device *device)
     {
          return ::ibv_get_device_guid(device);
     }
 };

在上面的类中扩展任何其他你可能需要的相关调用.

在全局范围内,声明一个上述类的实例和一个指向它的指针。

 RDMA g_product_code_rdma;
 RDMA* g_ptrRMDA = &g_product_code_rdma;

将所有的产品代码调用替换为 ibv 函数,通过全局指针调用到类中。 也就是说,把这个。

 ibv_free_device_list(&list);

被调用为。

 g_ptrRMDA->ibv_free_device_list(&list);

或者,你也可以声明辅助函数。

ibv_device **global_ibv_get_device_list(int *num_devices)
{
     return g_ptrRDMA->ibv_get_device_list(num_devices);
}

然后替换你所有的调用来使用新的 "全局 "版本。 一个简单的 sed/awk 脚本或者直接使用你的 IDE 来全局搜索并替换这些函数调用将是最简单的方法。

在这一点上,你的产品代码的功能和以前一样。

在你的单元测试中,你只需声明一个 MockRDMA 类,继承自 RDMA 类上面。

 class MockRDMA : public RDMA
 {
 public:

     ibv_device **ibv_get_device_list(int *num_devices) override
     {
          // return a fake list of devices
     }

     virtual void ibv_free_device_list(struct ibv_device **list) override
     {
          return;
     }


     virtual uint64_t ibv_get_device_guid(struct ibv_device *device) override
     {
          return 0x012345678;
     }
 };

然后你只需在单元测试开始时说这句话。

    MockRDMA mock;
    g_ptrRDMA = &mock;

Example:

bool test_that_thing()
{
    RDMA* original = g_ptrRDMA;
    MockRDMA mock;
    g_ptrRDMA = &mock;

    // test code to validate the code that depends on those RDMA calls

    // restore the RDMA class
    g_ptrRDMA = original;
    return result;

}

0
投票

如果你决定选择方案3(SoftRoCE),当然也可以让客户端和服务器在同一个主机上。你可以尝试一下 流浪汉箱 我创建的目的是为了在虚拟机中轻松测试SoftRoCE。

© www.soinside.com 2019 - 2024. All rights reserved.