forked from Cisco-Talos/clamav-bytecode-compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds testcase.py, derived from the one used in the clamav tests. Adds feature to find a clamav installation when the tests are enabled. It looks for ClamScan, SigTool, ClamBC, and the ClamBC Headers. The above applications will be useful in future tests to validate that the compiled signatures are correct. The ClamBC Headers will be required to compile signatures when running the test suite in the future when the ClamAV installation includes clambc generated headers (anticipated for 0.104.0), and when this project drops those headers. We presently carry those headers for 0.103.1. Adds a `--version` option to clambc-compiler.py, though it is presently hardcoded to 0.103.1. In the future, it should get the version from libclambcc.so if possible, which inherits that value from the project settings at the top of the main CMakeLists.txt file. Modified clambc-compiler.py so it will use LD_LIBRARY_PATH to find libclambcc.so if it can't find it in `../lib`. Added clamav to the Dockerfile builder image so we can run ctest, but since ctest currently fails some tests, it is set to ignore failures.
- Loading branch information
Showing
9 changed files
with
1,271 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ CTestTestfile.cmake | |
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
.pytest_cache | ||
|
||
# Ninja | ||
.ninja_deps | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# | ||
# Find the ClamAV programs and headers needed for the test suite. | ||
# | ||
# If found, will set: | ||
# ClamAV_FOUND, ClamAV_VERSION, and | ||
# - clamscan_EXECUTABLE | ||
# - clambc_EXECUTABLE | ||
# - sigtool_EXECUTABLE | ||
# - clambc_headers_DIRECTORY | ||
# | ||
# If you have a custom install location for ClamAV, you can provide a hint | ||
# by settings -DClamAV_HOME=<clamav install prefix> | ||
# | ||
|
||
find_program(clamscan_EXECUTABLE | ||
NAMES clamscan clamscan.exe | ||
HINTS "${ClamAV_HOME}" | ||
PATH_SUFFIXES "bin" | ||
) | ||
if(NOT clamscan_EXECUTABLE AND NOT ClamAV_FIND_QUIETLY) | ||
message("Unable to find clamscan") | ||
endif() | ||
|
||
find_program(clambc_EXECUTABLE | ||
NAMES clambc clambc.exe | ||
HINTS "${ClamAV_HOME}" | ||
PATH_SUFFIXES "bin" | ||
) | ||
if(NOT clambc_EXECUTABLE_EXECUTABLE AND NOT ClamAV_FIND_QUIETLY) | ||
message("Unable to find clambc") | ||
endif() | ||
|
||
find_program(sigtool_EXECUTABLE | ||
NAMES sigtool sigtool.exe | ||
HINTS "${ClamAV_HOME}" | ||
PATH_SUFFIXES "bin" | ||
) | ||
if(NOT sigtool_EXECUTABLE AND NOT ClamAV_FIND_QUIETLY) | ||
message("Unable to find sigtool") | ||
endif() | ||
|
||
if(clamscan_EXECUTABLE AND clambc_EXECUTABLE AND sigtool_EXECUTABLE) | ||
execute_process(COMMAND "${clamscan_EXECUTABLE}" --version | ||
OUTPUT_VARIABLE ClamAV_VERSION_OUTPUT | ||
ERROR_VARIABLE ClamAV_VERSION_ERROR | ||
RESULT_VARIABLE ClamAV_VERSION_RESULT | ||
) | ||
if(NOT ${ClamAV_VERSION_RESULT} EQUAL 0) | ||
if(NOT ClamAV_FIND_QUIETLY) | ||
message(STATUS "ClamAV not found: Failed to determine version.") | ||
endif() | ||
unset(clamscan_EXECUTABLE) | ||
else() | ||
string(REGEX | ||
MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?(-devel)?" | ||
ClamAV_VERSION "${ClamAV_VERSION_OUTPUT}" | ||
) | ||
set(ClamAV_VERSION "${ClamAV_VERSION}") | ||
set(ClamAV_FOUND 1) | ||
|
||
# Look for the clambc-headers. E.g.: <clamav prefix>/lib/clambc-headers/0.104.0 | ||
# | ||
# In the future, the clamav-derived headers for compiling signatures will be | ||
# installed with clamav, and this path will be necessary to find them for running | ||
# the test suite. | ||
find_file(clambc_headers_DIRECTORY | ||
clambc-headers/${ClamAV_VERSION} | ||
HINTS "${ClamAV_HOME}" | ||
PATH_SUFFIXES "lib" | ||
) | ||
|
||
if(NOT ClamAV_FIND_QUIETLY) | ||
message(STATUS "ClamAV found: ${ClamAV_VERSION}") | ||
message(STATUS " clamscan: ${clamscan_EXECUTABLE}") | ||
message(STATUS " clambc: ${clambc_EXECUTABLE}") | ||
message(STATUS " sigtool: ${sigtool_EXECUTABLE}") | ||
message(STATUS " bc headers: ${clambc_headers_DIRECTORY}") | ||
endif() | ||
|
||
if(NOT clambc_headers_DIRECTORY) | ||
set(clambc_headers_DIRECTORY "") | ||
endif() | ||
endif() | ||
|
||
mark_as_advanced(clamscan_EXECUTABLE clambc_EXECUTABLE sigtool_EXECUTABLE ClamAV_VERSION) | ||
else() | ||
if(ClamAV_FIND_REQUIRED) | ||
message(FATAL_ERROR "ClamAV not found.") | ||
else() | ||
if(NOT ClamAV_FIND_QUIETLY) | ||
message(STATUS "${_msg}") | ||
endif() | ||
endif() | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | ||
|
||
""" | ||
The tests in this file check that clambcc is able to compile the example | ||
bytecode signatures. | ||
""" | ||
|
||
import os | ||
from pathlib import Path | ||
import platform | ||
import shutil | ||
import subprocess | ||
import sys | ||
import time | ||
import unittest | ||
|
||
import testcase | ||
|
||
|
||
os_platform = platform.platform() | ||
operating_system = os_platform.split('-')[0].lower() | ||
|
||
|
||
class TC(testcase.TestCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
super(TC, cls).setUpClass() | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
super(TC, cls).tearDownClass() | ||
|
||
def setUp(self): | ||
super(TC, self).setUp() | ||
|
||
def tearDown(self): | ||
super(TC, self).tearDown() | ||
self.verify_valgrind_log() | ||
|
||
@unittest.expectedFailure | ||
def test_00_version(self): | ||
self.step_name('clambcc version test') | ||
|
||
command = '{clambcc} -V'.format( | ||
clambcc=TC.clambcc | ||
) | ||
output = self.execute_command(command) | ||
|
||
assert output.ec == 0 # success | ||
|
||
expected_results = [ | ||
'ClamBC-Compiler {}'.format(TC.version), | ||
] | ||
self.verify_output(output.out, expected=expected_results) | ||
|
||
def test_01_compile_all_o0_examples(self): | ||
self.step_name('Test that clambcc can compile a basic signature') | ||
|
||
testpaths = list((TC.path_source / 'test' / 'examples' / 'in').glob('*.o0.c')) # A list of Path()'s of each of our generated test files | ||
|
||
testfiles = ' '.join([str(testpath) for testpath in testpaths]) | ||
for testfile in testpaths: | ||
|
||
outfile = (TC.path_tmp / testfile.name).with_suffix('.cbc') | ||
|
||
command = '{clambcc} -O0 {testfile} -o {outfile} {headers}'.format( | ||
clambcc=TC.clambcc, | ||
testfile=testfile, | ||
outfile=outfile, | ||
headers=TC.headers | ||
) | ||
output = self.execute_command(command) | ||
|
||
expected_results = [] | ||
unexpected_results = ["error: "] | ||
self.verify_output(output.err, expected=expected_results, unexpected=unexpected_results) | ||
|
||
assert output.ec == 0 | ||
assert outfile.exists() | ||
|
||
def test_01_compile_all_o1_examples(self): | ||
self.step_name('Test that clambcc can compile a basic signature') | ||
|
||
testpaths = list((TC.path_source / 'test' / 'examples' / 'in').glob('*.o1.c')) # A list of Path()'s of each of our generated test files | ||
|
||
testfiles = ' '.join([str(testpath) for testpath in testpaths]) | ||
for testfile in testpaths: | ||
|
||
outfile = (TC.path_tmp / testfile.name).with_suffix('.cbc') | ||
|
||
command = '{clambcc} -O1 {testfile} -o {outfile} {headers}'.format( | ||
clambcc=TC.clambcc, | ||
testfile=testfile, | ||
outfile=outfile, | ||
headers=TC.headers | ||
) | ||
output = self.execute_command(command) | ||
|
||
expected_results = [] | ||
unexpected_results = ["error: "] | ||
self.verify_output(output.err, expected=expected_results, unexpected=unexpected_results) | ||
|
||
assert output.ec == 0 | ||
assert outfile.exists() | ||
|
||
def test_01_compile_all_o2_examples(self): | ||
self.step_name('Test that clambcc can compile a basic signature') | ||
|
||
testpaths = list((TC.path_source / 'test' / 'examples' / 'in').glob('*.o2.c')) # A list of Path()'s of each of our generated test files | ||
|
||
testfiles = ' '.join([str(testpath) for testpath in testpaths]) | ||
for testfile in testpaths: | ||
|
||
outfile = (TC.path_tmp / testfile.name).with_suffix('.cbc') | ||
|
||
command = '{clambcc} -O2 {testfile} -o {outfile} {headers}'.format( | ||
clambcc=TC.clambcc, | ||
testfile=testfile, | ||
outfile=outfile, | ||
headers=TC.headers | ||
) | ||
output = self.execute_command(command) | ||
|
||
expected_results = [] | ||
unexpected_results = ["error: "] | ||
self.verify_output(output.err, expected=expected_results, unexpected=unexpected_results) | ||
|
||
assert output.ec == 0 | ||
assert outfile.exists() |
Oops, something went wrong.