<br><div class="gmail_quote">2012/10/16  <span dir="ltr"><<a href="mailto:VaclavKrpec@eaton.com" target="_blank">VaclavKrpec@eaton.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hello Arnaud, Charles,<br></blockquote><div><br>Hi Vasek,<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
regarding the nut_clock_* iface unit testing,<br>
I came to the following conclusion:<br>
<br>
1/ It is IMO generally impossible to do deterministic<br>
unit test; the problem in question is inherently<br>
non-deterministic (I mean non-det. by nature).<br>
Justification: the main reason is that we can't<br>
perfectly predict the CPU time spent on computation,<br>
mainly because we have multi-tasking; there might<br>
be any number of context switches between almost<br>
any states, so if we measure time with us/ns precisions,<br>
we can't expect fitting times at that scale.<br></blockquote><div><br>Charles has already answered, and this is also my stance:<br>we are not in hard RT context.<br>we just want to ensure that a 5 seconds timer/sleep/whatever, will actually fires within 10 %, rounded to the prox. boundaries.<br>
i.e, 5 seconds +/- 10 % => between 4 to 6 seconds actually<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2/ This means that there will always be a possibility<br>
of false-positive unit test case failure; it is therefore<br>
inevitable to try to<br>
i) decrease the case possibility to minimum<br>
ii) think about whether we want to invalidate a build if<br>
such a UT fails<br></blockquote><div><br>as told above, 10 % is fine.<br>up to 20 % (below, we are still in the rounding), we are more in a warning area.<br>beyond that, the deviation is an error.<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

ad i) The only thing I came with is usage of statistic<br>
techniques: we should randomise the unit test and/or<br>
run it multiple times. The meaningful deviation from<br>
expected result shall be the avg/mean deviation (with all<br>
the standard statistic tricks applied --- like extremes<br>
cuts etc).  I also suggest that if there's a failure,<br>
we could re-run the very same test case another time to see<br>
whether the next run fails, again (thus eliminating possibility<br>
of a temporary influence etc).<br></blockquote><div><br>the multi run is indeed a good thing.<br>I'm not sure on the random side usefulness though.<br>for ex, 5 runs with 4 under 10 % and 1 above the 20 % would be considered good...<br>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
ad ii) I think the above should be quite enough to eliminate<br>
false positive UT failure reports.  However, it's still not<br>
certain (and can never be).  Therefore, we should decide whether<br>
we want to be pessimistic or optimistic by default, i.e. whether<br>
to invalidate the build or to just send a warning or something...<br>
<br>
3/ The methods I'd use are actually quite simple; for the timestamps<br>
difference (i.e. typical usage of the monotonic clock) validity<br>
checking, I'd simply use select with ho descriptors and a timeout.<br>
I'd take a timestamp before, after and compare the diff. with<br>
the timeout.<br>
In pseudo-code:<br>
<br>
nut_clock_timestamp(&ts);<br>
<br>
select(0, NULL, NULL, NULL, &to);<br>
<br>
diff = nut_clock_sec_since(&ts);<br>
<br>
ut_pass = abs((to.tv_sec + to.tv_usec / 1000000.0) - diff) < sigma;<br>
<br>
(Note that this pseudo-code doesn't include application of the statistic<br>
methods discussed above.)<br></blockquote><div><br>works for me.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I believe that cca 10 us precision is actually far the best we can hope<br>
(actually, I think that we could accept even worse precision regarding<br>
our practical needs).  This doesn't apply to the case of using the<br>
time_t fallback, of course.<br>
<br>
As of the RTC unit testing, I think that we might be OK with unit-sec<br>
precision; if so, we can simply exec "date +%s" to make an "external<br>
authority" to give us seconds since the Epoch and compare this with<br>
what our iface provides.  Note that there is generally the problem<br>
of "what if the UT is executed exactly at the time of clock change...?"<br>
Yes, that's a bugger (sorry for my Greek), but the repeated execution<br>
should filter such problems out (see 2/i).<br>
<br>
<br>
... and that's it, actually.<br>
I'll be more than glad to know if you have better ideas;<br>
I know that's not much, but right now, it's all I've got<br>
(I mean all what can be simply and safely done automatically upon<br>
every build.)<br></blockquote><div><br>that is already a good base for unit tests.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Note that the statistic methods make the UT quite time consuming;<br>
also note that it would actually be great if we could automate<br>
tests like "shifting the system clock and check that the diff.<br>
of 2 timestamps is still OK --- i.e. automatic UT of monotonic<br>
clock.  However, I wouldn't want to actually mess with the buildslave<br>
system clock...  It could be done on a virtual machine though;<br>
so we would need a VM/QEMU and do make test, there...<br>
That could be possible, but also quite complicated.<br></blockquote><div><br>yup, that's still a point I don't have a conclusion yet:<br>QRT (QA regression testing) should have a test with time set back (and/or  forth), and check that this has no incidence on NUT timers.<br>
the thing is that, executing that from the buildslaves may potential break the system, or generate issue.<br>this needs to be checked. but spawning a VM to execute this may solve the point.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


And that's indeed all I have.<br>
<br>
As always, any comments, suggestions etc welcome,<br>
<br></blockquote><div><br>done... with a bit of lag.<br></div></div><br>cheers,<br clear="all">Arnaud<br>-- <br>Linux / Unix / Opensource Engineering Expert - Eaton - <a href="http://opensource.eaton.com" target="_blank">http://opensource.eaton.com</a><br>
Network UPS Tools (NUT) Project Leader - <a href="http://www.networkupstools.org" target="_blank">http://www.networkupstools.org</a><br>Debian Developer - <a href="http://www.debian.org" target="_blank">http://www.debian.org</a><br>
Free Software Developer - <a href="http://arnaud.quette.fr" target="_blank">http://arnaud.quette.fr</a><br><br>