Skip to content

Commit 1fdf328

Browse files
authored
Compare unit tests using file content hashes (#75)
We can pass when a test case isn't found but not so important
2 parents 539c43c + f62c7af commit 1fdf328

File tree

4 files changed

+29
-30
lines changed

4 files changed

+29
-30
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ jobs:
1919
# build and test with multiple LLVM versions
2020
- run: docker build --build-arg LLVM_VERSION=${{ matrix.llvm_versions }} -t symqemu .
2121
- run: docker run -t symqemu make -C build check
22-
- run: docker run -t symqemu sh -c "cd tests/symqemu && python3 -m unittest test.py"
22+
- run: docker run -t symqemu sh -c "cd tests/symqemu && python3.11 -m unittest test.py"

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ GTAGS
2020
*.swp
2121
*.patch
2222
*.gcov
23+
24+
**/generated_outputs/

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ RUN apt update && apt install -y \
66
libglib2.0-dev \
77
llvm \
88
git \
9-
python3 \
9+
python3.11 \
1010
python3-pip \
1111
cmake \
1212
wget \

tests/symqemu/test.py

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import filecmp
21
import pathlib
32
import shutil
43
import unittest
54
import tempfile
65
import subprocess
76
import os
7+
import hashlib
88

99
import util
1010

@@ -19,33 +19,30 @@ def run_symqemu_and_assert_correct_result(self, binary_name):
1919

2020
util.run_symqemu_on_test_binary(binary_name=binary_name, generated_test_cases_output_dir=symqemu_gen_output_dir)
2121

22-
# `filecmp.dircmp` does a "shallow" comparison, but this is not a problem here because
23-
# the timestamps should always be different, so the actual content of the files will be compared.
24-
# See https://docs.python.org/3/library/filecmp.html#filecmp.dircmp
25-
expected_vs_actual_output_comparison = filecmp.dircmp(symqemu_gen_output_dir, symqemu_ref_output_dir)
26-
27-
for diff_file in expected_vs_actual_output_comparison.diff_files:
28-
ref_file = symqemu_ref_output_dir / diff_file
29-
gen_file = symqemu_gen_output_dir / diff_file
30-
31-
tmp_ref = tempfile.NamedTemporaryFile("w+")
32-
subprocess.run(["xxd", f"{ref_file}"], stdout=tmp_ref, check=True)
33-
34-
tmp_gen = tempfile.NamedTemporaryFile("w+")
35-
subprocess.run(["xxd", f"{gen_file}"], stdout=tmp_gen, check=True)
36-
37-
wdiff = subprocess.run(["wdiff", f"{tmp_ref.name}", f"{tmp_gen.name}"], capture_output=True)
38-
colordiff = subprocess.run(["colordiff"], input=wdiff.stdout, capture_output=True)
39-
40-
print(f"===== Diff found in {diff_file} ======")
41-
print(f"{colordiff.stdout.decode('utf-8').strip()}")
42-
print(f"=================================")
43-
print()
44-
45-
self.assertEqual(expected_vs_actual_output_comparison.diff_files, [])
46-
self.assertEqual(expected_vs_actual_output_comparison.left_only, [])
47-
self.assertEqual(expected_vs_actual_output_comparison.right_only, [])
48-
self.assertEqual(expected_vs_actual_output_comparison.funny_files, [])
22+
expected_hashes = {}
23+
for ref_file in symqemu_ref_output_dir.iterdir():
24+
with open(ref_file, 'rb', buffering=0) as f:
25+
f_hash = hashlib.file_digest(f, "sha256").hexdigest()
26+
expected_hashes[f_hash] = [False, ref_file]
27+
28+
testcase_not_found = False
29+
for gen_file in symqemu_gen_output_dir.iterdir():
30+
with open(gen_file, 'rb', buffering=0) as f:
31+
f_hash = hashlib.file_digest(f, "sha256").hexdigest()
32+
ret = expected_hashes.get(f_hash)
33+
if ret is not None:
34+
ret[0] = True
35+
expected_hashes[f_hash] = ret
36+
else:
37+
print(f"Error: content of file {gen_file} not found in expected testcases.");
38+
testcase_not_found = True
39+
40+
for (is_found, fname) in expected_hashes.values():
41+
# (is_found, fname) = tuple(ret)
42+
if not is_found:
43+
print(f"Warning: expected testcase {fname} has not been generated.")
44+
45+
self.assertFalse(testcase_not_found)
4946

5047
def test_simple(self):
5148
self.run_symqemu_and_assert_correct_result('simple')

0 commit comments

Comments
 (0)