Skip to content

Commit

Permalink
Fix2
Browse files Browse the repository at this point in the history
  • Loading branch information
kenlautner committed Jun 29, 2024
1 parent 7dc8ec2 commit 3a70fc9
Showing 1 changed file with 26 additions and 32 deletions.
58 changes: 26 additions & 32 deletions UnitTestFrameworkPkg/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -1093,22 +1093,6 @@ int main(int argc, char* argv[]) {
}
```
However, while GoogleTest does not require test suites or test cases to be
registered, there is still one rule within EDK II that currently needs to be
followed. This rule is that all tests for a given GoogleTest application must
be contained within the same source file that contains the `main()` function
shown above. These tests can be written directly in the file or a `#include`
can be used to add them into the file indirectly.
The reason for this is due to EDK II taking the host application INF file and
first compiling all of its source files into a static library. This static
library is then linked into the final host application. The problem with this
method is that only the tests in the object file containing the `main()`
function are linked into the final host application. This is because the other
tests are contained in their own object files within the static library and
they have no symbols in them that the final host application depends on, so
those object files are not linked into the final host application.
### GoogleTest - A Simple Test Case
Below is a sample test case from `SampleGoogleTestHost`.
Expand Down Expand Up @@ -1314,6 +1298,20 @@ leave those details to be explained in the gMock documentation.
To write more advanced tests, take a look at the
[GoogleTest User's Guide](http://google.github.io/googletest/).

## Development

### Iterating on a Single Test

When using the EDK2 Pytools for CI testing, the host-based unit tests will be built and run on any build that includes
the `NOOPT` build target.

If you are trying to iterate on a single test, a convenient pattern is to build only that test module. For example,
the following command will build only the SafeIntLib host-based test from the MdePkg...

```bash
stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=VS2017 -p MdePkg -t NOOPT BUILDMODULE=MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.inf
```

### Hooking BaseLib

Most unit test mocking can be performed by the functions provided in the UnitTestFrameworkPkg libraries, but since
Expand Down Expand Up @@ -1363,10 +1361,6 @@ After that, the following commands will set up the build and run the host-based
# stuart_setup -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=<GCC5, VS2019, etc.>
stuart_setup -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=VS2019

# Mu specific step to clone mu repos required for ci check
# stuart_ci_setup -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=<GCC5, VS2019, etc.>
stuart_ci_setup -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=VS2019

# Update all binary dependencies
# stuart_update -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=<GCC5, VS2019, etc.>
stuart_update -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=VS2019
Expand Down Expand Up @@ -1563,7 +1557,7 @@ Code/Test | Location
Host-Based Unit Tests for a Library/Protocol/PPI/GUID Interface | If what's being tested is an interface (e.g. a library with a public header file, like DebugLib) and the test is agnostic to a specific implementation, then the test should be scoped to the parent package.<br/>Example: `MdePkg/Test/UnitTest/[Library/Protocol/Ppi/Guid]/`<br/><br/>A real-world example of this is the BaseSafeIntLib test in MdePkg.<br/>`MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost.inf`
Host-Based Unit Tests for a Library/Driver (PEI/DXE/SMM) implementation | If what's being tested is a specific implementation (e.g. BaseDebugLibSerialPort for DebugLib), then the test should be scoped to the implementation directory itself, in a UnitTest (or GoogleTest) subdirectory.<br/><br/>Module Example: `MdeModulePkg/Universal/EsrtFmpDxe/UnitTest/`<br/>Library Example: `MdePkg/Library/BaseMemoryLib/UnitTest/`<br/>Library Example (GoogleTest): `SecurityPkg/Library/SecureBootVariableLib/GoogleTest/`
Host-Based Tests for a Functionality or Feature | If you're writing a functional test that operates at the module level (i.e. if it's more than a single file or library), the test should be located in the package-level Tests directory under the HostFuncTest subdirectory.<br/>For example, if you were writing a test for the entire FMP Device Framework, you might put your test in:<br/>`FmpDevicePkg/Test/HostFuncTest/FmpDeviceFramework`<br/><br/>If the feature spans multiple packages, it's location should be determined by the package owners related to the feature.
Non-Host-Based (PEI/DXE/SMM/UefiShell) Tests for a Functionality or Feature | Similar to Host-Based, if the feature is in one package, should be located in the `*Pkg/Test/[UefiShell/Dxe/Smm/Pei]Test` directory.<br/><br/>If the feature spans multiple packages, it's location should be determined by the package owners related to the feature.<br/><br/>USAGE EXAMPLES<br/>PEI Example: MP_SERVICE_PPI. Or check MTRR configuration in a notification function.<br/> SMM Example: a test in a protocol callback function. (It is different with the solution that SmmAgent+ShellApp)<br/>DXE Example: a test in a UEFI event call back to check SPI/SMRAM status. <br/> Shell Example: the SMM handler audit test has a shell-based app that interacts with an SMM handler to get information. The SMM paging audit test gathers information about both DXE and SMM. And the SMM paging functional test actually forces errors into SMM via a DXE driver.
Non-Host-Based (PEI/DXE/SMM/Shell) Tests for a Functionality or Feature | Similar to Host-Based, if the feature is in one package, should be located in the `*Pkg/Test/[Shell/Dxe/Smm/Pei]Test` directory.<br/><br/>If the feature spans multiple packages, it's location should be determined by the package owners related to the feature.<br/><br/>USAGE EXAMPLES<br/>PEI Example: MP_SERVICE_PPI. Or check MTRR configuration in a notification function.<br/> SMM Example: a test in a protocol callback function. (It is different with the solution that SmmAgent+ShellApp)<br/>DXE Example: a test in a UEFI event call back to check SPI/SMRAM status. <br/> Shell Example: the SMM handler audit test has a shell-based app that interacts with an SMM handler to get information. The SMM paging audit test gathers information about both DXE and SMM. And the SMM paging functional test actually forces errors into SMM via a DXE driver.

### Example Directory Tree

Expand All @@ -1576,7 +1570,7 @@ Non-Host-Based (PEI/DXE/SMM/UefiShell) Tests for a Functionality or Feature |
ComponentYHostGoogleTest.inf # Host-Based Test for Driver Module
ComponentYGoogleTest.cpp
UnitTest/
ComponentYUnitTestHost.inf # Host-Based Test for Driver Module
ComponentYHostUnitTest.inf # Host-Based Test for Driver Module
ComponentYUnitTest.c
Library/
Expand All @@ -1593,8 +1587,8 @@ Non-Host-Based (PEI/DXE/SMM/UefiShell) Tests for a Functionality or Feature |
SpecificLibDxeHostGoogleTest.cpp
SpecificLibDxeHostGoogleTest.inf
UnitTest/ # Host-Based Test for Specific Library Implementation
SpecificLibDxeUnitTest.c
SpecificLibDxeUnitTestHost.inf
SpecificLibDxeHostUnitTest.c
SpecificLibDxeHostUnitTest.inf
Test/
<Package>HostTest.dsc # Host-Based Test Apps
GoogleTest/
Expand All @@ -1608,16 +1602,16 @@ Non-Host-Based (PEI/DXE/SMM/UefiShell) Tests for a Functionality or Feature |
UnitTest/
InterfaceX
InterfaceXUnitTestHost.inf # Host-Based App (should be in Test/<Package>HostTest.dsc)
InterfaceXUnitTestPei.inf # PEIM Target-Based Test (if applicable)
InterfaceXUnitTestDxe.inf # DXE Target-Based Test (if applicable)
InterfaceXUnitTestSmm.inf # SMM Target-Based Test (if applicable)
InterfaceXUnitTestUefiShell.inf # Shell App Target-Based Test (if applicable)
InterfaceXHostUnitTest.inf # Host-Based App (should be in Test/<Package>HostTest.dsc)
InterfaceXPeiUnitTest.inf # PEIM Target-Based Test (if applicable)
InterfaceXDxeUnitTest.inf # DXE Target-Based Test (if applicable)
InterfaceXSmmUnitTest.inf # SMM Target-Based Test (if applicable)
InterfaceXShellUnitTest.inf # Shell App Target-Based Test (if applicable)
InterfaceXUnitTest.c # Test Logic
GeneralPurposeLib/ # Host-Based Test for any implementation of GeneralPurposeLib
GeneralPurposeLibTest.c
GeneralPurposeLibUnitTestHost.inf
GeneralPurposeLibHostUnitTest
Mock/
Include/
Expand All @@ -1641,8 +1635,8 @@ the following, please make sure they live in the correct place.
Code/Test | Location
--------- | --------
Host-Based Library Implementations | Host-Based Implementations of common libraries (eg. MemoryAllocationLibHost) should live in the same package that declares the library interface in its .DEC file in the `*Pkg/Test/Library` directory. Should have 'Host' in the name.
Host-Based Mocks and Stubs | Mock and Stub libraries that require test infrastructure should live in the `UefiTestFrameworkPkg/Library` with either 'Mock' or 'Stub' in the library name.
Host-Based Library Implementations | Host-Based Implementations of common libraries (eg. MemoryAllocationLibHost) should live in the same package that declares the library interface in its .DEC file in the `*Pkg/HostLibrary` directory. Should have 'Host' in the name.
Host-Based Mocks and Stubs | Mock and Stub libraries should live in the `UefiTestFrameworkPkg/StubLibrary` with either 'Mock' or 'Stub' in the library name.
### If still in doubt
Expand Down

0 comments on commit 3a70fc9

Please sign in to comment.