'Cmocka: checking a structure passed as a parameter

Let's say that I declare a C struct called foo, which has an int field called bar and a char * called baz.

How do I use the Cmocka expect_ and check_expected macros to check that the structure passed was correct and both fields have the expected values? If there is an example in the documentation, I missed it.


[Update] Perhaps I can use expect_check()? But I can't find an example :-(



Solution 1:[1]

Use expect_memory(...) and check_expected(...):

Example:

I assume you have a function under test fut which calls a subfunction subfunc. Your struct looks like this:

typedef struct foo_s {
  int bar;
  int baz;
} foo;

And your test driving function could look like this:

void test(void **state) {
   foo myfoo = {
     .bar = 42,
     .baz = 13,
   };
   expect_memory(subfunc, param, &myfoo, sizeof(foo));

   fut();
}

And the subfunctions could look like this:

void subfunc(foo *param){
   check_expected(param);
}

Solution 2:[2]

Comparing the memory of the struct might work in most cases, however if your compiler puts some filler bytes in there, you have some bytes which you have no controll over and might have random values. This means that your test might not alway yield the same result, which can lead to very annoying debugging session.

For example if you have a struct like this:

typedef struct {
    uint8_t c;
    uint32_t i;
} tSomeStruct

You might think that the c and i are put right next to each other and sizeof( tSomeStruct ) returns 5. However if you try this out you would be surprised that it is more likely that sizeof( tSomeStruct ) actually returns 8. This is because of the mentioned filler bytes. You do not know what the values of these other bytes are. You can work around this by memsetting your structs to 0 before using them, however this is a little bit hacky and does not work in every case.

To compare structs in a clean way cmocka you can use expect_check( ... ) and check_expected( ... ). This gives you the possibility to write your own comparisson function.

Here is an example on how to use this ( Modified this example: Cmocka Gitlab )

typedef struct {
    char c;
    int i;
} tSomeStruct;

void mock_function( tSomeStruct* param )
{
    check_expected(param)
}

/* return 1 = true, return 0 = false */
int my_int_equal_check(const LargestIntegralType value,
                    const LargestIntegralType check_value_data)
{
    tSomeStruct* cast_value = ( tSomeStruct* ) value;
    tSomeStruct* cast_check_value_data = ( tSomeStruct* ) check_value_data;    

    if ( ( cast_value->c == cast_check_value_data->c )
    && ( cast_value->i == cast_check_value_data->i ) ) {
        return 1;
    }

    return 0;
}

void mytest(void **state)
{
    tSomeStruct struct = {
        .c = 'c',
        .i = 'i',
    }

    expect_check(mock_function, param, my_int_equal_check, &struct);
}

I am not sure however if this is possible, if you do not pass your struct as a pointer to your function, as the check function only takes LargestIntegralType.

Solution 3:[3]

I recently found out that you can use the struct members inside the check_expected and expect_value:

typedef struct 
{
  int   a;
  float b;
} SomeStruct_t;

void mocked_function(SomeStruct_t* s)
{
  check_expected(s->a);
  check_expected(s->b);
}

void someTest(void **state)
{
  expect_value(mocked_function, s->a, 3);
  expect_value(mocked_function, s->b, 7.2);
  // ...
}

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 KevJ
Solution 2 Usenka
Solution 3 mr_georg