I have C++ code which makes use of infiniband verbs for RDMA communication. I need to unit test this code, and thus, the function calls related to RDMA such as ibv_get_device_list() need to succeed without any actual hardware. From my understanding, I can do the following:
Create my own definition of each function to return the desired value, and link to this custom definition instead of infinband/verbs.h during testing. - Turning out to be very tedious
Create an interface and provide real and fake implementations of each function. The real one would simply call the infiniband verbs. - Can't do this as it would require too many changes to the original code
Use Soft-RoCE - I need to use the same machine as both the client and server, which I haven't been able to do
Would it be possible to use gmock to mock these functions? What other options can I consider?
Number 2 is the way to go. I'm going to challenge this statement:
Can't do this as it would require too many changes to the original code
If all goes well, your IDE has a "global search and replace" that can be used.
Let's fine the easiest way to abstract out your code with a minimal amount of disruptive changes:
Start by defining a class that simply wraps those C library function calls:
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);
}
};
Extend the above class with any other related calls you might need.
At global scope, declare an instance of the above class and a pointer to it:
RDMA g_product_code_rdma;
RDMA* g_ptrRMDA = &g_product_code_rdma;
Replace all your product code calls to the ibv functions to call through to the class via the global pointer. That is, change this:
ibv_free_device_list(&list);
to be invoked as:
g_ptrRMDA->ibv_free_device_list(&list);
Alternatively, you could declare helper functions:
ibv_device **global_ibv_get_device_list(int *num_devices)
{
return g_ptrRDMA->ibv_get_device_list(num_devices);
}
And then replace all your calls to use the new "global" version. A simple sed\awk script or just use your IDE to globally search and replace those function calls would be the easiest approach.
At this point, your product code functions the same as before.
in your unit tests, you simply declare a MockRDMA class that inherits from the RDMA class above.
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;
}
};
Then you just say this at the start of your unit tests:
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;
}
If you do decide to go for option 3 (SoftRoCE), it is certainly possible to have the client and server on the same host. You can try a Vagrant box I have created to make it easy to test SoftRoCE in a VM.
Related
I'm having trouble finding best practice information about what I believe should be a fairly common problem pattern.
I will start with a specific (software update related) example, because it makes the discussion more concrete, but the issue should be fairly generic.
Say that I have a software updater interface:
struct Software_updater {
virtual ~Software_updater() = default;
virtual void action1(const Input1& input1) = 0;
virtual void action2() = 0;
virtual bool action3(const Input2& input2) = 0;
virtual Data1 info1() = 0;
virtual Data2 info2() = 0;
// etc.
};
For my first implementation A, I am lucky, everything is straightforward.
class A_software_updater : public Software_updater {
// ...
};
A B_software_updater, however, is more complicated. Like in the A-case, it is connected to the target to update in a non-trivial manner and maintains a target connection state. But more importantly, it can update two images: the application image, and the boot loader image.
Liking what I have so far, I see no real reason to go for a refactoring, so I assume I can just build upon it. I come up with the following solution:
class B_software_updater {
public:
Software_updater& application_updater() { return application_updater_; }
Software_updater& boot_loader_updater() { return boot_loader_updater_; }
private:
class Application_updater : public Software_updater {
// ...
} application_updater_;
class Boot_loader_updater : public Software_updater {
// ...
} boot_loader_updater_;
};
I.e. I am returning non-const references to "interfaces to" member variables. Note that they cannot be const, since they mute state.
Request 1: I think the solution above is a clean one, but I would be happy to get some confirmation.
In fact, I have recently faced the issue of having to optionally provide an interface in a class, based on compile-time selection of a feature, and I believe the pattern above is a solution for that problem too:
struct Optional_interface {
virtual ~Optional_interface() = default;
virtual void action1(const Input1& input1) = 0;
virtual void action2() = 0;
virtual bool action3(const Input2& input2) = 0;
virtual Data1 info1() = 0;
virtual Data2 info2() = 0;
// etc.
};
class A_implementation {
public:
#ifdef OPTIONAL_FEATURE
Optional_interface& optional_interface() { return optional_implementation_; }
#endif
// ...
private:
#ifdef OPTIONAL_FEATURE
class Optional_implementation : public Optional_interface {
// ...
} optional_implementation_;
#endif
// ...
};
Request 2: I could not find a simple (as in: not unnecessarily complicated template-based) and clean way to express a compile-time optional inheritance at the A_implementation-level. Can you?
Better solution
Based on a comment from #ALX23z about invalidation of member variable reference upon move, I am now rejecting my initial solution (original post). That invalidation problem would not be an issue for my case, but I am in search of a generic pattern.
As usual, the solution is obvious once one has found it.
First a summary of my initial problem.
Say that I have a software updater interface (or any interface, this is just an example):
struct Software_updater {
virtual ~Software_updater() = default;
virtual void action1(const Input1& input1) = 0;
virtual void action2() = 0;
virtual bool action3(const Input2& input2) = 0;
virtual Data1 info1() = 0;
virtual Data2 info2() = 0;
// etc.
};
A B_software_updater can update two images: an application image, and a boot loader image. Therefore, it wants to provide two instances of the Software_updater interface.
A solution that is better than the one in my original post is to declare a B_application_updater and a B_boot_loader_updater, constructed from a B_software_updater&, outside of B_software_updater, and instantiated by client code.
class B_application_updater : public Software_updater {
B_application_updater(B_software_updater&);
// ...
};
class B_boot_loader_updater : public Software_updater {
B_application_updater(B_boot_loader_updater&);
// ...
};
It does have the drawback of forcing the client code to create three objects instead of only one, but I think that the cleanliness outweighs that drawback.
This will work for the optional interface too (see original post):
class A_optional_implementation : public Optional_interface {
A_optional_implementation(A_implementation&);
};
A_optional_implementation will be declared outside of A_implementation.
Applications that do not need that interface will simply not instantiate A_optional_implementation.
Additional thoughts
This is an application of the adapter design pattern!
Basically, what this answer comes down to:
An Interface class.
An Implementation class that does the job, but does not really care about the interface. It does not inherit Interface. The point of this is that Implementation could "do the job" corresponding to several interfaces, without the complexity and drawbacks of multiple inheritance (name conflicts, etc.). It could also do the job corresponding to several instances of the same interface (my case above).
An Interface_adapter class that takes an Implementation& parameter in its constructor. It inherits Interface, i.e. it effectively implements it, and that is its only purpose.
Taking a step back, I realize that this is simply an application of the adapter pattern (although Implementationin this case does not necessarily need to implement any externally defined interface - its interface is just its public member functions)!
An intermediate solution: leave the adapter classes inside the implementation class
In the solution above, I specify that the adapter classes are declared outside of the implementation classes. While this seems logical for the traditional adapter pattern case, for my case, I could just as well declare them inside the implementation class (like I did in the original post) and make them public. The client code would still have to create the implementation and adapter objects, but the adapter classes would belong to the implementation namespace, which would look nicer.
Let's say I have a class that represents a printing job: CPrintingJob. It knows nothing of the document being printed, just the job state - whether the job was queued, rejected, carried on etc.
The idea is an object of this class is instantiated whenever some printing needs to be done, then passed to the printing module along with other data, then the job's creator checks its state to see how printing is going.
Suppose CPrintingJob inherits two interfaces:
class IPrintingJob // this one is to check the job state
{
virtual TState GetState() const = 0;
// ... some other state-inquiring methods
class ICallback // job's owner is notified of state changes via this one
{
virtual void OnStateChange( const IPrintingJob& Job ) = 0;
};
};
and
class IPrintingJobControl // this one is for printing module to update the state
{
virtual void SetState( const TState& NewState ) = 0;
// ... some other state-changing methods
};
Problem is, the class that creates a CPrintingJob object shouldn't have access to the IPrintingJobControl, but the printing module CPrintingJob is being passed to must be able to change its state and, therefore, have access to that interface.
I suppose this is exactly the case where friends should be used but I have always avoided them as an inherently flawed mechanic and consequently have no idea of how to use them properly.
So, how do I do it properly?
Use a factory and have the factory return an instance of IPrintingJob (best wrapped inside a smart_ptr). e.g.:
struct PrintingFactory {
static auto create() -> std::unique_ptr<IPrintingJob> {
return std::unique_ptr<IPrintingJob>(new CPrintingJob());//as there is currently no std::make_unique..
}
}
Once you have to use the JobControl you can simply cast the pointer via std::dynamic_pointer_cast.
After some deliberation I've decided that:
This whole thing is definitely more trouble than it's worth;
(A slightly modified) version of MFH's answer above is the only, hence the best, way to go.
Thanks everyone for the input, it certainly has been enlightening.
Let's say I have the following class:
class Foo
{
public:
Foo()
{
Bar();
}
private:
Bar(bool aSendPacket = true)
{
if (aSendPacket)
{
// Send packet...
}
}
};
I am writing a test harness which needs to create a Foo object via the factory pattern (i.e. I am not instantiating it directly). I cannot change any of the factory instantiation code as this is in a framework which I don't have access to.
For various reasons I don't want the Bar method to send packets when running it from a test harness.
Assuming I cannot call Bar directly (eliminating potential solutions like using a friend class), what is an elegant design pattern to use to prevent packets being sent out when running my test harness? I definitely don't want to pollute my production code with special cases.
You want Bar to send a packet in ordinary operation, but not in testing. So you will have to have some code which runs when you call Bar during testing, even if it's an empty function. The question is where to put it.
We can't see the code inside the if(aSendPacket) loop, but if it delegates its work to some other class then we can make the substitution there. That is, if the loop is
if(aSendPacket)
{
mPacketHandler.send();
}
so that the work is done by the `packetHandler class:
// packetHandler.cc
void packetHandler::send()
{
// do some things
// send the packet
}
then we can make a "mute" version of the packetHandler class. (Some would call it a stub or a mock class, but there seems to be somedebate about the definitions of these terms.)
// version of packetHandler.cc to be used when testing e.g. Foo
void packetHandler::send()
{
// do some things
// don't actually send the packet
}
When testing Foo, compile this version of packetHandler and link it in. The factory won't know the difference.
If, on the other hand, the code for sending a packet is spelled out in Foo, with no way to head off the behavior outside the Foo class, then you will have to have a "testing" version of Foo.cc (there are other ways but they are clumsy and dangerous), and the best way to do that depends on the details of your codebase. If there are only a couple of "untestable" features like this, then it's probably best to put Foo::bar(...) in a source file by itself, with two versions (and do the same for each of the other special methods). If there are many then may be worth deriving a factory class specific to testing, which will construct instances of, e.g. class testingFoo : public Foo which overrides Bar. After all, this is what the abstract factory design pattern is for.
I would view 'bar' as an algorithm to send data which follows a template method
// Automation Strategies
class AutomationStrategy{
public:
void PreprocessSend(bool &configsend) const {return doPreprocessSend(configsend);}
void PostprocessSend() const {return doPostprocessSend();}
virtual ~AutomationStrategy(){}
private:
virtual void doPreprocessSend(bool &configsend) const = 0;
virtual void doPostprocessSend() const = 0;
};
// Default strategy is 'do nothing'
class Automation1 : public AutomationStrategy{
public:
~Automation1(){}
private:
void doPreprocessSend(bool &configsend) const {}
void doPostprocessSend() const {}
};
// This strategy is 'not to send packets' (OP's intent)
class Automation2 : public AutomationStrategy{
public:
~Automation2(){}
private:
void doPreprocessSend(bool &configsend) const {
configsend = false;
}
void doPostprocessSend() const {}
};
class Foo{
public:
Foo(){
Bar();
}
private:
// Uses Template Method
void Bar(bool aSendPacket = true, AutomationStrategy const &ref = Automation1())
{
ref.PreprocessSend(aSendPacket); // Customizable Step1 of the algorithm
if (aSendPacket) // Customizable Step2 of the algorithm
{
// Send packet...
}
ref.PostprocessSend(); // Customizable Step3 of the algorithm
}
};
int main(){}
If you can't modify 'bar' interface, then configure 'Foo' to accept the test automation strategy in it's constructor and store it (to be later used while calling 'bar')
It might be a gross oversimplification, but my first inclination is to add some sort of testing conditions object (really a variable library) which defaults everything to false, then put hooks in the code where you want to deviate from standard behavior for testing, switching on the [effectively global] testing conditions object variables. You're going to need to do the equivalent logic anyway, and everything else seems either needlessly more complicated, more disruptive to understanding the logic flow inside the object, or more potentially disruptive to the behavior in the testing case. If you can get away with a minimal amount of conditional switch locations/variables, that probably the easiest solution.
My opinion, anyway.
I'm looking at a simple class I have to manage critical sections and locks, and I'd like to cover this with test cases. Does this make sense, and how would one go about doing it? It's difficult because the only way to verify the class works is to setup very complicated threading scenarios, and even then there's not a good way to test for a leak of a Critical Section in Win32. Is there a more direct way to make sure it's working correctly?
Here's the code:
CriticalSection.hpp:
#pragma once
#include <windows.h>
#include <boost/shared_ptr.hpp>
namespace WindowsAPI { namespace Threading {
class CriticalSectionImpl;
class CriticalLock;
class CriticalAttemptedLock;
class CriticalSection
{
friend class CriticalLock;
friend class CriticalAttemptedLock;
boost::shared_ptr<CriticalSectionImpl> impl;
void Enter();
bool TryEnter();
void Leave();
public:
CriticalSection();
};
class CriticalLock
{
CriticalSection &ref;
public:
CriticalLock(CriticalSection& sectionToLock) : ref(sectionToLock) { ref.Enter(); };
~CriticalLock() { ref.Leave(); };
};
class CriticalAttemptedLock
{
CriticalSection &ref;
bool valid;
public:
CriticalAttemptedLock(CriticalSection& sectionToLock) : ref(sectionToLock), valid(ref.TryEnter()) {};
bool LockHeld() { return valid; };
~CriticalAttemptedLock() { if (valid) ref.Leave(); };
};
}}
CriticalSection.cpp:
#include "CriticalSection.hpp"
namespace WindowsAPI { namespace Threading {
class CriticalSectionImpl
{
friend class CriticalSection;
CRITICAL_SECTION sectionStructure;
CriticalSectionImpl() { InitializeCriticalSection(§ionStructure); };
void Enter() { EnterCriticalSection(§ionStructure); };
bool TryEnter() { if (TryEnterCriticalSection(§ionStructure)) return true; else return false; };
void Leave() { LeaveCriticalSection(§ionStructure); };
public:
~CriticalSectionImpl() { DeleteCriticalSection(§ionStructure); };
};
void CriticalSection::Enter() { impl->Enter(); };
bool CriticalSection::TryEnter() { return impl->TryEnter(); };
void CriticalSection::Leave() { impl->Leave(); };
CriticalSection::CriticalSection() : impl(new CriticalSectionImpl) {} ;
}}
Here are three options and personally I favour the last one...
You could create a 'critical section factory' interface that can be passed to your constructor. This would have functions that wrapped the API level functions that you need to use. You could then mock this interface up and pass the mock to the code when under test and you can be sure that the right API functions are called. You would, generally, also have a constructor that didn't take this interface and that instead initialised itself with a static instance of the factory that called directly to the API. Normal creation of the objects wouldn't be affected (as you have them use a default implementation) but you can instrument when under test. This is the standard dependency injection route and results in you being able to parameterise from above. The downside of all this is that you have a layer of indirection and you need to store a pointer to the factory in each instance (so you're probably losing out in both space and time).
Alternatively you could try and mock the API out from underneath... A long time ago I looked into testing this kind of low level API usage with API hooking; the idea being that if I hooked the actual Win32 API calls I could develop a 'mock API layer' which would be used in the same way as more normal Mock Objects but would rely on "parameterise from below" rather than parameterise from above. Whilst this worked and I got quite a long way into the project, it was very complex to ensure that you were only mocking the code under test. The good thing about this approach was that I could cause the API calls to fail under controlled conditions in my test; this allowed me to test failure paths which were otherwise VERY difficult to exercise.
The third approach is to accept that some code is not testable with reasonable resources and that dependency injection isn't always suitable. Make the code as simple as you can, eyeball it, write tests for the bits that you can and move on. This is what I tend to do in situations like this.
However....
I'm dubious of your design choice. Firstly there's too much going on in the class (IMHO). The reference counting and the locking are orthogonal. I'd split them apart so that I had a simple class that did critical section management and then built on it I found I really needed reference counting... Secondly there's the reference counting and the design of your lock functions; rather than returning an object that releases the lock in its dtor why not simply have an object that you create on the stack to create a scoped lock. This would remove much of the complexity. In fact you could end up with a critical section class that's as simple as this:
CCriticalSection::CCriticalSection()
{
::InitializeCriticalSection(&m_crit);
}
CCriticalSection::~CCriticalSection()
{
::DeleteCriticalSection(&m_crit);
}
#if(_WIN32_WINNT >= 0x0400)
bool CCriticalSection::TryEnter()
{
return ToBool(::TryEnterCriticalSection(&m_crit));
}
#endif
void CCriticalSection::Enter()
{
::EnterCriticalSection(&m_crit);
}
void CCriticalSection::Leave()
{
::LeaveCriticalSection(&m_crit);
}
Which fits with my idea of this kind of code being simple enough to eyeball rather than introducing complex testing ...
You could then have a scoped locking class such as:
CCriticalSection::Owner::Owner(
ICriticalSection &crit)
: m_crit(crit)
{
m_crit.Enter();
}
CCriticalSection::Owner::~Owner()
{
m_crit.Leave();
}
You'd use it like this
void MyClass::DoThing()
{
ICriticalSection::Owner lock(m_criticalSection);
// We're locked whilst 'lock' is in scope...
}
Of course my code isn't using TryEnter() or doing anything complex but there's nothing to stop your simple RAII classes from doing more; though, IMHO, I think TryEnter() is actually required VERY rarely.
In my C++ project, I've chosen to use a C library. In my zeal to have a well-abstracted and simple design, I've ended up doing a bit of a kludge. Part of my design requirement is that I can easily support multiple APIs and libraries for a given task (due, primarily, to my requirement for cross-platform support). So, I chose to create an abstract base class which would uniformly handle a given selection of libraries.
Consider this simplification of my design:
class BaseClass
{
public:
BaseClass() {}
~BaseClass() {}
bool init() { return doInit(); }
bool run() { return doWork(); }
void shutdown() { destroy(); }
private:
virtual bool doInit() = 0;
virtual bool doWork() = 0;
virtual void destroy() = 0;
};
And a class that inherits from it:
class LibrarySupportClass : public BaseClass
{
public:
LibrarySupportClass()
: BaseClass(), state_manager(new SomeOtherClass()) {}
int callbackA(int a, int b);
private:
virtual bool doInit();
virtual bool doWork();
virtual void destroy();
SomeOtherClass* state_manager;
};
// LSC.cpp:
bool LibrarySupportClass::doInit()
{
if (!libraryInit()) return false;
// the issue is that I can't do this:
libraryCallbackA(&LibrarySupportClass::callbackA);
return true;
}
// ... and so on
The problem I've run into is that because this is a C library, I'm required to provide a C-compatible callback of the form int (*)(int, int), but the library doesn't support an extra userdata pointer for these callbacks. I would prefer doing all of these callbacks within the class because the class carries a state object.
What I ended up doing is...
static LibrarySupportClass* _inst_ptr = NULL;
static int callbackADispatch(int a, int b)
{
_inst_ptr->callbackA(a, b);
}
bool LibrarySupportClass::doInit()
{
_inst_ptr = this;
if (!libraryInit()) return false;
// the issue is that I can't do this:
libraryCallbackA(&callbackADispatch);
return true;
}
This will clearly do Bad Things(TM) if LibrarySupportClass is instantiated more than once, so I considered using the singleton design, but for this one reason, I can't justify that choice.
Is there a better way?
You can justify that choice: your justification is that the C library only supports one callback instance.
Singletons scare me: It's not clear how to correctly destroy a singleton, and inheritance just complicates matters. I'll take another look at this approach.
Here's how I'd do it.
LibrarySupportClass.h
class LibrarySupportClass : public BaseClass
{
public:
LibrarySupportClass();
~LibrarySupportClass();
static int static_callbackA(int a, int b);
int callbackA(int a, int b);
private:
//copy and assignment are rivate and not implemented
LibrarySupportClass(const LibrarySupportClass&);
LibrarySupportClass& operator=(const LibrarySupportClass&);
private:
static LibrarySupportClass* singleton_instance;
};
LibrarySupportClass.cpp
LibrarySupportClass* LibrarySupportClass::singleton_instance = 0;
int LibrarySupportClass::static_callbackA(int a, int b)
{
if (!singleton_instance)
{
WHAT? unexpected callback while no instance exists
}
else
{
return singleton_instance->callback(a, b);
}
}
LibrarySupportClass::LibrarySupportClass()
{
if (singleton_instance)
{
WHAT? unexpected creation of a second concurrent instance
throw some kind of exception here
}
singleton_instance = this;
}
LibrarySupportClass::~LibrarySupportClass()
{
singleton_instance = 0;
}
My point is that you don't need to give it the external interface of a canonical 'singleton' (which e.g. makes it difficult to destroy).
Instead, the fact that there is only one of it can be a private implementation detail, and enforced by a private implementation detail (e.g. by the throw statement in the constructor) ... assuming that the application code is already such that it will not try to create more than one instance of this class.
Having an API like this (instead of the more canonical 'singleton' API) means that you can for example create an instance of this class on the stack if you want to (provided you don't try to create more than one of it).
The external constraint of the c library dictates that when your callback is called you don't have the identification of the "owning" instance of the callback. Therefore I think that your approach is correct.
I would suggest to declare the callbackDispatch method a static member of the class, and make the class itself a singleton (there are lots of examples of how to implement a singleton). This will let you implement similar classes for other libraries.
Dani beat me to the answer, but one other idea is that you could have a messaging system where the call back function dispatch the results to all or some of the instances of your class. If there isn't a clean way to figure out which instance is supposed to get the results, then just let the ones that don't need it ignore the results.
Of course this has the problem of performance if you have a lot of instances, and you have to iterate through the entire list.
The problem the way I see it is that because your method is not static, you can very easily end up having an internal state in a function that isn't supposed to have one, which, because there's a single instance on the top of the file, can be carried over between invocations, which is a -really- bad thing (tm). At the very least, as Dani suggested above, whatever methods you're calling from inside your C callback would have to be static so that you guarantee no residual state is left from an invocation of your callback.
The above assumes you have static LibrarySupportClass* _inst_ptr declared at the very top. As an alternative, consider having a factory function which will create working copies of your LibrarySupportClass on demand from a pool. These copies can then return to the pool after you're done with them and be recycled, so that you don't go around creating an instance every time you need that functionality.
This way you can have your objects keep state during a single callback invocation, since there's going to be a clear point where your instance is released and gets a green light to be reused. You will also be in a much better position for a multi-threaded environment, in which case each thread gets its own LibrarySupportClass instance.
The problem I've run into is that because this is a C library, I'm required to provide a C-compatible callback of the form int (*)(int, int), but the library doesn't support an extra userdata pointer for these callbacks
Can you elaborate? Is choosing a callback type based on userdata a problem?
Could your callback choose an instance based on a and/or b? If so, then register your library support classes in a global/static map and then have callbackADispatch() look up the correct instance in the map.
Serializing access to the map with a mutex would be a reasonable way to make this thread-safe, but beware: if the library holds any locks when it invokes your callback, then you may have to do something more clever to avoid deadlocks, depending on your lock hierarchy.