def test_check_tables_raises_on_uninstalled(self): # type: () -> None ( self.mock_callable(rpmutil, "run_with_timeout") .for_call( [self.rpm_path, "--dbpath", self.dbpath, "-qa", "--qf", "%{NAME}\\n"], timeout=rpmutil.RPM_CHECK_TIMEOUT_SEC, exception_to_raise=DBNeedsRebuild, ) .to_return_value(CompletedProcess(returncode=0, stdout="foo\nbaz\nfoo")) .and_assert_called_once() ) ( self.mock_callable(rpmutil, "run_with_timeout") .for_call( [self.rpm_path, "--dbpath", self.dbpath, "-q", "baz", "foo"], timeout=rpmutil.RPM_CHECK_TIMEOUT_SEC, exception_to_raise=DBNeedsRebuild, ) .to_return_value( CompletedProcess(returncode=0, stdout="baz is not installed\nfoo") ) .and_assert_called_once() ) with self.assertRaises(DBNeedsRebuild): self.rpmutil.check_tables()
def test_verify_tables_success(self): # type: () -> None # Not blacklisted tables (self.mock_callable(rpmutil, "run_with_timeout").for_call( "%s /var/lib/rpm/table0" % self.verify_path, rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ).to_return_value(CompletedProcess()).and_assert_called_once()) (self.mock_callable(rpmutil, "run_with_timeout").for_call( "%s /var/lib/rpm/table3" % self.verify_path, rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ).to_return_value(CompletedProcess()).and_assert_called_once()) self.rpmutil.verify_tables()
def test__pids_holding_file_success(self): # type: () -> None (self.mock_callable(pidutil, "run_with_timeout").to_return_value( CompletedProcess(stdout="\n".join( ["p12345", "f1", "p123456", "f1"]))).and_assert_called_once) self.assertEqual(set([12345, 123456]), pidutil._pids_holding_file("/path/to/lsof", "/tmp/a"))
def test__pids_holding_file_failed(self): # type: () -> None (self.mock_callable(pidutil, "run_with_timeout").to_return_value( CompletedProcess(returncode=1, stderr="oh no")).and_assert_called_once) self.assertFalse( pidutil._pids_holding_file("/path/to/lsof", "/tmp/foo"))
def test_check_rpm_qa_success(self): # type: () -> None self.mock_callable(rpmutil, "run_with_timeout").to_return_value( CompletedProcess(stdout="\n".join([ "rpm{}".format(i) for i in range(rpmutil.MIN_ACCEPTABLE_PKG_COUNT) ]))).and_assert_called_once() self.rpmutil.check_rpm_qa()
def test_clean_yum_transactions_success(self): # type: () -> None ( self.mock_callable(rpmutil, "run_with_timeout") .to_return_value(CompletedProcess(returncode=0)) .and_assert_called_once() ) self.rpmutil.clean_yum_transactions()
def test_check_tables_(self): # type: () -> None ( self.mock_callable(rpmutil, "run_with_timeout") .to_return_value(CompletedProcess(returncode=0, stdout="")) .and_assert_called_once() ) self.rpmutil.check_tables()
def test_rebuild_db_success(self): # type: () -> None ( self.mock_callable(rpmutil, "run_with_timeout") .to_return_value(CompletedProcess()) .and_assert_called_once() ) self.rpmutil.rebuild_db()
def test_query_success(self): # type: () -> None (self.mock_callable(rpmutil, "run_with_timeout").for_call( self.rpm_path + " --dbpath " + self.dbpath + " -q foo", rpmutil.RPM_CHECK_TIMEOUT_SEC, ).to_return_value( CompletedProcess(stdout="\n".join( ["foo-4.13.0-1.el7.centos.x86_64"]))).and_assert_called_once()) self.rpmutil.query("foo")
def test_verify_tables_fail(self): # type: () -> None (self.mock_callable(rpmutil, "run_with_timeout").for_call( "%s %s/table0" % (self.verify_path, self.dbpath), rpmutil.RPM_CHECK_TIMEOUT_SEC, raise_on_nonzero=False, ).to_return_value( CompletedProcess(returncode=1)).and_assert_called_once()) with self.assertRaises(DcRPMException): self.rpmutil.verify_tables()
def test_check_rpm_qa_not_enough_packages_linux(self): # type: () -> None (self.mock_callable(rpmutil, "run_with_timeout").to_return_value( CompletedProcess(stdout="\n".join(["rpm%s" % i for i in range(5) ]))).and_assert_called_once()) (self.mock_callable( platform, "system").to_return_value("Linux").and_assert_called_once()) with self.assertRaises(DBNeedsRecovery): self.rpmutil.check_rpm_qa()
def test_query_failure(self): # type: () -> None (self.mock_callable(rpmutil, "run_with_timeout").for_call( self.rpm_path + " --dbpath " + self.dbpath + " -q foo", rpmutil.RPM_CHECK_TIMEOUT_SEC, ).to_return_value( CompletedProcess( stdout="\n".join(["perl-File-Path-2.09-2.el7.noarch" ]))).and_assert_called_once()) with self.assertRaises(DBNeedsRebuild): self.rpmutil.query("foo")
def test_check_rpm_qa_not_enough_packages_darwin(self): # type: () -> None (self.mock_callable(rpmutil, "run_with_timeout").to_return_value( CompletedProcess(stdout="\n".join(["rpm%s" % i for i in range(5) ]))).and_assert_called_once()) (self.mock_callable( platform, "system").to_return_value("Darwin").and_assert_called_once()) try: self.rpmutil.check_rpm_qa() except DBNeedsRecovery: self.fail("Package count check should be bypassed on macOS")
def test_check_tables_success_on_no_rpms(self): # type: () -> None (self.mock_callable(rpmutil, "run_with_timeout").for_call( [ self.rpm_path, "--dbpath", self.dbpath, "-qa", "--qf", "%{NAME}\\n" ], timeout=rpmutil.RPM_CHECK_TIMEOUT_SEC, exception_to_raise=DBNeedsRebuild, ).to_return_value(CompletedProcess( returncode=0, stdout="")).and_assert_called_once()) self.rpmutil.check_tables()
class TestRPMUtil(unittest.TestCase): def setUp(self): self.rpmpath = rpmutil.RPM_PATH self.dbpath = '/var/lib/rpm' self.recover_path = '/opt/yum/bin/db48_recover' self.verify_path = '/opt/yum/bin/db48_verify' self.yum_complete_transaction_path = \ '/opt/yum/bin/yum-complete-transaction' self.blacklist = [ 'table1', 'table2', ] self.rpmutil = rpmutil.RPMUtil( dbpath=self.dbpath, recover_path=self.recover_path, verify_path=self.verify_path, yum_complete_transaction_path=self.yum_complete_transaction_path, blacklist=self.blacklist, ) self.rpmutil.tables = [ '/var/lib/rpm/table0', '/var/lib/rpm/table1', '/var/lib/rpm/table2', '/var/lib/rpm/table3', ] # check_rpm_qa @patch(run_str, return_value=CompletedProcess(stdout='\n'.join([ 'rpm{}'.format(i) for i in range(rpmutil.MIN_ACCEPTABLE_PKG_COUNT) ]), )) def test_check_rpm_qa_success(self, mock_run): self.rpmutil.check_rpm_qa() self.assertIn('{} --dbpath {} -qa'.format(self.rpmpath, self.dbpath), mock_run.call_args[0]) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() @patch(run_str, return_value=CompletedProcess(stdout='\n'.join( ['rpm{}'.format(i) for i in range(5)]), )) def test_check_rpm_qa_not_enough_packages(self, mock_run): with self.assertRaises(DBNeedsRecovery): self.rpmutil.check_rpm_qa() self.assertIn('{} --dbpath {} -qa'.format(self.rpmpath, self.dbpath), mock_run.call_args[0]) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() @patch(run_str, return_value=CompletedProcess(returncode=1)) def test_check_rpm_qa_raise_on_nonzero_rc(self, mock_run): with self.assertRaises(DBNeedsRecovery): self.rpmutil.check_rpm_qa() self.assertIn('{} --dbpath {} -qa'.format(self.rpmpath, self.dbpath), mock_run.call_args[0]) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() # recover_db @patch(run_str, return_value=CompletedProcess()) def test_recover_db_success(self, mock_run): self.rpmutil.recover_db() self.assertIn('{} -h {}'.format(self.recover_path, self.dbpath), mock_run.call_args[0]) self.assertIn(rpmutil.RECOVER_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() # rebuild_db @patch(run_str, return_value=CompletedProcess()) def test_rebuild_db_success(self, mock_run): self.rpmutil.rebuild_db() self.assertIn( '{} --dbpath {} --rebuilddb'.format(rpmutil.RPM_PATH, self.dbpath), mock_run.call_args[0]) self.assertIn(rpmutil.REBUILD_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() # check_tables @patch(run_str, return_value=CompletedProcess(returncode=1)) def test_check_tables_success(self, mock_run): self.rpmutil.check_tables() # verify_tables @patch(run_str, side_effect=2 * [CompletedProcess()]) def test_verify_tables_success(self, mock_run): self.rpmutil.verify_tables() self.assertEqual(mock_run.call_count, 2) mock_run.assert_has_calls([ call( '{} {}/table0'.format(self.verify_path, self.dbpath), rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ), call( '{} {}/table3'.format(self.verify_path, self.dbpath), rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ), ]) @patch(run_str) def test_verify_tables_all_blacklisted(self, mock_run): self.rpmutil.tables = self.rpmutil.tables[1:3] self.rpmutil.verify_tables() mock_run.assert_not_called() @patch(run_str, side_effect=2 * [CompletedProcess(returncode=1)]) def test_verify_tables_fail(self, mock_run): with self.assertRaises(DcRPMException): self.rpmutil.verify_tables() mock_run.assert_called_once_with( '{} {}/table0'.format(self.verify_path, self.dbpath), rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ) # clean_yum_transactions @patch(run_str, return_value=CompletedProcess(returncode=0)) def test_clean_yum_transactions_success(self, mock_run): self.rpmutil.clean_yum_transactions() self.assertIn( '{} --cleanup'.format(self.yum_complete_transaction_path), mock_run.call_args[0]) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once()
class TestRPMUtil(unittest.TestCase): def setUp(self): self.rpm_path = "/usr/bin/rpm" self.dbpath = "/var/lib/rpm" self.recover_path = "/usr/bin/db_recover" self.verify_path = "/usr/bin/db_verify" self.stat_path = "/usr/bin/db_stat" self.yum_complete_transaction_path = "/usr/bin/yum-complete-transaction" self.blacklist = ["table1", "table2"] self.forensic = (False, ) self.rpmutil = rpmutil.RPMUtil( dbpath=self.dbpath, rpm_path=self.rpm_path, recover_path=self.recover_path, verify_path=self.verify_path, stat_path=self.stat_path, yum_complete_transaction_path=self.yum_complete_transaction_path, blacklist=self.blacklist, forensic=self.forensic, ) self.rpmutil.tables = [ "/var/lib/rpm/table0", "/var/lib/rpm/table1", "/var/lib/rpm/table2", "/var/lib/rpm/table3", ] # query @patch( run_str, return_value=CompletedProcess( stdout="\n".join(["foo-4.13.0-1.el7.centos.x86_64"])), ) def test_query_success(self, mock_run): test_rpm_name = "foo" self.rpmutil.query("foo") self.assertIn( "{} --dbpath {} -q {}".format(self.rpm_path, self.dbpath, test_rpm_name), mock_run.call_args[0], ) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() @patch( run_str, return_value=CompletedProcess( stdout="\n".join(["perl-File-Path-2.09-2.el7.noarch"])), ) def test_query_failure(self, mock_run): with self.assertRaises(DBNeedsRebuild): self.rpmutil.query("foo") # check_rpm_qa @patch( run_str, return_value=CompletedProcess(stdout="\n".join([ "rpm{}".format(i) for i in range(rpmutil.MIN_ACCEPTABLE_PKG_COUNT) ])), ) def test_check_rpm_qa_success(self, mock_run): self.rpmutil.check_rpm_qa() self.assertIn( "{} --dbpath {} -qa".format(self.rpm_path, self.dbpath), mock_run.call_args[0], ) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() @patch( run_str, return_value=CompletedProcess( stdout="\n".join(["rpm{}".format(i) for i in range(5)])), ) def test_check_rpm_qa_not_enough_packages(self, mock_run): with self.assertRaises(DBNeedsRecovery): self.rpmutil.check_rpm_qa() self.assertIn( "{} --dbpath {} -qa".format(self.rpm_path, self.dbpath), mock_run.call_args[0], ) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() @patch(run_str, return_value=CompletedProcess(returncode=1)) def test_check_rpm_qa_raise_on_nonzero_rc(self, mock_run): with self.assertRaises(DBNeedsRecovery): self.rpmutil.check_rpm_qa() self.assertIn( "{} --dbpath {} -qa".format(self.rpm_path, self.dbpath), mock_run.call_args[0], ) self.assertIn(rpmutil.RPM_CHECK_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() # recover_db @patch(run_str, return_value=CompletedProcess()) def test_recover_db_success(self, mock_run): self.rpmutil.recover_db() self.assertIn("{} -h {}".format(self.recover_path, self.dbpath), mock_run.call_args[0]) self.assertIn(rpmutil.RECOVER_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() # rebuild_db @patch(run_str, return_value=CompletedProcess()) def test_rebuild_db_success(self, mock_run): self.rpmutil.rebuild_db() self.assertIn( "{} --dbpath {} --rebuilddb".format(self.rpm_path, self.dbpath), mock_run.call_args[0], ) self.assertIn(rpmutil.REBUILD_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() # check_tables @patch(run_str, return_value=CompletedProcess(returncode=1)) def test_check_tables_success(self, mock_run): self.rpmutil.check_tables() # verify_tables @patch(run_str, side_effect=2 * [CompletedProcess()]) def test_verify_tables_success(self, mock_run): self.rpmutil.verify_tables() self.assertEqual(mock_run.call_count, 2) mock_run.assert_has_calls([ call( "{} {}/table0".format(self.verify_path, self.dbpath), rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ), call( "{} {}/table3".format(self.verify_path, self.dbpath), rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ), ]) @patch(run_str) def test_verify_tables_all_blacklisted(self, mock_run): self.rpmutil.tables = self.rpmutil.tables[1:3] self.rpmutil.verify_tables() self.assertEqual(mock_run.call_count, 0) @patch(run_str, side_effect=2 * [CompletedProcess(returncode=1)]) def test_verify_tables_fail(self, mock_run): with self.assertRaises(DcRPMException): self.rpmutil.verify_tables() mock_run.assert_called_once_with( "{} {}/table0".format(self.verify_path, self.dbpath), rpmutil.VERIFY_TIMEOUT_SEC, raise_on_nonzero=False, ) # clean_yum_transactions @patch(run_str, return_value=CompletedProcess(returncode=0)) def test_clean_yum_transactions_success(self, mock_run): self.rpmutil.clean_yum_transactions() self.assertIn( "{} --cleanup".format(self.yum_complete_transaction_path), mock_run.call_args[0], ) self.assertIn(rpmutil.YUM_COMPLETE_TIMEOUT_SEC, mock_run.call_args[0]) mock_run.assert_called_once() # kill_spinning_rpm_query_processes @patch("psutil.process_iter") @patch("time.time") def test_kill_spinning_rpm_query_processes_success(self, mock_time, mock_iter): mock_time.return_value = 10000 young_rpm = make_mock_process(123, cmdline="rpm -q foo-124.x86_64", create_time=9000) young_non_rpm = make_mock_process(456, cmdline="java foobar", create_time=8000) young_non_rpm2 = make_mock_process(789, cmdline="ps aux", create_time=8000) old_bin_rpm = make_mock_process(111, cmdline="/bin/rpm -q bar-456.x86_64", create_time=3000) old_usr_bin_rpm = make_mock_process( 222, cmdline="/usr/bin/rpm -something -q bar-456.x86_64", create_time=2000) old_usr_bin_rpm_wait_throw = make_mock_process( 222, cmdline="/usr/bin/rpm -q bar-456.x86_64", create_time=1000, wait_throw=True, ) old_usr_bin_rpm_cmdline_throw = make_mock_process( 222, cmdline="/usr/bin/rpm -q bar-456.x86_64", create_time=4000, cmdline_throw=True, ) young_bin_rpm = make_mock_process(333, cmdline="/bin/rpm -q bar-788.x86_64", create_time=9000) mock_iter.return_value = [ young_rpm, young_non_rpm, young_non_rpm2, old_bin_rpm, old_usr_bin_rpm, old_usr_bin_rpm_wait_throw, old_usr_bin_rpm_cmdline_throw, young_bin_rpm, ] self.rpmutil.kill_spinning_rpm_query_processes() assert_called_like(young_rpm, { "create_time": True, "send_signal": False, "wait": False }) assert_called_like(young_non_rpm, { "create_time": False, "send_signal": False, "wait": False }) assert_called_like(young_non_rpm2, { "create_time": False, "send_signal": False, "wait": False }) assert_called_like(old_bin_rpm, { "create_time": True, "send_signal": True, "wait": True }) assert_called_like(old_usr_bin_rpm, { "create_time": True, "send_signal": True, "wait": True }) assert_called_like( old_usr_bin_rpm_wait_throw, { "create_time": True, "send_signal": True, "wait": True }, ) assert_called_like( old_usr_bin_rpm_cmdline_throw, { "create_time": False, "send_signal": False, "wait": False }, ) assert_called_like(young_bin_rpm, { "create_time": True, "send_signal": False, "wait": False })