diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c4f87216..c8ad91472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - MongoDb now gets launched by the Island via python. #1148 - Create/check data directory on Island init. #1170 - The formatting of some log messages to make them more readable. #1283 +- Some unit tests to run faster. #1125 ### Removed - Relevant dead code as reported by Vulture. #1149 diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index acb12d48a..55cd70b3b 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -360,7 +360,7 @@ class ConfigService: parent_config_arr = config_arr config_arr = config_arr[config_key_part] - if isinstance(config_arr, collections.Sequence) and not isinstance(config_arr, str): + if isinstance(config_arr, collections.abc.Sequence) and not isinstance(config_arr, str): for i in range(len(config_arr)): # Check if array of shh key pairs and then decrypt if isinstance(config_arr[i], dict) and "public_key" in config_arr[i]: diff --git a/monkey/tests/conftest.py b/monkey/tests/conftest.py deleted file mode 100644 index fc44af014..000000000 --- a/monkey/tests/conftest.py +++ /dev/null @@ -1,23 +0,0 @@ -import os -import sys -from pathlib import Path - -import pytest - -MONKEY_BASE_PATH = str(Path(__file__).parent.parent) -sys.path.insert(0, MONKEY_BASE_PATH) - - -@pytest.fixture(scope="session") -def data_for_tests_dir(pytestconfig): - return Path(os.path.join(pytestconfig.rootdir, "monkey", "tests", "data_for_tests")) - - -@pytest.fixture(scope="session") -def stable_file(data_for_tests_dir) -> Path: - return data_for_tests_dir / "stable_file.txt" - - -@pytest.fixture(scope="session") -def stable_file_sha256_hash() -> str: - return "d9dcaadc91261692dafa86e7275b1bf39bb7e19d2efcfacd6fe2bfc9a1ae1062" diff --git a/monkey/tests/unit_tests/conftest.py b/monkey/tests/unit_tests/conftest.py index 8e0fc96d9..3099263b0 100644 --- a/monkey/tests/unit_tests/conftest.py +++ b/monkey/tests/unit_tests/conftest.py @@ -1,4 +1,27 @@ +import os +import sys +from pathlib import Path + import pytest +from _pytest.monkeypatch import MonkeyPatch + +MONKEY_BASE_PATH = str(Path(__file__).parent.parent.parent) +sys.path.insert(0, MONKEY_BASE_PATH) + + +@pytest.fixture(scope="session") +def data_for_tests_dir(pytestconfig): + return Path(os.path.join(pytestconfig.rootdir, "monkey", "tests", "data_for_tests")) + + +@pytest.fixture(scope="session") +def stable_file(data_for_tests_dir) -> Path: + return data_for_tests_dir / "stable_file.txt" + + +@pytest.fixture(scope="session") +def stable_file_sha256_hash() -> str: + return "d9dcaadc91261692dafa86e7275b1bf39bb7e19d2efcfacd6fe2bfc9a1ae1062" @pytest.fixture @@ -6,3 +29,13 @@ def patched_home_env(monkeypatch, tmp_path): monkeypatch.setenv("HOME", str(tmp_path)) return tmp_path + + +# The monkeypatch fixture is function scoped, so it cannot be used by session-scoped fixtures. This +# monkeypatch_session fixture can be session-scoped. For more information, see +# https://github.com/pytest-dev/pytest/issues/363#issuecomment-406536200 +@pytest.fixture(scope="session") +def monkeypatch_session(): + monkeypatch_ = MonkeyPatch() + yield monkeypatch_ + monkeypatch_.undo() diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/test_zerologon.py b/monkey/tests/unit_tests/infection_monkey/exploit/test_zerologon.py index a2956887f..95beb1778 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/test_zerologon.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/test_zerologon.py @@ -1,6 +1,5 @@ import pytest -from infection_monkey.exploit.zerologon import ZerologonExploiter from infection_monkey.model.host import VictimHost DOMAIN_NAME = "domain-name" @@ -15,6 +14,8 @@ NT_HASHES = ["def456", "765vut"] @pytest.fixture def zerologon_exploiter_object(monkeypatch): + from infection_monkey.exploit.zerologon import ZerologonExploiter + def mock_report_login_attempt(**kwargs): return None @@ -25,11 +26,13 @@ def zerologon_exploiter_object(monkeypatch): return obj +@pytest.mark.slow def test_assess_exploit_attempt_result_no_error(zerologon_exploiter_object): dummy_exploit_attempt_result = {"ErrorCode": 0} assert zerologon_exploiter_object.assess_exploit_attempt_result(dummy_exploit_attempt_result) +@pytest.mark.slow def test_assess_exploit_attempt_result_with_error(zerologon_exploiter_object): dummy_exploit_attempt_result = {"ErrorCode": 1} assert not zerologon_exploiter_object.assess_exploit_attempt_result( @@ -37,6 +40,7 @@ def test_assess_exploit_attempt_result_with_error(zerologon_exploiter_object): ) +@pytest.mark.slow def test_assess_restoration_attempt_result_restored(zerologon_exploiter_object): dummy_restoration_attempt_result = object() assert zerologon_exploiter_object.assess_restoration_attempt_result( @@ -44,6 +48,7 @@ def test_assess_restoration_attempt_result_restored(zerologon_exploiter_object): ) +@pytest.mark.slow def test_assess_restoration_attempt_result_not_restored(zerologon_exploiter_object): dummy_restoration_attempt_result = False assert not zerologon_exploiter_object.assess_restoration_attempt_result( @@ -51,6 +56,7 @@ def test_assess_restoration_attempt_result_not_restored(zerologon_exploiter_obje ) +@pytest.mark.slow def test__extract_user_creds_from_secrets_good_data(zerologon_exploiter_object): mock_dumped_secrets = [ f"{USERS[i]}:{RIDS[i]}:{LM_HASHES[i]}:{NT_HASHES[i]}:::" for i in range(len(USERS)) @@ -71,6 +77,7 @@ def test__extract_user_creds_from_secrets_good_data(zerologon_exploiter_object): assert zerologon_exploiter_object._extracted_creds == expected_extracted_creds +@pytest.mark.slow def test__extract_user_creds_from_secrets_bad_data(zerologon_exploiter_object): mock_dumped_secrets = [ f"{USERS[i]}:{RIDS[i]}:::{LM_HASHES[i]}:{NT_HASHES[i]}:::" for i in range(len(USERS)) diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/zerologon_utils/test_vuln_assessment.py b/monkey/tests/unit_tests/infection_monkey/exploit/zerologon_utils/test_vuln_assessment.py index 525cd8e3f..c0635939c 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/zerologon_utils/test_vuln_assessment.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/zerologon_utils/test_vuln_assessment.py @@ -2,7 +2,6 @@ import pytest from nmb.NetBIOS import NetBIOS from common.utils.exceptions import DomainControllerNameFetchError -from infection_monkey.exploit.zerologon_utils.vuln_assessment import get_dc_details from infection_monkey.model.host import VictimHost DOMAIN_NAME = "domain-name" @@ -21,7 +20,10 @@ def _get_stub_queryIPForName(netbios_names): return stub_queryIPForName +@pytest.mark.slow def test_get_dc_details_multiple_netbios_names(host, monkeypatch): + from infection_monkey.exploit.zerologon_utils.vuln_assessment import get_dc_details + NETBIOS_NAMES = ["Name1", "Name2", "Name3"] stub_queryIPForName = _get_stub_queryIPForName(NETBIOS_NAMES) @@ -33,7 +35,10 @@ def test_get_dc_details_multiple_netbios_names(host, monkeypatch): assert dc_handle == f"\\\\{NETBIOS_NAMES[0]}" +@pytest.mark.slow def test_get_dc_details_no_netbios_names(host, monkeypatch): + from infection_monkey.exploit.zerologon_utils.vuln_assessment import get_dc_details + NETBIOS_NAMES = [] stub_queryIPForName = _get_stub_queryIPForName(NETBIOS_NAMES) diff --git a/monkey/tests/unit_tests/infection_monkey/telemetry/test_exploit_telem.py b/monkey/tests/unit_tests/infection_monkey/telemetry/test_exploit_telem.py index 95f853922..6ecfeba1a 100644 --- a/monkey/tests/unit_tests/infection_monkey/telemetry/test_exploit_telem.py +++ b/monkey/tests/unit_tests/infection_monkey/telemetry/test_exploit_telem.py @@ -2,7 +2,7 @@ import json import pytest -from infection_monkey.exploit.wmiexec import WmiExploiter +from infection_monkey.exploit.sshexec import SSHExploiter from infection_monkey.model.host import VictimHost from infection_monkey.telemetry.exploit_telem import ExploitTelem @@ -19,10 +19,10 @@ HOST_AS_DICT = { "default_tunnel": None, "default_server": None, } -EXPLOITER = WmiExploiter(HOST) -EXPLOITER_NAME = "WmiExploiter" +EXPLOITER = SSHExploiter(HOST) +EXPLOITER_NAME = "SSHExploiter" EXPLOITER_INFO = { - "display_name": WmiExploiter._EXPLOITED_SERVICE, + "display_name": SSHExploiter._EXPLOITED_SERVICE, "started": "", "finished": "", "vulnerable_urls": [], diff --git a/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py b/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py index 2df8be4dd..90fd9032a 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py +++ b/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py @@ -1,6 +1,5 @@ import logging import uuid -from time import sleep import pytest @@ -24,9 +23,9 @@ class TestMonkey: mia_monkey_ttl.save() mia_monkey = Monkey(guid=str(uuid.uuid4()), dead=False, ttl_ref=mia_monkey_ttl.id) mia_monkey.save() + # Emulate timeout - ttl is manually deleted here, since we're using mongomock and not a # real mongo instance. - sleep(1) mia_monkey_ttl.delete() dead_monkey = Monkey(guid=str(uuid.uuid4()), dead=True) diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/conftest.py b/monkey/tests/unit_tests/monkey_island/cc/resources/conftest.py index 0e82fe163..3ca40a11a 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/conftest.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/conftest.py @@ -9,12 +9,9 @@ import monkey_island.cc.resources.island_mode from monkey_island.cc.services.representations import output_json -# We can't scope to module, because monkeypatch is a function scoped decorator. -# Potential solutions: https://github.com/pytest-dev/pytest/issues/363#issuecomment-406536200 or -# https://stackoverflow.com/questions/53963822/python-monkeypatch-setattr-with-pytest-fixture-at-module-scope -@pytest.fixture(scope="function") -def flask_client(monkeypatch): - monkeypatch.setattr(flask_jwt_extended, "verify_jwt_in_request", lambda: None) +@pytest.fixture(scope="session") +def flask_client(monkeypatch_session): + monkeypatch_session.setattr(flask_jwt_extended, "verify_jwt_in_request", lambda: None) with mock_init_app().test_client() as client: yield client diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_configuration_import.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_configuration_import.py index ed1d908cf..e9672ebdf 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_configuration_import.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_configuration_import.py @@ -13,6 +13,7 @@ def test_is_config_encrypted__json(monkey_config_json): assert not ConfigurationImport.is_config_encrypted(monkey_config_json) +@pytest.mark.slow def test_is_config_encrypted__ciphertext(monkey_config_json): encrypted_config = encrypt_string(monkey_config_json, PASSWORD) assert ConfigurationImport.is_config_encrypted(encrypted_config) diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/attack/test_mitre_api_interface.py b/monkey/tests/unit_tests/monkey_island/cc/services/attack/test_mitre_api_interface.py index 44297795c..f93afc8d5 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/services/attack/test_mitre_api_interface.py +++ b/monkey/tests/unit_tests/monkey_island/cc/services/attack/test_mitre_api_interface.py @@ -1,14 +1,14 @@ -from unittest import TestCase +import pytest from monkey_island.cc.services.attack.mitre_api_interface import MitreApiInterface -class TestMitreApiInterface(TestCase): - def test_get_all_mitigations(self): - mitigations = MitreApiInterface.get_all_mitigations() - self.assertIsNotNone((len(mitigations.items()) >= 282)) - mitigation = next(iter(mitigations.values())) - self.assertEqual(mitigation["type"], "course-of-action") - self.assertIsNotNone(mitigation["name"]) - self.assertIsNotNone(mitigation["description"]) - self.assertIsNotNone(mitigation["external_references"]) +@pytest.mark.slow +def test_get_all_mitigations(): + mitigations = MitreApiInterface.get_all_mitigations() + assert len(mitigations.items()) >= 282 + mitigation = next(iter(mitigations.values())) + assert mitigation["type"] == "course-of-action" + assert mitigation["name"] is not None + assert mitigation["description"] is not None + assert mitigation["external_references"] is not None diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/ransomware/test_ransomware_report.py b/monkey/tests/unit_tests/monkey_island/cc/services/ransomware/test_ransomware_report.py index f59edbbc3..3f7ce4c57 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/services/ransomware/test_ransomware_report.py +++ b/monkey/tests/unit_tests/monkey_island/cc/services/ransomware/test_ransomware_report.py @@ -23,14 +23,14 @@ def fake_mongo(monkeypatch): @pytest.mark.usefixtures("uses_database") def test_get_encrypted_files_table(fake_mongo, monkeypatch): - fake_mongo.db.monkey.insert(MONKEY_AT_ISLAND) - fake_mongo.db.monkey.insert(MONKEY_AT_VICTIM) - fake_mongo.db.edge.insert(EDGE_EXPLOITED) - fake_mongo.db.edge.insert(EDGE_SCANNED) - fake_mongo.db.telemetry.insert(ENCRYPTED) - fake_mongo.db.telemetry.insert(ENCRYPTED_2) - fake_mongo.db.telemetry.insert(ENCRYPTION_ERROR) - fake_mongo.db.telemetry.insert(ENCRYPTION_ONE_FILE) + fake_mongo.db.monkey.insert_one(MONKEY_AT_ISLAND) + fake_mongo.db.monkey.insert_one(MONKEY_AT_VICTIM) + fake_mongo.db.edge.insert_one(EDGE_EXPLOITED) + fake_mongo.db.edge.insert_one(EDGE_SCANNED) + fake_mongo.db.telemetry.insert_one(ENCRYPTED) + fake_mongo.db.telemetry.insert_one(ENCRYPTED_2) + fake_mongo.db.telemetry.insert_one(ENCRYPTION_ERROR) + fake_mongo.db.telemetry.insert_one(ENCRYPTION_ONE_FILE) monkeypatch.setattr( ReportService, @@ -58,11 +58,11 @@ def test_get_encrypted_files_table(fake_mongo, monkeypatch): @pytest.mark.usefixtures("uses_database") def test_get_encrypted_files_table__only_errors(fake_mongo, monkeypatch): - fake_mongo.db.monkey.insert(MONKEY_AT_ISLAND) - fake_mongo.db.monkey.insert(MONKEY_AT_VICTIM) - fake_mongo.db.edge.insert(EDGE_EXPLOITED) - fake_mongo.db.edge.insert(EDGE_SCANNED) - fake_mongo.db.telemetry.insert(ENCRYPTION_ERROR) + fake_mongo.db.monkey.insert_one(MONKEY_AT_ISLAND) + fake_mongo.db.monkey.insert_one(MONKEY_AT_VICTIM) + fake_mongo.db.edge.insert_one(EDGE_EXPLOITED) + fake_mongo.db.edge.insert_one(EDGE_SCANNED) + fake_mongo.db.telemetry.insert_one(ENCRYPTION_ERROR) monkeypatch.setattr( ReportService, @@ -84,10 +84,10 @@ def test_get_encrypted_files_table__only_errors(fake_mongo, monkeypatch): @pytest.mark.usefixtures("uses_database") def test_get_encrypted_files_table__no_telemetries(fake_mongo, monkeypatch): - fake_mongo.db.monkey.insert(MONKEY_AT_ISLAND) - fake_mongo.db.monkey.insert(MONKEY_AT_VICTIM) - fake_mongo.db.edge.insert(EDGE_EXPLOITED) - fake_mongo.db.edge.insert(EDGE_SCANNED) + fake_mongo.db.monkey.insert_one(MONKEY_AT_ISLAND) + fake_mongo.db.monkey.insert_one(MONKEY_AT_VICTIM) + fake_mongo.db.edge.insert_one(EDGE_EXPLOITED) + fake_mongo.db.edge.insert_one(EDGE_SCANNED) monkeypatch.setattr( ReportService, diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/utils/ciphertexts_for_encryption_test.py b/monkey/tests/unit_tests/monkey_island/cc/services/utils/ciphertexts_for_encryption_test.py index b35513a2a..0fa7131e0 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/services/utils/ciphertexts_for_encryption_test.py +++ b/monkey/tests/unit_tests/monkey_island/cc/services/utils/ciphertexts_for_encryption_test.py @@ -1,3 +1,61 @@ +VALID_CIPHER_TEXT = ( + "QUVTAgAAG0NSRUFURURfQlkAcHlBZXNDcnlwdCA2LjAuMACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPzzL7yzdvBdhwJiYrRRb/0f4hmQSN9OaYNfqcXKk/c0vnzqWh1Yo7AAjODs2D" + "nZU7bp1VxM3OE/iHLK8+YOD6TVcJMMSk5TdaHyuo/oCcWSA5xHGhSUPQEXk+sPglNv/PO1qyHFQl9m2nAvwdfsJpdYi5Fi" + "6euP9XBy3mViu70IrxqNAgc8DdWqAII4Y9UW+x2jnLgnBT6NBk0DWXMyWZ3+aji+D1hb9DTwAn+/5HQWviFASwEwMaoYFV" + "/Guy3M7NGfSD15wpYaLN5ZszBWGUSi7Ewf7TBRK2Vc1DFJClj05A8/TyjeCyHKnjdGoOl3qqszvj8D8fVAuMkXsqu0G7Lb" + "TjTYDnBxZ8rEV8uRLQrvnLGULkKXyeFP2yfuzfyYSbXRYIAw+lY1EIzcNhmMzaZVFOVd/q6/e7FTJd/JoyhK7gD+zErn0T" + "u4k6c6/2kkZlc4MQYCMZGBNzdnuTEKrFsiFjWI9b4oz2mVRI2anXXYRMCqN1+L9XBCfscaUlc/NPDMFGdsZGsRpFJCbda6" + "X5j/45luqSdVU8l4M+uW7xGe/jroRtTooCFjk0r0miNToJZunafluTCfFSnbLAkaYxBRe0kYryfbP/38geWU46tIenKEQD" + "YDlDYVc1lr1CKjn39NJdACgOzzY/I0ZmXLNreonYjjRZ1+0rxeTqYiPwlUJdfdEkRDhii404Wxb9l9rUWaK2sGXq2Ykh1r" + "VLPjEa8bRaqWzguqk+k8aHjzHSSkSIl+8PXC8RSnmsJXka33xX9quOqUMT+hp2IhRu8L86ub1K635/b82i9T2R/bghkLy4" + "d/+k5bOUPXlNAA0OyGC/7JQgNWV/3ddiO6/k5tREaM9H44r0dJuFSS3+fjTwnlQMvp/ypOrGjgYpY77H0VubPma0Y3m2VB" + "U8pNPd0Mpv7qe9iQsJPG93I4rP/vzwi5TbeK4Gsg0gBSL2HsP/mGTUNpj1CwrBj+JridWEnwCsq7yaQacVoYqxiB4zKNS5" + "XupVlrkNxf8GyaBFonQNWPlmtvoY7dnG81YwLdKF4GwcP23SLfgtnHjSRtgdVgmO498HBTJVg7nJcvGuZiBqJbXRFcMgik" + "HwgBVA8F/WzrTtzhzd+bazOHWaU+4Tlo3fkQq/tQvfGawNbXCoakn69jWMV7xP6K2w3oeJie3d3YfqNbCBiaVGiF8KB7ui" + "ly6G+8pirNWihIZJ+r2PORsTkQwNMzff1odnP6e4lYs3LbVwdS5Pwzkp4LjzUKJBtXo7vCS+WXlGpMz30CwXR8tnyg+4QK" + "NrdprPkqTOHLz/EmBdfjS1MG9fv6U3pTHM2oZnaLQIqs167FS8OQejE6c6t0Wn/bIlkn7i7Xw3pq/ICWx4pR0Mq9RLDr55" + "EfUW0gPJiGquDMgmLcvoJmNY6ENYdG/cPvbbqxCZIlMjPWk3+8myH8QB6b5J/FKEXh2IcMHrKETM+X0XhrueWLclTFCVwE" + "AkBN4V6oWlKUnuFJscSKQKhzJQ94iSTiwzZphktCDvgVncTSa3YqLZ0wPsdmdy7QDdP7xh1SYAAyTQKvanHAgEakDQ+gVF" + "EfPhJhTfYEEXxMdaUmorxaCbH0xzpqJZPuaq7Xt97dQeZOaJvXDBiJ7ek+ZFJCrtxmUaEF4vHCDjOMbggrfINTErDngFT8" + "/SiFeSy17/pz6Bv39xxhdzTtWqc29ffW1uK/hlK4g2sPaCuHEu/55+gQoZpsqHDJCkmfBlL1BSoWBbSAZrE07T+Qb7oigu" + "/Ko4Z+cL3npSsn9btkN3XNaHH9q4vN+ut9etLi8TmpAUJqvTlGCy9tlWmdRe5346LVHLfHNFHZ9nyZhwMWfiQaMWlwcLel" + "MP3CKsez9u7Cd2ybR0e2SFRLC1bY7H9Vg4/RMJjPsCHFDU0FAan8X5estTBBFKA3OfNc8DxcbS+jXMWYjdLv6M9cS7rAS4" + "zdumgz++f0y+4TKkFQdC3LKGEGYpJ+KoG7HStbUIkqp4YvLaQFsnt/gwrPOlAAYfso/ot3KjhBXILyfsA4EgbJt295uD8P" + "2cCB/2s8tdTb78L1k2vhnvDv+1lox7n3PgfqYqsnB8Rjd/XhwzKfJJUcwmjCBG2IdWycy0zKOoeU0WEr7rphwFIG7wnAuG" + "uufmZX75GZ9BIRbFoiRprLeCU45ha0Wwm7UJwP5os3ER6nLWzQyEOTG0s1HWd8MqdMCwZK/1MHwAVIXrRh+xpESwpABZ6O" + "ZQbb/Rp9DddEKy7d5XDQhStbApYnlayVrYUHzCnJrvLYxxO938n0bD+itPyWXs+Nizta+XUFbmuDmjdR60Vzp7AHzgNlJD" + "BtxJltAX29JA08BG4+W/tOI0YfoeaYrHbmRlw9USXa411th9lvvMgfEGDR4ql9nLUsb/gFv4UKpcsG/MQkWT1CnSXCBTmc" + "574HQgRLdakkAGaWekU5zI7h4LWgQVqu2K7zTyqn0cFKfiaBW4r8i56+nlzfq++MgFDsJ2z3hj7OFFv9d97G5lw+ftpYP3" + "QIpNDnniOGJuV1b3Aqvr1RCS6xhE7ljpI+lJnDk0mKZfKumUFV/EA5QIa1B5s5lnREm4iqGwOpvSb1gm/guYiO+sNQLn9w" + "SZDj4iPPHl8vpRvj5FyCxLKj4CP/lGHXBhu5d6LtoUQT5mG4NrygJRsV7iym1IRdrRl1CSkwl7f1lBj00KZ9s1YQftWbTp" + "UtUCq+cMeF07GqoAjDUqfUMd3L70o5LGkhqxceZBusS5MiED56QAWbHJ0YIY+lNwttqf9njzgUs3ZjH9WM8+xVy6PK7g1Z" + "sRn2H6mpajwoHzzHdVdCw7Az+OCyf2ZP4k5aM8ZxUFmaQhyO//rhMJYeyPNzpxaXxQkAU6w39BId1hQA2n0rhaeVfdo0Ry" + "NJNn23PVHUlTHxLoAMiop/BbbY3sqGlB2Cc6X9FDGMhvQQMinQ09hUwEpYX5bZli2J8MiPDHSiQ490zJlVn3QDyhfPDcve" + "mq68kzRp/BkoRkoqp8aUkJ7mb4EYxPtJMSg4eBq4uaJY+vEISCSXDaZBn5kL+KL93ttkykkbWf0Z8RN290Pc4Tq76Oj5oX" + "2BSlCpBXbxqpOvi7Msccb8ZtTEoha4wTZzrTD6P+P44u9UycZgjz6jZdzNKy4RCG8O2ow1RIxEtexKG+YRu3jWNb7T92Jy" + "iFDvuUfd7jj3dzhdeRGK9jnhyHxduqw92XbPBgXLOcXB0uszI0I+bd0OATfvbK+gTsRutxHDb5R2f0lSoMsIQcv9PnwJPV" + "HpvWsY82/6s6Jq9HAni9E/PCK3RbLs+VkO5BFwFLC1euG1AyfI/M8C/dZjDdZjdInITfvGukqv/81mnGdcwGFA6b3S6tjA" + "Oc8vKHYm3xS0GG89GEHzTYMGz3d+OvkIIPal3C/F99wNUv2WiJ+uOB5mVVaplaulWM/uOdlbHTwKYJeBEr/US0Tnju0gYc" + "R4wTZwTzPfqf/zMaazB6M0J0XI/WWWPfES8mABrPvD29Sd2BSXL5vQoXT39gSPYO+/8Gc7oySD0SPrXXUFmqzblUmDeYkO" + "K2BwGNfVZOpuZA+Aals+Rb9Cexzmj2Jxkl0qj/1e9YoWjpVumIAQkgl5WmlXDb0/BJ4zuPThwgFhSIkocnytUmfKlYoZGQ" + "fH4snJ183nUCct3QK5/WMgRPsZh7jKQtx5KDwX4rAbNkH99KPEwOaQSUcDxzeCVKU74c81FX0EmewovknBQLC3x5cBmuPN" + "HRAGvvST0275f2FkaFgXfLwCbHnf5o+EPeoRxm4NGcosjXdhaU6bXCPWyBuwZUpgaoR94FC/xe0wRKhM6xLucOoo599CLA" + "kIv820DkbHBikiIpOw/7NmpztRMtH7Kq2ZESmpBnU7wUxWBqrlgBo+ywEjSItsah54mOExpOiF/1hg0Swg48WD2Z1Mw1Gz" + "6BRqgJnLfjEGeBHty2wuq06qgepQPfy2/N3QFUOXU+Y/akNlxgyQN7sULYq0Elrhnif0uiJVaj8H53wmyPq2zKAzwPos4P" + "m4DnoDgBOuTqdwRAANg5m7idaKnXBsvpF+DKGi3b1HXuGttTXiZIHDutB3oLGQHQ3+uT6rdzwLlQNuKqCkOjTH0NXL7cio" + "1ldCclvNFRoEEzk4aW4djpESRqgFBac62UJpsoflmxEzdqaHlWrqJ6IK5knjv8PREY1Cf0mXVE7bmsSyonI7Tu0JhkRquN" + "8T+Eg1I7DGsqO3buWmAiulN/TTqC92uid3c+PiSGXJ6nEQ+RDlwwd2iq/wmDAu8hq6AbW6wA3Atu7xKQC0xkD2RhzF9yIu" + "t9tNYNWWRl14tjwmfvurE65F0mMqgbLhepQ3ajYXqSOytOBNxlrhpGJ7ZFngNiRLP90jYOcZ4tWIMpt5XPCDQXiehtvU+M" + "zRoDfKjtSXbux9/w92es+2nVJUxrWQPvjsoRphYK6eVO5FbClmc+w7np2ugFZ231isdHYaMRe4VaXA7YkVqMuiBY4ZXrnA" + "vtBZRzNGgSoFMmHQ0WebwipLXjJpLoQDktWItFbY1AI5MeJDu1fLR6EK9c5opCk/doK9RozfPfyinh9oBfZ3ZmSdY1WOxj" + "LGc3QmCXFbxapAFNdzS8satGjn/VV1ZbhZBU7fzW1auiRxk1H0/CjWK0w1g2KQ2DRPG2vPpLAJVjy3cyNn0oS6YgDStDN2" + "fUtRYH1oBt6cIeW4K8Mp7I1fD+Wa45ZFonmeeuBj53S6k+Ov2aX5cIUeRrB4tvmkBosYdL9N+lr1wORZLj2us8IWmnlKh4" + "nmV0tcZxh5kBZW1vgP+LWHEN4ialItBPmsggRWqyBSVTr8tbtLEaJrlZ2NXiUFhcVJkggItwU02Ueesvjpjngfd/UluO/d" + "5pnm3dizp6Q=" +) + MALFORMED_CIPHER_TEXT_CORRUPTED = ( "QUVTAgAAGM0NKEYTESTURfQlkAcHlBZXNDcnlwdCA2LjAuMACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/utils/test_config_encryption.py b/monkey/tests/unit_tests/monkey_island/cc/services/utils/test_config_encryption.py index 23b399cc5..fd3191f50 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/services/utils/test_config_encryption.py +++ b/monkey/tests/unit_tests/monkey_island/cc/services/utils/test_config_encryption.py @@ -1,6 +1,7 @@ import pytest from tests.unit_tests.monkey_island.cc.services.utils.ciphertexts_for_encryption_test import ( MALFORMED_CIPHER_TEXT_CORRUPTED, + VALID_CIPHER_TEXT, ) from monkey_island.cc.services.utils.encryption import ( @@ -15,23 +16,25 @@ PASSWORD = "hello123" INCORRECT_PASSWORD = "goodbye321" +@pytest.mark.slow def test_encrypt_decrypt_string(monkey_config_json): encrypted_config = encrypt_string(monkey_config_json, PASSWORD) assert decrypt_ciphertext(encrypted_config, PASSWORD) == monkey_config_json -def test_encrypt_decrypt_string__wrong_password(monkey_config_json): - encrypted_config = encrypt_string(monkey_config_json, PASSWORD) +@pytest.mark.slow +def test_decrypt_string__wrong_password(monkey_config_json): with pytest.raises(InvalidCredentialsError): - decrypt_ciphertext(encrypted_config, INCORRECT_PASSWORD) + decrypt_ciphertext(VALID_CIPHER_TEXT, INCORRECT_PASSWORD) -def test_encrypt_decrypt_string__malformed_corrupted(): +@pytest.mark.slow +def test_decrypt_string__malformed_corrupted(): with pytest.raises(ValueError): decrypt_ciphertext(MALFORMED_CIPHER_TEXT_CORRUPTED, PASSWORD) -def test_encrypt_decrypt_string__decrypt_no_password(monkey_config_json): - encrypted_config = encrypt_string(monkey_config_json, PASSWORD) +@pytest.mark.slow +def test_decrypt_string__no_password(monkey_config_json): with pytest.raises(InvalidCredentialsError): - decrypt_ciphertext(encrypted_config, "") + decrypt_ciphertext(VALID_CIPHER_TEXT, "") diff --git a/pyproject.toml b/pyproject.toml index 319c4cc1f..05c8dfe81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ log_cli_format = "%(asctime)s [%(levelname)s] %(module)s.%(funcName)s.%(lineno)d log_cli_date_format = "%H:%M:%S" addopts = "-v --capture=sys tests/unit_tests" norecursedirs = "node_modules dist" +markers = ["slow: mark test as slow"] [tool.vulture] exclude = ["monkey/monkey_island/cc/ui/", "monkey/tests/"]