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
[REBASE & FF] Add GoogleTest Mocks and STATIC Testing Ability #830
Conversation
59afc0e
to
35ade72
Compare
35ade72
to
5dd900b
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## release/202311 #830 +/- ##
===============================================
Coverage 1.22% 1.22%
===============================================
Files 1303 1303
Lines 335685 335685
Branches 3183 3183
===============================================
Hits 4118 4118
Misses 331491 331491
Partials 76 76
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
20b0d23
to
14f9703
Compare
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.
Even with the minimum set of dependencies of GOOGLETEST_HOST_UNIT_TEST_BUILD, are we sure there will be no symbol collisions with platform code?
865b3dd
to
e9081c2
Compare
@mdkinney do you have any thoughts on this approach for solving the GoogleTest STATIC testing issue? I will push this to edk2 also, but testing this in Mu first and getting feedback. |
We are trying to remove use of STATIC in existing code and prevent adding STATIC to new code. This would reverse that idea and if we added GoogleTest coverage across all the components would significant increase the use of STATIC. There are also several places that 'static' had to be added to modules/libs to prevent symbol collisions between components. This approach would reopen those issues.
|
Thanks for the review @mdkinney. We looked at the two options you listed, I think that the first option is not viable, static does provide a useful hiding of internal functions. For the second one, I would be curious if the compat issues can be solved, this is how we used to do it in Cmocka, but we have seen a number of issues, the largest being C++ having stricter rules about implicit casting, which occurs all over the codebase. Another idea we reviewed was changing STATIC to PRIVATE and then using static for static lifetime variables, since in effect C is using the same keyword for two different ideas. This would change almost every file though and doesn't seem worthwhile to do. The idea here is that when building a HOST_APPLICATION, you are at the minimal set of dependencies and so we expect that symbol collisions should be rare. It really would just be if there were symbol collisions in the module under test, which I think would be a design flaw for a single module to have symbol collisions. This is not a perfect solution to be sure, but it seemed the lowest lift. If STATIC is removed, I assume you mean that static would be used instead? If that were the case, I would think we would have to solve the GoogleTest including C files compat issues or else GoogleTest would be unable to unit test many static functions (which I think there is great value to as the author of a library or module to ensure that at a function level your helper functions are working as expected, particularly over time as those functions get changed). |
@mdkinney - It would be great to explore other ideas your team may have but after trying to find the best compromise we think this makes sense for testing module C files and library class implementation C files. |
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.
why are you adding all sorts of mock libraries in this PR? I thought we had a plan to only add them as a test needed them?
@spbrogan they are getting consumed in this PR: microsoft/mu_plus#471, so they are needed. |
This patch adds a GoogleTest Mock for UefiRuntimeLib to be consumed in a GoogleTest that requires this lib be mocked.
This patch adds a GoogleTest mock for MemoryAllocationLib, which is needed for a GoogleTest that is attempting to mock that lib.
Gmock does not support mocking variadic functions such as gBS->InstallMultipleProtocolInterfaces. This patch adds support for mocking gBS->InstallProtocolInterface and a wrapper function that calls the mocked gBS->InstallProtocolInterface when code under test attemps to call gBS->InstallMultipleProtocolInterfaces, which mirrors what the actual code does.
In order to support GoogleTest testing STATIC functions, convert the few instances in the codebase where STATIC is used to mean a static lifetime as opposed to meaning a private function/global variable. This allows us to undef STATIC for private functions/global variables to allow them to be unit tested by GoogleTest.
Cmocka is able to test STATIC functions by including the C file in the test file. However, in many scenarios, GoogleTest files cannot do this as the C++ compiler has stricter rules than the C compiler. This patch updates the UnitTestFrameworkPkgHost.dsc.in to add a new build flag GOOGLETEST_HOST_UNIT_TEST_BUILD for HOST_APPLICATIONS only. Base.h is then updated to undef STATIC if this flag is set. This allows for STATIC functions to be tested in GoogleTest. There is less danger of symbol collision here, because HOST_APPLICATIONS are running with the least amount of dependencies possible. This still allows for interfaces tests (where a Library Class is tested, not an instance, so the library is linked in to the test instead of compiled) as the library in this case will not be compiled as a HOST_APPLICATION and so the STATIC functions will remain STATIC.
e9081c2
to
162f3ca
Compare
Description
This PR adds GoogleTest mocks needed for some AdvancedLogger GoogleTests. It also adds the capability to test STATIC functions by undefining the STATIC keyword if a HOST_APPLICATION is being built. The statement is that a HOST_APPLICATION is running with the minimal set of dependencies and should not run into symbol collision.
These will be sent to edk2, but feedback is wanted first, as well as getting the dependent Advanced Logger PR in. If this patch is approved, UnitTestFrameworkPkg's README will also be updated in edk2. This is not done here as that would create a lot of conflicts.
For each item, place an "x" in between
[
and]
if true. Example:[x]
.(you can also check items in the GitHub UI)
flow, or firmware?
validation improvement, ...
in build or boot behavior?
a function in a new library class in a pre-existing module, ...
outside direct code modifications (and comments)?
on an a separate Web page, ...
How This Was Tested
Tested with the Advanced Logger GoogleTests
Integration Instructions
Follow the UnitTestFrameworkPkg README.md for instructions on using GoogleTest mocks. To test STATIC functions, compile the relevant C files with your GoogleTest C++ files and you will be able to access the formerly STATIC functions in your test.
Interface tests (that load a library instead of compiling the C files) will still not be able to access STATIC functions. This is intentional as interface tests should be testing a library interface (the class itself) not an instance.