General Overview¶
This section contains a general overview of the directory structure for regression tests.
Basic Directory Structure¶
The root directory of all regression tests is retdec-regression-tests
. The tests are structured into subdirectories, where each test is formed by a single subdirectory. Such a subdirectory has to contain:
- A
test.py
file, which is a test module containing test classes, settings, and methods that check whether the test passes or fails. Basically, it represents test specification. - Inputs for the test. These are usually binary files to be decompiled.
A sample test structure looks like this:
regression-tests/
├── bugs/
│ └── invalid-function-name/
│ ├── input.exe
│ └── test.py
├── features/
│ └── main-detection/
│ ├── input.msvc.exe
│ ├── input.gcc.elf
│ └── test.py
└── integration/
├── ack/
│ ├── ack.exe
│ └── test.py
└── ackermann/
├── ackermann.exe
└── test.py
Outputs from Decompilations¶
After you run the regression tests, outputs from decompilations are placed into subdirectories named outputs
. In this way, you can check them after the tests finish to see what exactly was generated. These subdirectories are created inside the corresponding test directory. For example, for retdec-regression-tests/integration/ack
, the outputs are placed into retdec-regression-tests/integration/ack/outputs
.
To differentiate between the outputs of different decompilations, the outputs from each decompilation are placed into a properly named directory. The name is based on the parameters that were passed to the decompiler when the test ran.
For example, a directory with outputs for the factorial
test may contain the following subdirectories and files:
regression-tests/integration/factorial/outputs/
├── Test_2017 (factorial.x86.gcc.O0.exe)/
│ ├── factorial.x86.gcc.O0.c
│ ├── factorial.x86.gcc.O0.c-compiled
│ ├── factorial.x86.gcc.O0.bc
│ ├── factorial.x86.gcc.O0.ll
│ ├── factorial.x86.gcc.O0.c.fixed.c
│ ├── factorial.x86.gcc.O0.dsm
│ ├── factorial.x86.gcc.O0.config.json
│ └── factorial.x86.gcc.O0.c.log
├── ...
└── Test_2017 (factorial.x86.clang.O0.exe)/
├── factorial.x86.clang.O0.c
├── factorial.x86.clang.O0.c-compiled
├── factorial.x86.clang.O0.bc
├── factorial.x86.clang.O0.ll
├── factorial.x86.clang.O0.c.fixed.c
├── factorial.x86.clang.O0.dsm
├── factorial.x86.clang.O0.config.json
└── factorial.x86.clang.O0.log
Naming Conventions¶
Directory names can contain characters that are valid on common file systems, except a dot (.
). The reason for not allowing a dot is that it is internally used to separate subdirectories in module names. Python uses a dot to separate namespaces, anyway. Examples:
features # OK
cool_backend_feature1 # OK
cool-backend-feature2 # OK
cool.backend.feature1 # WRONG: A dot '.' is not allowed by the regression tests framework.
cool/backend/feature1 # WRONG: A slash '/' is not allowed in a directory name on Linux.
cool|backend*feature1 # WRONG: Characters '|' and '*' are not allowed on Windows.
The naming of functions, classes, methods, and variables inside test.py
files follows standard Python conventions, defined in PEP8. Example:
def my_function():
my_var = [1, 2, 3]
class MyClass(BaseClass):
def do_something(self):
...
def do_something_else(self):
...
Summary¶
To summarize, a test is a subdirectory that is arbitrarily nested inside the root directory and contains a test.py
file and input files. After the tests are run, the output files are placed into a corresponding outputs
directory. For every decompilation, the outputs are placed into a separate subdirectory.
Next, we will learn how to create a new test.