From 908324fde43fd66e6eb79a2830ed686bdfb42d43 Mon Sep 17 00:00:00 2001 From: Micah Snyder Date: Wed, 12 Apr 2023 22:42:31 -0700 Subject: [PATCH] Tests: Add sigtool tests for correct CDIFF UNLINK functionality Also includes: - A sigtool test to verify that Rust log macros are working. - Changing the freshclam tests to use --no-dns so they run faster when DNS isn't working (e.g. no internet). --- unit_tests/freshclam_test.py | 34 ++++++++-------- unit_tests/sigtool_test.py | 78 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 17 deletions(-) diff --git a/unit_tests/freshclam_test.py b/unit_tests/freshclam_test.py index 31e3776be..ae5b9b8a2 100644 --- a/unit_tests/freshclam_test.py +++ b/unit_tests/freshclam_test.py @@ -87,7 +87,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} -V'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} -V'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -133,7 +133,7 @@ class TC(testcase.TestCase): user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config}'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config}'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -174,7 +174,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=daily'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=daily'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -189,7 +189,7 @@ class TC(testcase.TestCase): # verify stderr self.verify_output(output.err, expected=expected_stderr) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=daily'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=daily'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -229,7 +229,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=daily --daemon -F'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=daily --daemon -F'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -269,7 +269,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=daily'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=daily'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -322,7 +322,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -384,7 +384,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -440,7 +440,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -465,7 +465,7 @@ class TC(testcase.TestCase): # # Try again, we should be 1 behind which is tolerable and should not trigger a full CVD download # - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -526,7 +526,7 @@ class TC(testcase.TestCase): port=TC.mock_mirror_port, user=getpass.getuser(), )) - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -551,7 +551,7 @@ class TC(testcase.TestCase): # # Try again, we should be 2 behind which is NOT tolerable and SHOULD trigger a full CVD download # - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -617,7 +617,7 @@ class TC(testcase.TestCase): # # 1st attempt # - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -637,7 +637,7 @@ class TC(testcase.TestCase): # # 2nd attempt # - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -663,7 +663,7 @@ class TC(testcase.TestCase): # # 3rd attempt # - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -724,7 +724,7 @@ class TC(testcase.TestCase): # # Now run the update for the first set up updates. # - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) @@ -755,7 +755,7 @@ class TC(testcase.TestCase): # # Now re-run the update for more updates. # - command = '{valgrind} {valgrind_args} {freshclam} --config-file={freshclam_config} --update-db=test'.format( + command = '{valgrind} {valgrind_args} {freshclam} --no-dns --config-file={freshclam_config} --update-db=test'.format( valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, freshclam=TC.freshclam, freshclam_config=TC.freshclam_config ) output = self.execute_command(command) diff --git a/unit_tests/sigtool_test.py b/unit_tests/sigtool_test.py index 63a512537..3da0aba36 100644 --- a/unit_tests/sigtool_test.py +++ b/unit_tests/sigtool_test.py @@ -58,11 +58,13 @@ class TC(testcase.TestCase): super(TC, cls).tearDownClass() def setUp(self): + TC.original_cwd = os.getcwd() super(TC, self).setUp() def tearDown(self): super(TC, self).tearDown() self.verify_valgrind_log() + os.chdir(TC.original_cwd) def test_sigtool_00_version(self): self.step_name('sigtool version test') @@ -79,3 +81,79 @@ class TC(testcase.TestCase): 'ClamAV {}'.format(TC.version), ] self.verify_output(output.out, expected=expected_results) + + def test_sigtool_01_run_cdiff(self): + self.step_name('sigtool run cdiff test') + # In addition to testing that running a cdiff works, this also tests a regression. + # Applying test-3.cdiff was failing because UNLINK wasn't properly implemented (since 0.105.0). + # We didn't notice it because logging wasn't enabled, and leniency in our freshclam cdiff process + # allowed the test to pass without noticing the bug. + + self.log.warning('VG: {}'.format(os.getenv("VG"))) + + (TC.path_tmp / 'run_cdiff').mkdir() + os.chdir(TC.path_tmp / 'run_cdiff') + + command = '{valgrind} {valgrind_args} {sigtool} --unpack {cvd}'.format( + valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, sigtool=TC.sigtool, + cvd=TC.path_source / 'unit_tests' / 'input' / 'freshclam_testfiles' / 'test-1.cvd' + ) + output = self.execute_command(command) + + assert output.ec == 0 # success + + # Apply 1st cdiff. + + command = '{valgrind} {valgrind_args} {sigtool} --run-cdiff={cdiff}'.format( + valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, sigtool=TC.sigtool, + cdiff=TC.path_source / 'unit_tests' / 'input' / 'freshclam_testfiles' / 'test-2.cdiff' + ) + output = self.execute_command(command) + + # Apply 2nd cdiff. This one failed because the CLOSE operation should create a file + # if it didn't exist, and it was only appending but not creating. + + command = '{valgrind} {valgrind_args} {sigtool} --run-cdiff={cdiff}'.format( + valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, sigtool=TC.sigtool, + cdiff=TC.path_source / 'unit_tests' / 'input' / 'freshclam_testfiles' / 'test-3.cdiff' + ) + output = self.execute_command(command) + + assert output.ec == 0 # success + + def test_sigtool_02_rust_logs_messages_work(self): + self.step_name('sigtool test rust log macros work') + # In addition to testing that running a cdiff works, this also tests a regression. + # Applying test-3.cdiff was failing because UNLINK wasn't properly implemented (since 0.105.0). + # We didn't notice it because logging wasn't enabled, and leniency in our freshclam cdiff process + # allowed the test to pass without noticing the bug. + + self.log.warning('VG: {}'.format(os.getenv("VG"))) + + (TC.path_tmp / 'run_cdiff_log').mkdir() + os.chdir(TC.path_tmp / 'run_cdiff_log') + + command = '{valgrind} {valgrind_args} {sigtool} --unpack {cvd}'.format( + valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, sigtool=TC.sigtool, + cvd=TC.path_source / 'unit_tests' / 'input' / 'freshclam_testfiles' / 'test-1.cvd' + ) + output = self.execute_command(command) + + assert output.ec == 0 # success + + # Apply cdiffs in wrong order. Should fail and print a message. + + command = '{valgrind} {valgrind_args} {sigtool} --run-cdiff={cdiff}'.format( + valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, sigtool=TC.sigtool, + cdiff=TC.path_source / 'unit_tests' / 'input' / 'freshclam_testfiles' / 'test-3.cdiff' + ) + output = self.execute_command(command) + + assert output.ec == 1 # failure + + # Verify that the `error!()` message was printed to stderr. + # This didn't happen before when we didn't initialize the rust logging lib at the top of sigtool. + expected_results = [ + 'LibClamAV Error', + ] + self.verify_output(output.err, expected=expected_results)