Mocking the ‘asm’ directive with CppUMock

My last article featured a hand crafted a spy to monitor asm directives. Now let’s use CppUMock (the mock support companion CppUTest) to create a mock version of asm.

Starting with the test (where else would you start), MockAsm works like this:

#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"
 
extern "C"
{
#include "MockAsm.h"
}
 
TEST_GROUP(MockAsm)
{
    void setup()
    {
    }
 
    void teardown()
    {
       mock().checkExpectations();
       mock().clear();
    }
};
 
TEST(MockAsm, CaptureAsmInstructions)
{
    mock().expectOneCall("asm")
          .withParameter("instruction", "NOP");
    mock().expectOneCall("asm")
          .withParameter("instruction", "FLOP");
    mock().expectOneCall("asm")
          .withParameter("instruction", "POP");
 
	MockAsm("NOP");
	MockAsm("FLOP");
	MockAsm("POP");
}

To get a successful build and link, you need to build CppUTest extensions. You can do this with make extensions. You will also have to tell CppUTest’s makefile system to use extensions by adding this to your makefile.

CPPUTEST_USE_EXTENSIONS = Y

Like the last example, use the preprocessor to sneak the mock into the production code by forcing each compilation unit to include MockAsm.h.

CPPUTEST_CFLAGS += -include mocks/MockAsm.h

MockAsm.h looks like this:

#ifndef D_MockAsm_H
#define D_MockAsm_H
 
#define asm MockAsm
 
void MockAsm(const char * instruction);
 
#endif

Here’s MockAsm.c.

#include "MockAsm.h"
#include "CppUTestExt/MockSupport_c.h"
 
void MockAsm(const char * instruction)
{
  mock_c()->actualCall("asm")
          ->withStringParameters("instruction", instruction);
}

That was easy.

2 thoughts on “Mocking the ‘asm’ directive with CppUMock

  1. This is a very interesting use of mocks. However, what is the point of a test like this? While it is easy to see why I might want the asm() directives to go away altogether, or maybe replace it with some normal C code that works on the development system, but why would I want to test – at runtime – for the presence of a particular line of assembly code? What would I prove by such a test?

  2. This would mainly be for off-target testing. This might be of limited value. But what it tells you is that no one changed the asm() instructions. You are locking in and checking that the right sequence is there.

    It could also be helpful in a legacy code situation where this is your monitor point to see if the asm instructions were on the execution path.

    Good question, James

Leave a Reply

Your email address will not be published.

Be gone spammers * Time limit is exhausted. Please reload the CAPTCHA.