From 71d9c6d0f4f061ee969aee6d89b3ff82c6eb69d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 22:31:01 +0200 Subject: [PATCH] Stabilization of unittests --- .github/workflows/tests.yml | 4 +++ data/txt/sha256sums.txt | 58 ++++++++++++++++---------------- lib/core/settings.py | 2 +- tests/_testutils.py | 16 +++++++++ tests/test_agent.py | 6 +++- tests/test_brute.py | 6 +++- tests/test_common.py | 11 ++++-- tests/test_databases_enum.py | 6 +++- tests/test_dbms_enum.py | 6 +++- tests/test_dialect.py | 6 +++- tests/test_dns_engine.py | 10 ++++-- tests/test_dump_format.py | 6 +++- tests/test_dump_jsonl.py | 6 +++- tests/test_entries.py | 6 +++- tests/test_error_engine.py | 6 +++- tests/test_filesystem.py | 6 +++- tests/test_fingerprint.py | 12 ++++++- tests/test_generic_takeover.py | 6 +++- tests/test_graphql.py | 6 ++++ tests/test_identifiers_output.py | 6 +++- tests/test_inference_engine.py | 6 +++- tests/test_misc.py | 6 +++- tests/test_parse_modules.py | 6 +++- tests/test_property.py | 6 +++- tests/test_report.py | 6 ++++ tests/test_search_enum.py | 6 +++- tests/test_target_parsing.py | 10 ++++-- tests/test_techniques.py | 6 +++- tests/test_union_engine.py | 6 +++- tests/test_users_enum.py | 6 +++- tests/test_xpath.py | 3 ++ 31 files changed, 200 insertions(+), 58 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 367bec214..a6bedc1e6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,6 +17,10 @@ jobs: runs-on: ${{ matrix.os }} timeout-minutes: 30 + env: + # deterministic dict/set iteration order run-to-run (guards against hash-order flakiness in CI) + PYTHONHASHSEED: "0" + strategy: matrix: include: diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 0c28db3dd..c654360a5 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -efadf8b3de6c132219b026eb80fa61756787df0753fa00aff420f60c92b17a52 lib/core/settings.py +de1ffd738b35e31eb95467eda8a230cc81ff4d21e48e4c02c29da09299823126 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -586,86 +586,86 @@ dcdeed9ee285e63cf06baf8347e3db7f210ef25a63869bab78ce1ec6898ae191 tamper/unional 0694e721b07b8242245688be5c7951a3a22f512ed73776a998885e4b1bc82bc7 tamper/versionedmorekeywords.py ce1b6bf8f296de27014d6f21aa8b3df9469d418740cd31c93d1f5e36d6c509cf tamper/xforwardedfor.py 44401cad3e39ae9fb899ed5d0e2fdd0879561de05c3117f17f3b0db54f4e3724 tests/__init__.py -d16977d057c28888aa41500f79a19789cadef693cb8b7d9a3bca55b983ce2266 tests/test_agent.py +0e9054da5d1fed1ddfc982b8f559914237f65d9be5e595c3218fcd236dfa7212 tests/test_agent.py 138381e05a860272fedab780e6c38ab74c59c879048b11b909d23f8df654352a tests/test_api.py feb763ddcbf4f32822372ca53f8c71c754af7b72510ef06e1e9c77927fc90b10 tests/test_bigarray.py -36bcb68483d824db5d05870fab62f1907221bf256826b734302fbc15a9231c42 tests/test_brute.py +aeefe699f477e77ec4fb46c2692a1ea04cd89ad9cce62e8857d13e3bc0606e9d tests/test_brute.py 27ad87c0ea377e0657bd6f6a4eaa0e9756aa9d28ec0483bdadeb3f66dcc4660d tests/test_charset.py 7596fc69678304923b5c945c0fd9b8ee62a2dfc7fb14ccb6dc7af30893dc8012 tests/test_checks.py 9e678a56e16211c49ab4995b6c658d3f122bfa3b357d9e17ff38f5a489ace6ad tests/test_cloak.py 2ec894f49ca9bd750a23ead16dae176bcbc57d18ec5847fa4a5eeb886d75c1bd tests/test_common_helpers.py -cdacb37cbe5667fded00abe62a822e11c917e9cb5c3f664b7aa1a8d738412ed4 tests/test_common.py +d436ad4c99be71d5faadb37f63d96a498e7e2b84f257ac9c7965b2ccd999e9e9 tests/test_common.py 899bc085e96d68f8a8cbe0d7e55863e98ef37b73ab0e4234f7d969e31ea2d23a tests/test_comparison_json.py 7b72d4f850bbd059b8e95fceb45a58470354cb7270c99b0e9981aaa189af20d1 tests/test_comparison.py a7c3cf9f7820f377ebfdecf9383ebebc2932dd4a2a531a2b4496071f9d973c1c tests/test_compat.py 75357efd92f3f57cc05244a0f40985108077479fd192caaaa81e14f61c13783d tests/test_convert.py -2bd0faeaf7db1d73dd0caab3bde9900fdaa1f38fd736a6e238cd56ff9bc67b66 tests/test_databases_enum.py +6e3c08e1f76dd6c782d2ddc505b4e1a751b381c88ad91f79a95bf49f9c28a28f tests/test_databases_enum.py c17544be5e945dc8c4fbb5c3b922da8eceec30b0fb239c32fb5f40e1660a197f tests/test_datafiles.py 9c240d4f796e56376374d4ce46f358ceb7d48cc6a7427760c5bfb89ff01cb545 tests/test_datatypes.py -8a1edb6dbc000e412ba5cc598e024b669fc76ec0a8fc32136808e6325a018f70 tests/test_dbms_enum.py +7cf63166206d543ff4423e1b5bda3ec3212805b0aeaf95d877117df7eb79c8ec tests/test_dbms_enum.py 3804eb2d730220360f9dc07d5994eb64e9f65acf3b0d8648df8df2a2177ba8fd tests/test_decodepage.py 180e5fd3f75fadf7ac1135f99797314e2cf1f8ae6dced02edfb18ccba43c0148 tests/test_deps.py fa85881aa8d082a65aeacb2b03fcb5d2abb1daa9a02ee24ff048d54fbc904b90 tests/test_dialectdbms.py -e40a49cfa73c45b3c3c6d1d1d00738861e270cb7a07b28f5a5356f9c7c800cf2 tests/test_dialect.py +41bb0981cb7372753dbaa328c8be3678d328b736e6b97f7bd2573b465753af01 tests/test_dialect.py 993a2d4d87c4fbaf261663b069629acc95ee4405aa0c42cf5a8f39649fdb0fff tests/test_dicts.py -7f9180a53dbf0bb3e52801fdbfffd31f365a0bff77bf90e58d2ef63a0c23026f tests/test_dns_engine.py +62a4386524d0ef269cba3bd6dcadc5a2a11c0d2bdd198773b79bcd8589324328 tests/test_dns_engine.py ec58ba0849d90d2bb7580fe2b8b96cd8299ddfc25f14dc27d9de9d41f152c78a tests/test_dns_server.py -4556bb0bfa6fcd5b98552426c57c99942ee8274eaefec7c316fd64247e4fcd6a tests/test_dump_format.py -9cd5841349bc4db818658d12184929a96f7f279eff1f53ad18a54dbefbd6b276 tests/test_dump_jsonl.py +3dc788fd3adba8b6f766281e0a50025b1ee9150d80ab9a738c6c43f2eaf805b3 tests/test_dump_format.py +118d1987861ed0df978474329adce8c23009b3964210c13fbaf667e0019bbd15 tests/test_dump_jsonl.py 2bbe4b01f79992cfa8884651fc0a28dbd0e3abb0cbea9eb7eadf1f98ca3c3420 tests/test_encoding.py -fe1211ce43a51cd8ec7dd3395aafda8d7313ff60e2ef013072ce9fa49ca4a242 tests/test_entries.py -bb6991260a994fcbe79e05febaa34affd5631d02299fbc626820addd5f6ea4f4 tests/test_error_engine.py -26730151abea598f193131c5d64ef92b531941972f3d6236f9951c3116030b1c tests/test_filesystem.py -16fba97cba6afe8af11aa30bcc4266f53b00f2530161e010af10b51db1509703 tests/test_fingerprint.py -20844dfc758e99b2f757906c51ef32aca0f699283ec5aa629158d3dc0fd279ea tests/test_generic_takeover.py -f1f38f8b8ca667caadcb027d1a20eb895be4ef0935511114db235e66903bb463 tests/test_graphql.py +f4c54b19a294bf392b23dc627781d50894c8e44ca4fe5d7315c98984a3e196a4 tests/test_entries.py +ed7df24ce154e4cbb4462874a38202794664d12b083845bbee9f80481ec9cf52 tests/test_error_engine.py +6f3c214128c7147307c70f0905a0d1aa8118cbbc95086c6fcadce13009fb4946 tests/test_filesystem.py +31fa778c7ee318169961d04ea7b93afc539c24b4114a6a3eaf45698fef57bb4b tests/test_fingerprint.py +abb6eef3d2d08b87b6210dde6dd1333d39da64f5abe5574240fa47efce7528f3 tests/test_generic_takeover.py +b7d59fe68af29d47dda1d7ad77e9b5c91ed50e9efbb976e62e0dc67dd11b3e17 tests/test_graphql.py 50b71422ee91b9a4864f4d5ce6c9bdf169dc5f57ed1db05c152eb010c282136b tests/test_gui_helpers.py 92648f2fe81e22c5726b198bbbda14961cd4d3294a0d9139dcea808b324142ac tests/test_har.py cc7677bc6c568c395112c1aa7d01e1d664e4d5940c86cb4d44987172864bae6f tests/test_hash_crack.py 0336c875dd2b6554bff6eafd746229e38c69ca8070cd933d45cf27c82ef3e05f tests/test_hashdb.py c04e8358fb6df45f69f2f26435c971acde280535bf304e84d30cf2681158c6a7 tests/test_hash.py b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_http2.py -d539d0ae758b5bb91e314ab82ab4fe03d6fb2f8b377d16aefa6d7d1d77a7d5a9 tests/test_identifiers_output.py -5372270b7ed82b62f273c2e9bd1f7ecd8605371e66cd0ad70663762cb08d42f1 tests/test_inference_engine.py +139dcedb9093eb0404ce497549eb6ab7e83ae1e70df8eb42da74ab5a3e7d2a85 tests/test_identifiers_output.py +0a5736b86a47e66d47d44ecf7b8c7531417453fc3e976cd64e9865d3afba78f4 tests/test_inference_engine.py 0fc7bd9bae4fbd09f51027780b7a8e72eab73810dccdfdf87ed9e489e6e671c9 tests/test_ldap.py 571d7761d60a2919985d065893af68eac5d12286f491eaba434c1d8587f913a0 tests/test_library.py -caa06fed7323b2bb6d0f2443ce343de94f75bf8ad012c055d5e07741d908ebad tests/test_misc.py +d2f701f4c3a8621b937ddd322343df91e102af5424ab58675dec4dc7781035b4 tests/test_misc.py 790b78c600b61eb0bdd6e07e14b1db3eb2ddd5fc5d4edb9e975f85ced38558c7 tests/test_nosql.py 88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py a0d173bb595ffbd2b49ee7fb1519d9898aefc262f2565923c4fe41bbc06f57e0 tests/test_openapi.py 6e63ed05db0490148d1c8428d785a23b0d5d5a0f566cd397c9c4a8fe8a6ed7dc tests/test_option.py cde0bea1263ae857561f91ed2bd515e972b716743f017d31b1718a8546c72759 tests/test_pagecontent.py -7554a918309cf0f2cd8a63a3bb7659708f13beffbcd5ce498ece9f9167d55c97 tests/test_parse_modules.py +7297b791aed9278d9252a3ade688e67796eb5c9cc4d6b29e1d2b56d83aa20295 tests/test_parse_modules.py 0d52bf4b96eea2330553fdf7f875ed571e596d2f7a4b3648a2b53e44666f0c70 tests/test_payload_marking.py 6bfc8201724078bd9d6d559916ef73c9ff97e19b0f2948f37e588a49b027795f tests/test_payloads_structure.py d6ffa83bd56ae98e7f55307b72dd7ea4802bccea9a85bb8f062619fb0a88913e tests/test_progress.py -a6d013104601c0414628aff3d8b5b69bee3e6733781d8f8da880457d8b44bd3a tests/test_property.py +2d135eba3ad0fd091962d84742ebf67314fd3f89dcaaa1252b3e3d76fae7c9fd tests/test_property.py c4c6f500bb71c3e430da343a49e8c8b8b3c919f438b6e6130597ce68dd856487 tests/test_purge.py 2dfefb4bfaee3868152835502ec43da317c4f274b1d55cd2ef21e4f7390c9bea tests/test_replication.py -67a5241aeebc20eb1c20cfc490422a59af5179040824e5731bd785db2e6bf750 tests/test_report.py +427a543e17dfede42b9fbccc916fa0aecd93fb7bfb5c280de4c2bca87c5d8de5 tests/test_report.py 4723d3bdf9623a49972e1d7378168ae8efbeaa31fb11c35d83bb40cc135fa0a8 tests/test_request_basic.py cec98d72992c0799229a780fa7f0d7f3fb01ec2d708187ce0e4a05c8612f291b tests/test_safe2bin.py -5b6ce95dddbd07d0126224f4f066643938476e536e18b700ea5d916e1052a715 tests/test_search_enum.py +575ebc336be598858279094072cde1ac9b124109cd7397bd805decd1b0a616d4 tests/test_search_enum.py a1c6cda1e5b483f61e6a4f8ddd0b06a15ddaa3fd2119bfb9dbd9cc970d7a751d tests/test_settings_regex.py 29d0278e3718b0fee422d3f6bb85ca02560138d48cd76f9fe1f35ac19d96071b tests/test_sgmllib.py d3d991331096e16e5019de3d652e9fff92c09bd9f97c50b1c2c3ceb0ed49b17e tests/test_sqlparse.py 412a61053c2531cc0380b34dfd01d52bd118f6a6473728c069c467054c7e3c8e tests/test_ssti.py 8bcbf1091134dd0a62f6201f8b3645ed87b5ff2f7ba40a87231a29dac412591f tests/test_strings.py 8f1c5f0f337ecd26d35c5551060034e0aa33a62cce5385fc1227fdc485f6383e tests/test_tamper.py -67472bd71c20782cc0f738e2c2e674c29d6985669e14d15b69baef7d0e33de62 tests/test_target_parsing.py +b2b3a00254301e5e880e2e77351ebc47eed2c5280477915feedf780ea8cbd34f tests/test_target_parsing.py b3e13febe9e0ff6f97334f2868655bfdbaa18755e464a6dc4c6d424f513bad02 tests/test_targeturl.py -0e644bb7b25c183d0d689ea7be542d7a2ce780cc68067f89afb2ee095a79f762 tests/test_techniques.py +d7d8aaba1d22ee690c8da2c6e28cea0ab45b0d7a6915a5ae7f581c44d7121aab tests/test_techniques.py 639851dc68f62b559b200b09c308e64e453f414969940005bac75dc0ab07a6b6 tests/test_texthelpers.py f49bcce1df533ffa1acfd02af43faf6687b21eebda9362ceb1e5871b8cb37fd4 tests/test_threads.py -708b3c040f8b677a84020dd6f7c4242f77260b3c6d2697fe8189e1881b0e1365 tests/test_union_engine.py +8d23cb42cde68e0da2c4b47db367139d0c53363fef7493ae70b7f6636a1bbbc7 tests/test_union_engine.py 48b0ae4abe0fdde8ce4975c5cbf4c3514a2815021cb2e3a490a189bea5edfe78 tests/test_unpickle_security.py 4b646f513c6da1e33200184ed6eabe0aa345eb2e2a19598dc123e191168591bf tests/test_urls.py -eca021208e388b4d14c53f1e9f8a6e7d685e54ba572fb2a8487e6b620a20bcb5 tests/test_users_enum.py -045f05f958100adc883b3f56613c5f8002dd19d0752225397a1f771775cb2779 tests/_testutils.py +b03689c4dcca0e88a62a88784c61418f963c031d338a357dcc223560c8f9bd22 tests/test_users_enum.py +729b3a5e00fff2e2b6c3acd3fd3e970ac1985c0a6ad1829b23c4099bd409afa1 tests/_testutils.py 2364db35025a53ea4e5a0a80c034997642785f7e6d1566d0d0f1db959fe3c82e tests/test_utils.py 93ef9944effc62d4f744c57bd643137c90fd92205c6a6cbe891e0e99efb80a7f tests/test_wafbypass.py 81bb6d7449f224fa337734ae361c1a340bf9a51768a854d6a1a6e718ed1263ca tests/test_wordlist.py -2698060e7f001e054e345512ce95be458d9902b913afa769398b53145475738a tests/test_xpath.py +9d6dd551b751ab38200ab190c744ec0a9afa798b37f83b0078a4325ab3f80aec tests/test_xpath.py 55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py f597b49ef445bfbfb8f98d1f1a08dcfe4810de5769c0abfab7cdce4eebbfcae7 thirdparty/beautifulsoup/beautifulsoup.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 2caa66593..fa05cc0ed 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.19" +VERSION = "1.10.7.20" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/tests/_testutils.py b/tests/_testutils.py index 781f54749..a856b1ebc 100644 --- a/tests/_testutils.py +++ b/tests/_testutils.py @@ -98,6 +98,22 @@ def set_dbms(name): Backend.forceDbms(name) +def reset_dbms(): + """Clear any DBMS forced via set_dbms()/Backend, restoring the clean post-bootstrap state. + + A forced DBMS lives on the global `kb` singleton and is read by every dialect/agent path, so a + module that forces one without clearing it would leak that back-end into later test modules + (order-dependent flakiness). Modules that call set_dbms() should expose this as their + `tearDownModule` so the leak can never cross a module boundary. + """ + from lib.core.common import Backend + from lib.core.data import kb + from lib.core.settings import UNKNOWN_DBMS_VERSION + Backend.flushForcedDbms(force=True) # kb.forcedDbms = None; kb.stickyDBMS = False + kb.resolutionDbms = None + kb.dbmsVersion = [UNKNOWN_DBMS_VERSION] + + # --- property/fuzz testing harness (shared so individual test files don't each reinvent it) --- _PROPERTY_BASE = 0x51A1 diff --git a/tests/test_agent.py b/tests/test_agent.py index d49a7d76f..203e27896 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -34,7 +34,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.agent import agent @@ -766,3 +766,7 @@ class TestAgentWhereQuery(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_brute.py b/tests/test_brute.py index 3d8143b91..c13395978 100644 --- a/tests/test_brute.py +++ b/tests/test_brute.py @@ -22,7 +22,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -196,3 +196,7 @@ class TestBrute(DbmsStateMixin, unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_common.py b/tests/test_common.py index 87369fe42..73396f0ec 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -19,14 +19,16 @@ irrelevant. Temp files go to the session scratchpad and are removed. stdlib unittest only (no pytest / no pip); works on Python 2.7 and 3.x. """ +import atexit import base64 import os +import shutil import sys import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb, paths @@ -119,7 +121,8 @@ from lib.core.common import ( zeroDepthSearch, ) -SCRATCH = "/tmp/claude-1000/-tmp-tmp-oUnlQJzlQN/fcd55d25-6313-49ed-817e-dcbe7fc2bf22/scratchpad" +SCRATCH = tempfile.mkdtemp(prefix="sqlmap-tests-") # per-run temp dir (portable; replaces a stale hardcoded path) +atexit.register(lambda: shutil.rmtree(SCRATCH, ignore_errors=True)) def _write_temp(content, suffix): @@ -1714,3 +1717,7 @@ class TestCheckOldOptions(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_databases_enum.py b/tests/test_databases_enum.py index 3bba88dde..13cc6a54a 100644 --- a/tests/test_databases_enum.py +++ b/tests/test_databases_enum.py @@ -21,7 +21,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -765,3 +765,7 @@ class TestDatabasesBruteForce(_DbBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dbms_enum.py b/tests/test_dbms_enum.py index dff6a0465..973255063 100644 --- a/tests/test_dbms_enum.py +++ b/tests/test_dbms_enum.py @@ -24,7 +24,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.common import Backend @@ -720,3 +720,7 @@ class TestHSQLDBEnum(_EnumBaseB): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dialect.py b/tests/test_dialect.py index 4cce55abf..5e8212763 100644 --- a/tests/test_dialect.py +++ b/tests/test_dialect.py @@ -20,7 +20,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.agent import agent @@ -105,3 +105,7 @@ class TestForgeUnionQuery(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dns_engine.py b/tests/test_dns_engine.py index 767a5019c..e1194142d 100644 --- a/tests/test_dns_engine.py +++ b/tests/test_dns_engine.py @@ -38,7 +38,7 @@ import time import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.agent import agent @@ -188,7 +188,7 @@ class _DnsCase(unittest.TestCase): finally: c.close() served[0] += len(chunk) - for _ in range(100): + for _ in range(500): # ~5s deadline (was ~1s) - loopback packet can lag on a loaded CI runner with self.server._lock: if any(host.encode() in r for r in self.server._requests): break @@ -313,7 +313,7 @@ class TestDnsLabelInvariant(_DnsCase): finally: c.close() served[0] += len(chunk) - for _ in range(100): + for _ in range(500): # ~5s deadline (was ~1s) - loopback packet can lag on a loaded CI runner with self.server._lock: matched = [r for r in self.server._requests if host.encode() in r] if matched: @@ -394,3 +394,7 @@ class TestDnsChannelDetection(_DnsCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dump_format.py b/tests/test_dump_format.py index ce9076c6b..d3484c28f 100644 --- a/tests/test_dump_format.py +++ b/tests/test_dump_format.py @@ -27,7 +27,7 @@ import unittest from collections import OrderedDict as _PlainOrderedDict sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap +from _testutils import bootstrap, reset_dbms bootstrap() from lib.core.common import Backend @@ -408,3 +408,7 @@ class TestReplication(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dump_jsonl.py b/tests/test_dump_jsonl.py index 9dc5cac8a..515b68bf3 100644 --- a/tests/test_dump_jsonl.py +++ b/tests/test_dump_jsonl.py @@ -26,7 +26,7 @@ import unittest from collections import OrderedDict sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap +from _testutils import bootstrap, reset_dbms bootstrap() from lib.core.common import Backend @@ -165,3 +165,7 @@ class TestJsonlContract(_JsonlDumpCase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_entries.py b/tests/test_entries.py index d54a92bbc..b4cb78dfb 100644 --- a/tests/test_entries.py +++ b/tests/test_entries.py @@ -22,7 +22,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -800,3 +800,7 @@ class TestEntriesInference(_EntriesBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_error_engine.py b/tests/test_error_engine.py index 2c9b54c5a..d13231729 100644 --- a/tests/test_error_engine.py +++ b/tests/test_error_engine.py @@ -22,7 +22,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -111,3 +111,7 @@ class TestOneShotErrorUse(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_filesystem.py b/tests/test_filesystem.py index 70b6192e1..353252f8e 100644 --- a/tests/test_filesystem.py +++ b/tests/test_filesystem.py @@ -28,7 +28,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -733,3 +733,7 @@ class TestUDF(_FsBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_fingerprint.py b/tests/test_fingerprint.py index 0aefbd3da..b583ea061 100644 --- a/tests/test_fingerprint.py +++ b/tests/test_fingerprint.py @@ -18,7 +18,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -93,12 +93,18 @@ class TestFingerprint(unittest.TestCase): conf.batch = True conf.extensiveFp = False conf.api = False + # _drive() stubs the SHARED lib.request.inject module (plugins do `from lib.request import inject`), + # so snapshot the originals and restore them, else stubbed getValue/checkBooleanExpression leak process-wide + import lib.request.inject as _inject + self._inject = _inject + self._inject_saved = (_inject.getValue, _inject.checkBooleanExpression) def tearDown(self): for k, v in self._saved.items(): conf[k] = v for k, v in self._kb.items(): kb[k] = v + self._inject.getValue, self._inject.checkBooleanExpression = self._inject_saved def _drive(self, name, modpath, pkg, oracle): set_dbms(name) @@ -201,3 +207,7 @@ for _name, _mod, _pkg in TARGETS: if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_generic_takeover.py b/tests/test_generic_takeover.py index 89449adf4..40f0f0c9d 100644 --- a/tests/test_generic_takeover.py +++ b/tests/test_generic_takeover.py @@ -26,7 +26,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -599,3 +599,7 @@ class TestTakeover(_GenericBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_graphql.py b/tests/test_graphql.py index 5be9d901b..506e8f102 100644 --- a/tests/test_graphql.py +++ b/tests/test_graphql.py @@ -246,6 +246,7 @@ class TestGraphqlBooleanDetection(unittest.TestCase): def setUp(self): self._gql = gi._gqlSend + self._conf = gi.conf gi.conf = type("C", (), {"url": "http://test/graphql"})() pages = {"true": MATCH, "false": NOMATCH} @@ -259,6 +260,7 @@ class TestGraphqlBooleanDetection(unittest.TestCase): def tearDown(self): gi._gqlSend = self._gql + gi.conf = self._conf def test_boolean_detected(self): slot = _slot("query", "Query", "user", "username", "string") @@ -277,6 +279,7 @@ class TestGraphqlErrorDetection(unittest.TestCase): def setUp(self): self._gql = gi._gqlSend + self._conf = gi.conf gi.conf = type("C", (), {"url": "http://test/graphql"})() def fakeSend(endpoint, query, variables=None): @@ -287,6 +290,7 @@ class TestGraphqlErrorDetection(unittest.TestCase): def tearDown(self): gi._gqlSend = self._gql + gi.conf = self._conf def test_error_detected(self): slot = _slot("query", "Query", "user", "username", "string") @@ -372,10 +376,12 @@ class TestGraphqlIntrospectionFallback(unittest.TestCase): def setUp(self): self._gql = gi._gqlSend + self._conf = gi.conf gi.conf = type("C", (), {"url": "http://test/graphql"})() def tearDown(self): gi._gqlSend = self._gql + gi.conf = self._conf def test_fallback_without_specifiedByURL(self): calls = [] diff --git a/tests/test_identifiers_output.py b/tests/test_identifiers_output.py index dfa27ab27..39a97f066 100644 --- a/tests/test_identifiers_output.py +++ b/tests/test_identifiers_output.py @@ -13,7 +13,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.common import safeSQLIdentificatorNaming, unsafeSQLIdentificatorNaming, safeCSValue @@ -83,3 +83,7 @@ class TestSafeCSValue(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_inference_engine.py b/tests/test_inference_engine.py index bbc0b5a1f..066c70406 100644 --- a/tests/test_inference_engine.py +++ b/tests/test_inference_engine.py @@ -24,7 +24,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -151,3 +151,7 @@ class TestSearchIsLogarithmic(_EngineCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_misc.py b/tests/test_misc.py index d92b72b17..f3bf3faef 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -13,7 +13,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core import common as C @@ -123,3 +123,7 @@ class TestArrayHelpers(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_parse_modules.py b/tests/test_parse_modules.py index 37e90cc2e..f94a4d27b 100644 --- a/tests/test_parse_modules.py +++ b/tests/test_parse_modules.py @@ -18,7 +18,7 @@ import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import kb, conf @@ -173,3 +173,7 @@ class TestConfigFileParser(unittest.TestCase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_property.py b/tests/test_property.py index 04cf72180..789eea476 100644 --- a/tests/test_property.py +++ b/tests/test_property.py @@ -28,7 +28,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, for_all, set_dbms +from _testutils import bootstrap, for_all, set_dbms, reset_dbms bootstrap() from extra.cloak.cloak import cloak, decloak @@ -272,3 +272,7 @@ class TestRobustness(unittest.TestCase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_report.py b/tests/test_report.py index 63c4fd7e0..d5dade141 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -38,6 +38,12 @@ class _CollectorCase(unittest.TestCase): def tearDown(self): kb.partRun = self._saved_partRun + # setupReportCollector() attaches a ReportErrorRecorder to the GLOBAL logger; drop it so it does + # not leak a handler bound to a now-closed collector into later tests + from lib.core.data import logger + for handler in list(logger.handlers): + if isinstance(handler, api.ReportErrorRecorder): + logger.removeHandler(handler) try: self.c.disconnect() except Exception: diff --git a/tests/test_search_enum.py b/tests/test_search_enum.py index ae9437ec7..66b3b850a 100644 --- a/tests/test_search_enum.py +++ b/tests/test_search_enum.py @@ -20,7 +20,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -548,3 +548,7 @@ class TestSearchInference(_SearchBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_target_parsing.py b/tests/test_target_parsing.py index 0dcd8312c..c5a981f4a 100644 --- a/tests/test_target_parsing.py +++ b/tests/test_target_parsing.py @@ -22,6 +22,7 @@ respect to the network, so they are exercised here against real temp dirs. All expected values below were probed from actual output, not assumed. """ +import atexit import os import shutil import sys @@ -29,7 +30,7 @@ import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap +from _testutils import bootstrap, reset_dbms bootstrap() from lib.core.data import conf @@ -62,7 +63,8 @@ from lib.core.target import _setRequestParams from lib.core.target import _setResultsFile from lib.core.target import initTargetEnv -SCRATCH = "/tmp/claude-1000/-tmp-tmp-oUnlQJzlQN/fcd55d25-6313-49ed-817e-dcbe7fc2bf22/scratchpad" +SCRATCH = tempfile.mkdtemp(prefix="sqlmap-tests-") # per-run temp dir (portable; replaces a stale hardcoded path) +atexit.register(lambda: shutil.rmtree(SCRATCH, ignore_errors=True)) # conf/kb keys that the tests below mutate; saved in setUp, restored in tearDown so # one test can never leak global state into another (or into the rest of the suite). @@ -519,3 +521,7 @@ class TestSetResultsFile(_TargetTestBase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_techniques.py b/tests/test_techniques.py index c1f1b6313..6ab50de7e 100644 --- a/tests/test_techniques.py +++ b/tests/test_techniques.py @@ -30,7 +30,7 @@ import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -1518,3 +1518,7 @@ class TestConfigUnion(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_union_engine.py b/tests/test_union_engine.py index 97ac88081..f0592fe4e 100644 --- a/tests/test_union_engine.py +++ b/tests/test_union_engine.py @@ -23,7 +23,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -105,3 +105,7 @@ class TestOrderByColumnCount(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_users_enum.py b/tests/test_users_enum.py index d23e2db17..f20c14328 100644 --- a/tests/test_users_enum.py +++ b/tests/test_users_enum.py @@ -20,7 +20,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -476,3 +476,7 @@ class TestUsersGetUsersInference(_UsersBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_xpath.py b/tests/test_xpath.py index 2c3dcfac1..99903382a 100644 --- a/tests/test_xpath.py +++ b/tests/test_xpath.py @@ -9,8 +9,11 @@ HTTP/lxml layer so detection, fingerprinting, blind inference, payload building, formatting can be exercised without a live target. """ +import os +import sys import unittest +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _testutils import bootstrap bootstrap()