-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add test for Timer class. #4971
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few comments:
- I wonder if the intermediary variables
read_val
,read_ms_val
,read_us_val
andread_hr_us_val
are necessary. In my opinion, calling the timer functions in the assertion is clear enough. - The comment about the timer existence present in every test is unnecessary.
- Would it be possible to test accumulation with the stub while moving the counter value between stop/start call.
- Would it be possible to split unit test from integration tests (the tests using the real ticker).
- The Timer class is underspecified and inconsistent regards to the unit returned by
read*
function, it would be interesting to specify behavior in boundary case and add test for these case.
static uint32_t curr_ticker_us_val; | ||
|
||
/* User ticker interface function. */ | ||
static void my_interface_init() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my_
functions are stubs. I suggest replacing my_
prefix by stub_
prefix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
* system clock frequency = 32 678 Hz (~32 kHz) => 1 tick = 31.25 us. | ||
* delta = truncate(31.25 * 10 + 5) = truncate(317.5) = 317 us. | ||
*/ | ||
#define DELTA_SYS_CLK_US ((int)((1.0f / ((float)osKernelGetSysTimerFreq() / US_PER_SEC) ) * 10 + 5)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to use a constant variable instead of a macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible, but then it would have to be a very large value (e.g. 500 us), to be able to successfully execute test on each board. It looks like the better option is to define delta value based on board clock frequency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant:
static const int delta_sys_clk_us = (...);
* ticker data provided by the user. | ||
* | ||
* */ | ||
utest::v1::status_t timer_user_ticker_setup_h(const Case *const source, const size_t index_of_case) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What the suffix _h
stands for ? _handler
? If so then given there is no such suffix define by greentea_*_handler
I suggest to use the _handler
suffix instead of its shortened form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
*/ | ||
void test_timer_creation() | ||
{ | ||
float read_val; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to declare variables at initialization point ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed - removed local variables to hold measured time. Instead call read function inside assertion.
read_hr_us_val = p_timer->read_high_resolution_us(); | ||
|
||
/* Check results. */ | ||
TEST_ASSERT_EQUAL(0, read_val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
read_val
is a float, might be good to use the float assertion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
read_hr_us_val = p_timer->read_high_resolution_us(); | ||
|
||
/* Check results. */ | ||
TEST_ASSERT_EQUAL(0, read_val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
read_val
is a float, might be good to use the float assertion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
/* Note that timers are based on 32-bit int microsecond counters, | ||
* so can only time up to a maximum of 2^31-1 microseconds i.e. | ||
* 2147483647 us (about 35 minutes). */ | ||
curr_ticker_us_val = 2147483647; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serious question, what is supposed to happens when curr_ticker_us_val.read returns a value outside the [0 : MAX_INT] range ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curr_ticker_us_val is of unsigned integer type. In case when the value would be greater than MAX_INT, then we have inconsistency. In such case read functions would return negative values.
I have assumed that the max tested measured time can not exceed MAX_INT based on information from mBed handbook (see Warning):
https://developer.mbed.org/handbook/Timer
https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/tasks/Timer/
According to the documentation Timer is dedicated to measure small times (between microseconds and seconds).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bulislaw Could you clarify the behavior of the Timer class when the time measured exceeds the value returned ?
There is a warning in the handbook but nothing in the class declaration. The range returned by read
, read_ms
, read_us
and read_high_resolution_us
is also unspecified. According to the warning in the handbook, the maximum value returned by read_ms
will be 2147483
which is not very intuitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, best would be to check how it actually works. Confirm it makes sense and update the docs/handbook.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bulislaw @pan- I created test based on documentation provided in handbook. So the boundary case for max measured time is MAX_INT. I agree that values returned by the read* functions are not very intuitive. Currently when measured time is equal to MAX_INT (2147483647) read* functions return the following values:
read(): 2147.483643 - ok
read_ms(): 2147483 - ok
read_us(): 2147483647 - ok
read_high_resolution_us(): 2147483647 - ok
When measured time is equal to MAX_INT+1 (2147483648), then we have the following results:
read(): -2147.483643 - wrong
read_ms(): 2147483 - ok
read_us(): -2147483648 - wrong
read_high_resolution_us(): 2147483648 - ok.
It is very strange that returned time can be negative, but warning in handbook informs about Timer time measurement limitations. On the other hand maybe we could modify Timer::read_us()
and Timer::read_ms() function declarations and change returned type to unsigned int. This way measured time limit would be increased and we would also rid of negative results.
In such case handbook and documents need to be also updated.
Please look at the failure in jenkins ci : |
@mprse Bump |
8e11d6a
to
4255a54
Compare
I restarted jenkins CI, as the last failure is not available anymore to review, @mprse please review if it fails again |
retest uvisor |
bump for review round ! |
@pan- are you happy with the fixes? |
retest uvisor |
bump |
#define DELTA_US delta_sys_clk_us | ||
#define DELTA_S ((float)delta_sys_clk_us/US_PER_SEC) | ||
|
||
static Timer *p_timer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please initialize p_timer to NULL so the test in timer_user_ticker_setup_handler is valid.
* */ | ||
utest::v1::status_t cleanup_handler(const Case *const source, const size_t passed, const size_t failed, const failure_t reason) | ||
{ | ||
delete p_timer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please reset p_timer to NULL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
/morph test |
1 similar comment
/morph test |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputTest failed! |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputBuild failed! |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputTest failed! |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputTest failed! |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputTest failed! |
Result: ABORTEDYour command has finished executing! Here's what you wrote!
|
@studavekar Just to be aware of cyclic running CI (it seems to me) ? @mprse Please look at the failures, there are related to this patch I aborted the last job |
@0xc0170 the recursive trigger was due to an experimental scrip where bot triggered the aborted jobs, however when bot makes a comment of results it has a test trigger morph command in it causing recursive trigger. this is disabled and we shouldn't see this now. |
Increased measured time tolerance (for NRF51_DK). |
/morph test |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
/morph test-nightly |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
We're going to make sure this is not flaky by running it a bunch. |
/morph test-nightly |
Build : SUCCESSBuild number : 101 Triggering tests/test mbed-os |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputBuild failed! |
It looks like there was IAR licence problem: |
@mprse The build trigger the test that is equal to nightly, wait for the next status, should be OK , license problem was resolved |
Updated the status of "morph-test-nightly" with last passing run #4971 (comment). |
Description
Add unit tests for Timer class.
Status
READY
Migrations
NO