-
Notifications
You must be signed in to change notification settings - Fork 204
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
Fix #1815, add retroactive CFE status asserts #1816
Fix #1815, add retroactive CFE status asserts #1816
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.
Do the globals get cleared on a unit test reset? I'd think they should be (or at least clear StoredText so it won't warn)... I'm thinking the case where something isn't implemented and we just want to skip the rest of the test, but the next store shouldn't error since it was intended to skip.
I don't think we need to give a warning at all about overriding the store. |
Just had a new idea here, which may make this cleaner. The idea is to change "WAS" to be a soft fail - that is, it asserts with the NA case type, so you can do more than one test. Then we can also have a "MUSTBE" for a hard fail. This may make testcase code more readable. |
Fairly trivial change to the macro/code makes the use case look like this:
And the output log looks like this:
|
I think that makes this more complicated than it really needs to be. Also having an N/A without any kind of explanation why that test is no longer applicable would just be confusing. |
If you want to do more than one test on it why not just not clear out the store after a WAS is called. I don't think it's a problem if Store just overrides everytime. |
Not convinced breaking the assert pattern for STATUS_WAS is worth the extra complexity (introducing the concept of soft fail). The test can store the status on the stack and do whatever logic you want. Basically it feels like adding an assert to be able to control the flow where it's not really needed... it isn't asserting anything. |
I dunno, focusing on the test case implementation, IMO this makes the code read like a book. Plain as day - No extra local variables, no checking for things that are already checked for.
The whole point of all this is we have plenty of cases where testing cannot boil down to not "one right value" in our test code. That's just reality... In that sense, the UtAssert "pattern" is already broken (because they are written with the notion of one right value). So yes, this is a "new" pattern - sort of. Because we've done one-off workarounds in a number of places already (and as such, not new). It's just a matter of how it was solved in the past and how we want to solve it going forward. Do we want lots of different ways of doing this type of thing, or do we want consistent patterns in the testing? That's really the choice here. Whether we go with this suggestion or something different, we do need to establish a some sort of recommended pattern or at least a modicum of consistency when dealing with cases where the output of a function is permitted to be one of several different values. It isn't that rare in functional test. (at least not rare enough, IMO, to say "lets not bother with that" - in coverage test, sure - there should be only one right value - but in functional test with uncontrolled preconditions - not so much). |
My concern with the original form is that it's a little goofy to use in the test case code, typically asserting on something you just checked, in order to get the logs complete. Take the CDS use case - with the original proposal, it would go something like this:
The fact that we checked for Again, the whole impetus of this, is to get some improvement and consistency in what goes into the test log file. With test cases handling each exception like this in a one-off manner, there is no consistency in either implementation or what gets logged (making tracing more difficult - we have to go back to the source code to see what "status == CFE_SUCCESS" meant here). The macros are intended to improve the accuracy of the log file - to more fully capture what was called and what was returned. No earth-shattering new assert capabilities, just a better log file at the end of the day. |
I do like the STORE and WAS asserts as they relate to the logs (with WAS being a hard assert). I don't see the added value of having a soft fail w/ an NA in the log, it seems more straight forward to me to keep it focused on actual asserts. Or use a completely different prefix since it's not really an assert in the classical sense (at least not how I currently understand the proposed pattern) and I'd prefer it be very obvious and hard to get wrong... if you really want logic flow sort of messages in the log. UtBranch/UtFlow/UtPath or similar, and could have it as another stage of reporting (or just make them debug) where it's optional if you want? |
And in the form I'm proposing today, the same CDS use case would look something like:
No extra local status or local checks, no double-checking. Reads clean, which I like - very clear what's going on here! |
CFE_UtFlow_STATUS_CHECK(blah) and keep CFE_UtAssert_STATUS_WAS as a hard assert? STATUS_CHECK could just be debug info, or a step below the PASS/FAIL. |
The value of "soft fail with NA" is that it's a casetype we already have, and requires absolutely no updates to the UtAssert library. Yes, it is a stretch from the original intent of NA, and we could consider using a different name, but for the proof of concept, it fit what was needed to make a check that doesn't fail the test. The extra "N/A" line in the log is a valid concern, but I don't think its wrong to have it in there:
It's the truth, anyway - the test case DID check for it. I concur its probably not much value to the end user, but to squelch it would require an update to UtAssert (I think) to differentiate from the cases you do want to see - so that's where IMO it's better to leave it as is. More info in logs is OK (ignore the extra), but too little is bad. |
I get it now, you are using CFE_UtAssert_STATUS_WAS as a getter that makes a record in the log. That idea is fine but I agree with skilper on the name change since this isn't a assert anymore. I also think that it should be an [info] event in the log instead of an [n/a]. |
Sorry, reading out of order. So I think the example you had in this case is definitely goofy, but only because you are asserting something you weren't actually originally testing for. Keep that specific test related to creating new, and the assert for already existing should be separate. You have to do it if it is new, so why try to double up the purpose of the first test? At minimum change the prefix... I don't care all that much about reporting, NA is fine but it needs to be clear it's not a PASS/FAIL assert. |
In other words, I see:
as being plenty good. Sure it doesn't put the non-assert flow info in there, but it's really obvious in the log what it did... |
To a human reader, maybe ... They'll see the string "CDS already exists. CFE_ES_RegisterCDS new allocation could not be properly tested" ... one has to go back to the code and see that it was from a call to CFE_ES_RegisterCDS(), with three valid input arguments, returning CFE_ES_CDS_ALREADY_EXISTS. My point is, that latter info should really be in the log too - like we log everything else that we call and returns a value, we should log the fact that we called |
Also, I read the prefix a little differently. Per coding standards/naming conventions, all macros/constants/functions defined by a module should be prefixed with the name of that module. That's what the The point is, that prefix is not to say that everything makes some sort of "assert" in the log - far from it, the library has plenty of helper functions that are also prefixed with _CFE_RegisterTest, CFE_Assert_LibInit, and on. Just because it starts with "CFE_Assert" does not mean it triggers an assert in the log. |
Latest update does the following:
|
The base branch does not yet include a test for create pipe max number, but that test now looks like this:
|
Heads up, this will have conflicts with #1785 |
Note, see also nasa/osal#1131 - adding a couple new case types to OSAL allows us to better capture the nuanced differences between these N/A cases. With that, we relegate these new "MAY_BE" messages to the debug level if they don't match, which cleans up the log nicely. In my own test branch (including nasa/osal#1131) the logs now look like this. For CDS normal startup (PO):
For CDS already exists startup (PR):
And finally, the CreatePipe max test (all other "max" tests would be similar):
|
1406779
to
20b9dd9
Compare
CCB:2021-08-18 APPROVED
|
286c76e
to
fdeac78
Compare
Latest proposal just uses a case type of "FLOW" (see latest updates in nasa/osal#1131) Here is what a "Nominal" CDS test run looks like in the log (PO reset, CDS does not exist, default log level):
Here is what a "Verbose" CDS test run looks like:
And for another example, here is what the "Max Gen Counters" test case looks like in default log level:
And here is what the same run looks like with "verbose" log level:
|
Note that the "special sauce" of including an extra match/not match tag at the end is done inside the implementation of |
IMO, its kinda redundant, because the raw info (numbers) are already there, you can already see its not a match. But if this helps, I'm OK with it. |
Is CFE_Assert_STATUS_MUST_BE also adding that match/not match text. I don't think it should be since it is a hard pass or fail test. |
Any method you want to report in the log what the test thinks the result is works for me, I think the implementation in the macro is ideal. You could even change it to just show |
To me then it would basically read as for the MAY_BE test it was either PASS based on the result in the text or was FLOW based on the result shown in the text. Makes it really clear it's a non-failure and just a decision point. But really I'm fine with it as-is also since it meets my desired criteria... just brainstorming. |
This really does help me. I very much struggle with comparing -1021399484 with -1021399484 with -1021394984 quickly and benefit greatly from knowing what the code thought the result was. Somewhat trivial here (although I honestly do still struggle w/ this simple example and have to study it for quite a while before I'm really sure), but string comparisons if we eventually support those in a soft test are much harder to spot quickly. |
fdeac78
to
621cc35
Compare
OK - the latest update squashes all the activity, along with the following cleanup:
Should be good to go, however this depends on nasa/osal#1131 (this is why the CI is failing build, as soon as OSAL is merged should be able to re-run and pass). |
OK, the only downside/weirdness that I can see is that when a case of Example, I hacked the CreatePipe max test to force a failure - basically to check
|
To clarify - match/no match was still added/printed in the MUST_BE case, it just made a little more sense than switching to |
Add a set of macros that decouple the function call from the expected status: - CFE_UtAssert_STATUS_STORE - CFE_UtAssert_STATUS_MAY_BE - CFE_UtAssert_STATUS_MUST_BE The first will make the function call and put the status into a temporary holding area, but will not assert on any particular result. The may/must macros then check the value of the holding area.
621cc35
to
52f77e3
Compare
Updated again to change the
I like this better because we are being accurate about the actual condition that was checked for in all cases, but it still should be clear if that had evaluated as false. Note that I did not add a corresponding |
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.
Looks good to me, I would like to consider the additional [false] marker for the other macros under our control for consistency (fine as a separate/future issue).
Note - the build failure currently reported from CI is fixed by nasa/osal#1131 - currently in IC - so if this gets merged (or if we just finish the OSAL merge) this should work OK. I'd like to get this merged in the build before the new RC tag is created, if possible. |
**Combines** nasa/cFE# v6.8.0-rc1+dev933 nasa/osal# v5.1.0-rc1+dev594 **Includes** *osal* nasa/osal#1131, add test case types similar to NA *cFE* nasa/cFE#1803, Add software bus tests nasa/cFE#1756, separate variable for OSAL status nasa/cFE#1809, increase SB pool max size bucket nasa/cFE#1842, Add Null check for CFE_ResourceId_FindNext nasa/cFE#1828, Improve TBL coverage tests nasa/cFE#1833, Clean up Message ID Functional Test #1824, Add missing cases for msg id func tests nasa/cFE#1832, Combine SB Set/Get message characteristics group #1831, Consolidate msg get/set doxygen group nasa/cFE#1836, Adding coverage tests to cFE TIME nasa/cFE#1848, enable strict resource id w/OMIT_DEPRECATED nasa/cFE#1845, HOTFIX IC-20210819, type correction TBL coverage test nasa/cFE#1806, Add test for ES BackgroundWakeup nasa/cFE#1813, Success Test for CFE_ES_RestartApp nasa/cFE#1814, Subscribe to Message Limit Greater Than CFE_PLATFORM_SB_DEFAULT_MSG_LIMIT nasa/cFE#1811, Success Test for CFE_ES_GetMemPoolStats nasa/cFE#1822, Group MSG APIs documentation by header type nasa/cFE#1816, add retroactive CFE status asserts nasa/cFE#1854, remove unused CFE_TBL_ERR_BAD_APP_ID nasa/cFE#1855, correct syslog message in pool create nasa/cFE#1853, remove unused CFE_ES_POOL_BOUNDS_ERROR nasa/cFE#1859, remove unused CFE_TBL_ERR_FILE_NOT_FOUND nasa/cFE#1856, Check error ctr to TransmitMsg test nasa/cFE#1857, End Child Task requirement remove error code nasa/cFE#1782, Add functional tests for resource misc Co-authored-by: Jacob Hageman <skliper@users.noreply.github.com> Co-authored-by: Joseph Hickey <jphickey@users.noreply.github.com> Co-authored-by: Alex Campbell <zanzaben@users.noreply.github.com> Co-authored-by: Niall Mullane <nmullane@users.noreply.github.com> Co-authored-by: Ariel Adams <ArielSAdamsNASA@users.noreply.github.com> Co-authored-by: Jose F Martinez Pedraza <pepepr08@users.noreply.github.com>
Describe the contribution
Add a set of macros that decouple the function call from the expected status:
CFE_Assert_STATUS_STORE
CFE_Assert_STATUS_MAY_BE
CFE_Assert_STATUS_MUST_BE
The first will make the function call and put the status into a temporary holding area, but will not assert on any particular
result.
The others will check the value of the holding area.
Fixes #1815
Testing performed
Build and run all tests
Also Add new test cases that need this paradigm and confirm macros working as expected (will be in other PRs).
Expected behavior changes
None, new test macros only, not used yet.
System(s) tested on
Ubuntu
Additional context
These macros should be used whenever a specific status is not predictable before the call, but other checks after the call can determine if the result was OK or not.
A typical use case for a function that might return any of 3 status values (e.g. status1, status2, status3) would be something like:
Contributor Info - All information REQUIRED for consideration of pull request
Joseph Hickey, Vantage Systems, Inc.