import unittest from configparser import NoSectionError, DuplicateOptionError, DuplicateSectionError from tests.unit_tests.utils.update_settings import UpdateSettings from tests.unit_tests.utils.dummy_documents_generate import DummyDocumentsGenerate from helpers.outlier import Outlier from helpers.singletons import settings from helpers.settings import print_failed_configs_and_exit as print_failed_configs_and_exit test_whitelist_single_literal_file = "/app/tests/unit_tests/files/whitelist_tests_03_with_general.conf" test_whitelist_multiple_literal_file = "/app/tests/unit_tests/files/whitelist_tests_01_with_general.conf" test_whitelist_duplicate_option_file = "/app/tests/unit_tests/files/whitelist_tests_duplicate_keys.conf" test_whitelist_duplicate_section_file = "/app/tests/unit_tests/files/whitelist_tests_duplicate_section.conf" test_config_without_whitelist_file = "/app/tests/unit_tests/files/config_without_whitelist_tests.conf" test_config_without_whitelist_literals_file = "/app/tests/unit_tests/files/config_without_whitelist_literals.conf" test_config_without_whitelist_regexps_file = "/app/tests/unit_tests/files/config_without_whitelist_regexps.conf" test_config_that_does_not_exist = "/app/tests/unit_tests/files/this_file_does_not_exist.conf" test_config_that_is_a_directory = "/app/tests/unit_tests/files/" class TestSettings(unittest.TestCase): def setUp(self): import logging as base_logging base_logging.disable(base_logging.CRITICAL) self.test_settings = UpdateSettings() def tearDown(self): import logging as base_logging base_logging.disable(base_logging.NOTSET) self.test_settings.restore_default_configuration_path() def test_whitelist_correctly_reload_after_update_config(self): self.test_settings.change_configuration_path(test_whitelist_single_literal_file) dummy_doc_gen = DummyDocumentsGenerate() doc = dummy_doc_gen.generate_document({"create_outlier": True, "outlier_observation": "dummy observation", "filename": "osquery_get_all_processes_with_listening_conns.log"}) # With this configuration, outlier is not whitlisted self.assertFalse(Outlier.is_whitelisted_doc(doc)) # Update configuration self.test_settings.change_configuration_path(test_whitelist_multiple_literal_file) # Now outlier is whitelisted self.assertTrue(Outlier.is_whitelisted_doc(doc)) def test_duplicate_whitelist_keys_not_crash(self): self.test_settings.change_configuration_path(test_whitelist_duplicate_option_file) self.assertEqual(settings.config.get("whitelist_literals", "single_key"), "dummy_whitelist_item_two") def test_no_error_when_forgot_whitelist_config(self): # with self.assertRaises(NoSectionError): try: self.test_settings.change_configuration_path(test_config_without_whitelist_file) except Exception as ex: self.fail("configuration file that does not contain whitelist raised the exception: %s" % ex) def test_no_error_when_forgot_whitelist_literals_config(self): # with self.assertRaises(NoSectionError): try: self.test_settings.change_configuration_path(test_config_without_whitelist_literals_file) except Exception as ex: self.fail("configuration file that does not contain whitelist_literals raised the exception: %s" % ex) def test_no_error_when_forgot_whitelist_regexps_config(self): # with self.assertRaises(NoSectionError): try: self.test_settings.change_configuration_path(test_config_without_whitelist_regexps_file) except Exception as ex: self.fail("configuration file that does not contain whitelist_regexps raised the exception: %s" % ex) def test_error_on_duplicate_key_check(self): self.test_settings.change_configuration_path(test_whitelist_duplicate_option_file) result = settings.check_no_duplicate_key() self.assertIsInstance(result, DuplicateOptionError) def test_error_on_duplicate_section_check(self): self.test_settings.change_configuration_path(test_whitelist_duplicate_section_file) result = settings.check_no_duplicate_key() self.assertIsInstance(result, DuplicateSectionError) # Test on process_configuration_files function def test_error_when_config_file_does_not_exist(self): with self.assertRaises(SystemExit) as cm: self.test_settings.change_configuration_path(test_config_that_does_not_exist) self.assertEqual(cm.exception.code, 2) # Test on process_configuration_files function def test_error_when_config_file_is_a_directory(self): with self.assertRaises(SystemExit) as cm: self.test_settings.change_configuration_path(test_config_that_is_a_directory) self.assertEqual(cm.exception.code, 2) # Test on check_no_failed_config_paths function def test_error_when_failed_config_file_exists_on_interactive_mode(self): with self.assertRaises(SystemExit) as cm: print_failed_configs_and_exit({test_config_that_does_not_exist}) self.assertEqual(cm.exception.code, 2) def test_error_when_multiple_failed_config_files_exist(self): failed_config_files = {test_config_that_does_not_exist, test_config_that_is_a_directory} with self.assertRaises(SystemExit) as cm: print_failed_configs_and_exit(failed_config_files) self.assertEqual(cm.exception.code, 2) def test_no_exceptions_on_valid_config_file(self): try: self.test_settings.change_configuration_path(test_whitelist_multiple_literal_file) except Exception: self.fail("loading a valid configuration file raised an unexpected exception!") # Test on check_no_failed_config_paths function def test_error_when_no_failed_config_paths_exist(self): failed_config_files = {} raised = False try: print_failed_configs_and_exit(failed_config_files) except SystemExit: raised = True self.assertFalse(raised)