- Notifications
You must be signed in to change notification settings - Fork0
An adapter for making C code testable from Python (seehttps://headlock.readthedocs.io/en/latest)
License
mrh1997/headlock
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This is an adapter for testing C code via tests written in python.When being combined i.e. with pytest it provides a very powerful andconvinient way of writing (unit-/integration-) tests for C code.
In contrary to other C/Python bridges (like ctypes, cffi, swing, ...)the goals of this projects are:
- Run (and Compile) a piece of C code (Module Under Test)out of the box with as less lines of Python code as possible.No need to create Makefile, no need to run extra build steps.
- Provide a simple, intuitive API for accessing C objects
- Allow to quickly:
- mock the underlying C modules in Python
- work with different binaries of a Module Under Test atthe same time.
- testing a Module Under Test with binaries compiled withdifferent preprocessor defines
- Run the C code in a separate Address Space to avoid that a crashingModule Under Test crashes also the testing python code(Not implemented yet!).
- Especially make it work with embedded systems, so that
- C code can be run onreal hardware while python tests run on PC.(Mainly useful for integration tests)This is not implemented yet!
- C code can be run on PC instead of embedded environment.(Mainly useful for unittests)
Explicitly Non-Goals Are:
- Supporting C++ is not planned
- Performance has a very low priority. This does not mean that it isslow. But if speed conflicts with one of the goals of this project,there will be no compromises in favour of speed.
- Being self-contained is not planned. A C-compiler is requiredto be installed. Furthermore currently LLVM has to be installedat it is used for parsing the file.
- Python < 3.6 will never be supported
This piece of C-code contains a macros, a struct a functionimplementation and a function that is relying on(which should be mocked):
#include"underlying_module.h"structops_t{inta,b;} ;#defineMACRO_2 (MACRO_1 + 1)intfunc(structops_t*p){returnunderlying_func(p->a+p->b+MACRO_1);}
You can access it from python throughheadlock like:
fromheadlock.testsetupimportTestSetup,CModule@CModule('dummy.c',MACRO_1=1)classTSSample(TestSetup):defunderlying_func_mock(self,param):returnparam.val+4000withTSSample()asts:ops=ts.struct.ops_t(a=ts.MACRO_2,b=20)assertts.func(ops.ptr).val==4021
This demonstrates how:
- You can handle different binaries of the same C-source per .py file(as each one is a TestSetup derived class instead of a module)
- Every binary can be compiled with other parameters(PY_MACRO can be set differently per testsetup)
- structures/unions/enums/typedefs can be accessed from Python withoutextra declarations (
struct ops_t
in this case). - You can access C-functions from Python without extra declarations(
func
in this case) - You can access C-macros from Python without extra declarations(
C_MACRO
in this case) - You can call python-methods from C (=mocking C functions that arenot part of the Module Under Test;
underlying_func
in this case). It is even possible todynamicially replace mocks (i.e. by unittest.mock.Mock())
Currently this is alpha.
For a list of planned but not yet implemented features please refer toDevelopment Status
About
An adapter for making C code testable from Python (seehttps://headlock.readthedocs.io/en/latest)