-
Notifications
You must be signed in to change notification settings - Fork 0
209 lines (168 loc) · 6.53 KB
/
ci.yml
File metadata and controls
209 lines (168 loc) · 6.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
name: LibSurgeon CI
on:
push:
pull_request:
jobs:
# ============================================================
# Code Quality Checks
# ============================================================
lint:
name: Lint & Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install black flake8 isort
- name: Check formatting with black
run: |
python -m black --check --diff libsurgeon.py evaluate_quality.py tests/*.py
- name: Lint with flake8
run: |
python -m flake8 .
# ============================================================
# Unit Tests
# ============================================================
test:
name: Tests (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov
pip install -r requirements.txt || true
- name: Build test fixtures
run: |
cd tests
bash build_fixtures.sh
- name: Run tests
run: |
pytest tests/ -v --tb=short
- name: Run tests with coverage
if: matrix.python-version == '3.11'
run: |
pytest tests/ --cov=. --cov-report=xml --cov-report=term-missing
- name: Upload coverage to Codecov
if: matrix.python-version == '3.11'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
fail_ci_if_error: false
# ============================================================
# Integration Test (with Ghidra)
# ============================================================
integration:
name: Integration Test (Ghidra)
runs-on: ubuntu-latest
# Run on all PRs and pushes to test Ghidra integration
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Download and setup Ghidra
run: |
wget -q https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_11.2.1_build/ghidra_11.2.1_PUBLIC_20241105.zip
unzip -q ghidra_11.2.1_PUBLIC_20241105.zip
mv ghidra_11.2.1_PUBLIC $HOME/ghidra
echo "GHIDRA_HOME=$HOME/ghidra" >> $GITHUB_ENV
- name: Build test fixtures
run: |
cd tests
bash build_fixtures.sh
- name: Test archive extraction
run: |
python -c "from libsurgeon import extract_archive; print('Import OK')"
- name: Test ELF detection
run: |
python -c "from libsurgeon import is_elf_file, get_file_type, FileType; assert get_file_type('test.elf') == FileType.ELF; print('ELF detection OK')"
- name: Test module strategies
run: |
python -c "from libsurgeon import MODULE_STRATEGIES; assert len(MODULE_STRATEGIES) == 4; print('Module strategies OK')"
- name: Test progress bar
run: |
python -c "from libsurgeon import draw_progress_bar; bar = draw_progress_bar(50, 100); assert len(bar) == 40; print('Progress bar OK')"
- name: Test quality evaluation
run: |
# Create a sample decompiled file
mkdir -p test_output
echo 'void test() { return; }' > test_output/sample.cpp
python evaluate_quality.py test_output/
- name: Test quality evaluation with C files
run: |
# Test that *.c* pattern works for both .c and .cpp
mkdir -p test_output_c
echo 'int foo(void) { return 42; }' > test_output_c/sample.c
echo 'void bar() { return; }' > test_output_c/sample.cpp
python evaluate_quality.py test_output_c/
- name: Test libsurgeon help
run: |
python libsurgeon.py --help
# Verify ELF module option exists
python libsurgeon.py --help | grep -q "\-m.*prefix\|alpha\|camelcase\|single"
- name: Test architecture detection
run: |
python -c "from libsurgeon import detect_elf_architecture, ELF_MACHINE_MAP; assert 0x28 in ELF_MACHINE_MAP, 'ARM should be in map'; assert 0x3E in ELF_MACHINE_MAP, 'x86-64 should be in map'; print('Architecture detection OK')"
- name: Test Ghidra decompilation of archive
run: |
# Test decompiling the test archive with Ghidra
python libsurgeon.py -g $HOME/ghidra tests/fixtures/libtest.a -o test_decompile_output --clean
# Verify output was generated
ls -la test_decompile_output/
test -d test_decompile_output/libtest/src
# Check that at least one .cpp file was created
cpp_count=$(find test_decompile_output/libtest/src -name "*.cpp" | wc -l)
echo "Generated $cpp_count .cpp files"
test $cpp_count -ge 1
- name: Test Ghidra decompilation with evaluation
run: |
# Test with --evaluate flag
python libsurgeon.py -g $HOME/ghidra tests/fixtures/libtest.a -o test_eval_output --evaluate --clean
# Verify quality report was generated
test -f test_eval_output/libtest/quality_report.json
cat test_eval_output/libtest/quality_report.json
- name: Test ELF file decompilation
run: |
# Test decompiling ELF executable
python libsurgeon.py -g $HOME/ghidra tests/fixtures/test_program.elf -o test_elf_output --clean
# Verify output
ls -la test_elf_output/
test -d test_elf_output/test_program/src
# ============================================================
# Documentation
# ============================================================
docs:
name: Documentation Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check README exists
run: |
test -f README.md
- name: Check LICENSE exists
run: |
test -f LICENSE