Running the test
|It should go without saying that you should never run test cases on your development machine or on production machines -- always run tests on dedicated test machines. The tests are run in kernel mode and can therefore crash your machine.|
Running kernel mode unit tests is no different than running user mode tests. That is, tests are run using the testrunner cfix32.exe (for 32 bit code) or cfix64.exe (for 64 bit code) .
Note that a 64 bit test driver can be run either with cfix64.exe or with cfix32.exe, i.e. cfix is aware of WOW64 and the possibility that the kernel uses another bitness than the user mode test runner. Still, using cfix64.exe is preferrable in such cases.
|For obvious reasons, the cfix driver (cfixkr.sys) is not signed. On Vista x64 and Server 2008 x64, the driver thus will not be able to load unless the test system has been booted in debug mode or with Kernel Mode Code Signing disabled.|
Copy the test driver to your test machine (as always, drivers must be loaded from the local disk, so any attempt to load the test driver over the network will fail). Having done that, you can run cfix32.exe -kern -d ktest.sys to display the tests contained in the driver:
C:\drv\i386>cfix32 -kern -d ktest.sys Cfix version 1.1.3059.65 (chk) (c) 2008 - Johannes Passing - http://cfix.sf.net/ Module: ktest (ktest.sys) Fixture: MyFixture Test1 Test2 Fixture: MyOtherFixture Test1
Note that we have used the -kern switch. To avoid using kernel mode features accidently, the -kern switch is always necessary if you intend to use kernel mode features.
That said, we can now run the test by executing cfix32.exe -kern ktest.sys. Assuming no kernel debugger has been attached, the following output will appear on your console:
C:\drv\i386>cfix32 -kern ktest.sys Cfix version 1.1.3059.65 (chk) (c) 2008 - Johannes Passing - http://cfix.sf.net/ [Log] ktest.MyFixture.Test1 a=1, b=1 [Success] ktest.MyFixture.Test1 [Failure] ktest.MyFixture.Test2 d:\dev\wdev\cfix\doc\samples\temp\test.c(65): Test2 Expression: a == 42 Last Error: 0 (The operation completed successfully. ) [Log] ktest.MyFixture.unknown Tearing down... [Log] ktest.MyOtherFixture.Test1 a=1, b=1 [Success] ktest.MyOtherFixture.Test1
As is the case with user mode tests, cfix will detect if a kernel debugger is attached and will adapt its behaviour, i.e. it will issue a breakpoint when an assertion has failed.
So let's run the command cfix32.exe -kern ktest.sys again on a machine that has a kernel debugger attched. Test1 passes, so the following output appears on the console first:
C:\drv\i386>cfix32 -kern ktest.sys Cfix version 1.1.3059.65 (chk) (c) 2008 - Johannes Passing - http://cfix.sf.net/ [Log] ktest.MyFixture.Test1 a=1, b=1 [Success] ktest.MyFixture.Test1
Test2, however, fails and causes a debugger breakin. WinDBG will report
Break instruction exception - code 80000003 (first chance) ktest!Test2+0x2e: f9fc50fe cc int 3
and the source window will show the culprit:
Hiting F5 will continue the test (the same rules apply as in user mode testing) and the rest of the output will appear on the console:
[Failure] ktest.MyFixture.Test2 d:\dev\wdev\cfix\doc\samples\temp\test.c(65): Test2 Expression: a == 42 Last Error: 0 (The operation completed successfully. ) [Log] ktest.MyFixture.unknown Tearing down... [Log] ktest.MyOtherFixture.Test1 a=1, b=1 [Success] ktest.MyOtherFixture.Test1
Some final words on kernel mode testing: cfix kernel mode tests are always initialted at PASSIVE_LEVEL. However, test cases are free to raise the IRQL to any level and still call CFIX_ASSERT etc.
Moreover, the cfix API (i.e. ASSERT etc) may only be used on the same thread. If called from a different thread, cfix will be unable to relate the call to a testrun -- after all, multiple kernel mode testruns could be run in parallel. Therefore, cfix will issue a warning via DbgPrint but will otherwise ignore these calls.
Finally, cfix will catch and report any exceptions that your test code has raised and failed to handle. However, if your code causes a bugcheck, cfix will not be able to prevent that.