'Can we unit test memory allocation?

I have to test a library that provides its own memory allocation routine:

void* allocation_routine(size_t size) throw();

Documentation states that this function allocates at least size bytes of memory (it's allowed to allocate more). By the way the function uses posix_memalign internally, but the implementation may change.

I'm wondering if it's possible to write a unit test for that kind of functions? How can we test whether the required amount of memory was allocated?

UPDATE:

If we can't write a unit test then what is the closest solution?



Solution 1:[1]

You cannot write a unit test for this function, because you cannot allocate memory on the heap without a system call. Hence, this is an integration test, as you are unable of isolating the unit under test from the operating system.

I would create a new, small executable that calls allocation_routine for n bytes. Depending on what allocation_routine is supposed to return, you can assert that it's non-nullptr. Then, write n bytes into this region of memory. Compile and link it using the address sanitizer (available with both gcc and clang), then try to integrate it into the test runner of your application (ctest etc.).

You might also want to restrict the available heap via the POSIX setrlimit to verify the behvaior when the allocation fails.

Solution 2:[2]

It's not unit test, but you can use Valgrind to get different information about memory.

  • memory leaks (which are not free)
  • memory issues

It's mainly used for debugging, but it will warns you if something is not allocated well.

Solution 3:[3]

Note that while you can't unit test a malloc replacement directly you can if there is any level of indirection. Otherwise as @lubgr has stated this is an integration test.

Indirection can help on both sides. If you have a malloc wrapper that counts memory for example:

extern "C" void* malloc(const size_t size) __THROW
{
   return getAllocator().malloc(size);
}

struct Allocator
{
   using MallocFunc = std::function<void*(size_t)>;

   unsigned long numAllocs = 0;
   size_t totalMemAllocated = 0;
   MallocFunc = __libc_malloc;

   void* malloc(const size_t size)
   {
      ++numAllocs;
      totalMemAllocated += size;
      return __libc_malloc(size);
   }
}

You could instead set MallocFunc to point to your own mock version of malloc() instead of __libc_malloc to test the accounting mechanism works properly.

Likewise you can test the allocation routine itself if you provide interposed or mock versions of the system calls it uses in the unit test code. If using gcc you might consider using symbol wrapping or the LD_PRELOAD mechanism for this.

Remember that integration tests are important as well. The assumptions you make during unit testing may not hold.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Peter Mortensen
Solution 3 Bruce Adams