Module testing

Unit testing involves writing several test procedure calls and verifying the correctness of the returned values.

The majority of the interface functions of Hermes-core demands backends (for Data store/Credential store/Keystore) and transport to be implemented beforehand.

To simplify the testing and eliminate the influence of additional factors, simplified in-memory backends have been implemented for Stores (Data store, Credential store, Keystore) and transport using pipes.

The implementation and tests of backend and transport can be found in the corresponding folder of the tests folder in Hermes-core repository. The tests/rpc folder contains unit tests of the RPC implemented with the help of the transport mentioned above.

A standard target test was also added to the main Makefile for building tests. This means that you need to type the following command into the command line to build and run the tests:

make test

It's worth mentioning that the check target does not build the project.

In addition to unit testing, Hermes-core was also tested using static and dynamic code analysers.

Static code analysis

For static code analysis, we used cppcheck and clang static analysis tools.

Dynamic code analysis

While the static code analysis is performed without executing the code (i.e. on the compilation stage), dynamic analysis is performed during the code execution.
When analysing the compiled code from a security standpoint, dynamic analysis often means "fuzzing".

The advantage of fuzzing is that it is almost fully devoid of false positives (which quite often take place when static analyzers are used).

Usually, a fuzzer feeds the test data into the STDIN of the app through using a temporary file. If the process crashes - the fuzzer will notice it and write the data into the crashes directory.
An important moment for a successful fuzzing is that Address Sanitizer is added - this way the app is guaranteed to crash when even one byte of the dynamic memory is overwritten. We use sanitizers embedded into the compiler and find it to be a highly rewarding and advisable testing practice.

There are two approaches to fuzzing:
- fuzzing separate functions that look suspicious,
- fuzzing the whole app.

The libFuzzer library was used for fuzzing.
For implementing the first approach, a minimal wrapper needs to be written for the application:
```(fuzz.c)
int LLVMFuzzerTestOneInput(const uint8t *Data, sizet Size) {
functionForTest(Data, Size);
return 0;
}