Function called earlier than expected with no obvious reason

610 views
Skip to first unread message

Agnes Bousquier

unread,
Apr 13, 2022, 10:57:27 AM4/13/22
to ThrowTheSwitch Forums
Hello,

Sometimes, I am facing an error while calling many mocks one after the other: ceedling complains that one of them is called earlier than expected, whereas my test and my code call the mocks in the same order.
For example, in the following test:

    productConfiguration.dateTime.year.data = 2022;
    productConfiguration.dateTime.month.data = 02;
    productConfiguration.dateTime.day.data = 05;
    productConfiguration.dateTime.hours.data = 15;
    productConfiguration.dateTime.minutes.data = 45;
    SCRN_isDisplayAvailable_ExpectAndReturn(1);
    uint8_t date050222[DATE_STRING_SIZE] = "05/02/2022";
    SCRN_WriteMsgOnLine_ExpectWithArray(0, date050222, DATE_STRING_SIZE);
    uint8_t time15h45[TIME_STRING_SIZE] = "15:45";
    SCRN_WriteMsgOnLine_ExpectWithArray(1, time15h45, TIME_STRING_SIZE);
    SCRN_setIndexOfActiveLine_Expect(0); // on se positionne sur la 1ere ligne a editer
    SCRN_SetPositionOfCharacterToBlink_Expect(E_DIZAINES_JOUR); // on se positionne sur le 1er caractere a editer
    SCRN_display_Expect(SCRN_CHOOSE_DATE_TIME);
    MSM_Management();
    TEST_ASSERT_EQUAL(E_MSM_DATE_TIME_SELECTION, MSM_getState());


I am getting the error "Function SCRN_setIndexOfActiveLine.  Called earlier than expected."

The code under test is :
void MSm_Mgt(void)
{
if(1 == SCRN_isDisplayAvailable())
        {
            switchToState(mainStateInfos[E_MSM_WAIT_FOR_END_OF_CONFIRMATION_DISPLAY].nextState);
        }
}

static void switchToState(e_MSM_State state)
{
    timerAttenteLectureEnMs = 0;
    if(NULL != mainStateInfos[state].stateEntryFunc)
        mainStateInfos[state].stateEntryFunc();
    MSM_currentState = state;
    if(SCRN_NO_SCREEN != mainStateInfos[state].screenToDisplay)
        SCRN_display(mainStateInfos[state].screenToDisplay);
}

In this case, stateEntryFunc is
static void sendCurrentDateAndTimeToScrn(void)
{
    sprintf((char*) MSM_msgLine0, "%.2d/%.2d/%.4d",
            productConfiguration.dateTime.day.data,
            productConfiguration.dateTime.month.data,
            productConfiguration.dateTime.year.data);

    SCRN_WriteMsgOnLine(0, (uint8_t*) MSM_msgLine0);

    sprintf((char*) MSM_msgLine1, "%.2d:%.2d",
            productConfiguration.dateTime.hours.data,
            productConfiguration.dateTime.minutes.data);

    SCRN_WriteMsgOnLine(1, (uint8_t*) MSM_msgLine1);

    MSM_positionOfCharacterToEdit = 0;
    MSM_selectedLine = 0;
    SCRN_setIndexOfActiveLine(MSM_selectedLine);
    SCRN_SetPositionOfCharacterToBlink(MSM_positionOfCharacterToEdit);
}

... So I do not understand why ceedling is complaining.

Can you help me please?


David Good

unread,
Apr 13, 2022, 11:51:57 AM4/13/22
to throwth...@googlegroups.com
In my experience, this is the hardest error to debug with Ceedling, because there is not a default 'trace' of function calls that led up to the error.

In general, the problem is usually that the code you believe is executing actually is not, and you task is to prove what is being executed. I have used the following:

1. printf statements in the production module that leave breadcrumbs (e.g. printf("a"), printf("b"), etc...).

2. Simplify your test by commenting out all but the top most part of the test and see if it passes. Then uncomment more and more of the test until you see where it breaks. You might also have to comment out portions of your module in order to support this kind of investigation.

3. Give up and switch careers. (Just kidding!! Don't do that!!)

Also, it is not clear to me how you are setting the initial conditions of your state machine which might be important. When I test state machines, I usually have some kind of SM_Reset() function in my setUp() function so that I am sure each test in my test file starts from the same clean state.

Hopefully that helps until someone else can give a better answer :) I'm interested in knowing myself if there is a better way.

--David

--
You received this message because you are subscribed to the Google Groups "ThrowTheSwitch Forums" group.
To unsubscribe from this group and stop receiving emails from it, send an email to throwtheswitc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/throwtheswitch/208d5a7a-2c74-41a3-a4e0-f1532937f820n%40googlegroups.com.

David Good

unread,
Apr 13, 2022, 11:55:47 AM4/13/22
to throwth...@googlegroups.com
I forgot to mention that if you call functions in your SM_Reset(), you might have to setup expectations/ignores in the setUp function as well. If you do Ignore functions, then you will have to call StopIgnore on those same functions at the end of the setUp or in your individual tests. That can trip you up too!

--David

Agnes Bousquier

unread,
Apr 14, 2022, 7:41:34 AM4/14/22
to ThrowTheSwitch Forums
Hi David,

Thank you for your reply. By using breadcrumbs I managed to see where my error was and fixed it;
So I do not need to switch carrer ;-)

Regards,

Agnes
Reply all
Reply to author
Forward
0 new messages