Путь номер 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;
Пример:
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;
}
person
selbie
schedule
05.05.2020