diff --git a/docs/dev/error-codes.md b/docs/dev/error-codes.md new file mode 100644 index 00000000..08d476ac --- /dev/null +++ b/docs/dev/error-codes.md @@ -0,0 +1,4 @@ +# Exit codes + +10: run with no command +3: command does not exist \ No newline at end of file diff --git a/run_tests.sh b/run_tests.sh index 9e23a84d..f5f82a89 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -24,9 +24,9 @@ echo "ran $ran integration tests." echo "total test time $SECONDS" ran=0; -for f in tests/browser-tests/*.py; do - python3 "$f" || close # if needed - let "ran++" -done -echo "ran $ran browser tests." -echo "total test time $SECONDS" \ No newline at end of file +#for f in tests/browser-tests/*.py; do +# python3 "$f" || close # if needed +# let "ran++" +#done +#echo "ran $ran browser tests." +echo "total test time $SECONDS" diff --git a/src/communicatorutils/housekeeping.py b/src/communicatorutils/housekeeping.py index a5ad3896..ba8fe82d 100755 --- a/src/communicatorutils/housekeeping.py +++ b/src/communicatorutils/housekeeping.py @@ -1,9 +1,17 @@ -''' - Onionr - Private P2P Communication +"""Onionr - Private P2P Communication. - Cleanup old Onionr blocks and forward secrecy keys using the communicator. Ran from a timer usually -''' -''' +Cleanup old Onionr blocks and forward secrecy keys using the communicator. +Ran from a communicator timer usually +""" +import sqlite3 +import logger +from onionrusers import onionrusers +from onionrutils import epoch +from coredb import blockmetadb, dbfiles +import onionrstorage +from onionrstorage import removeblock +from onionrblocks import onionrblacklist +""" This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or @@ -16,15 +24,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -''' -import sqlite3 -import logger -from onionrusers import onionrusers -from onionrutils import epoch -from coredb import blockmetadb, dbfiles -import onionrstorage -from onionrstorage import removeblock -from onionrblocks import onionrblacklist +""" + def __remove_from_upload(comm_inst, block_hash: str): try: @@ -32,8 +33,9 @@ def __remove_from_upload(comm_inst, block_hash: str): except ValueError: pass + def clean_old_blocks(comm_inst): - '''Delete old blocks if our disk allocation is full/near full, and also expired blocks''' + """Delete expired blocks + old blocks if disk allocation is near full""" blacklist = onionrblacklist.OnionrBlackList() # Delete expired blocks for bHash in blockmetadb.expiredblocks.get_expired_blocks(): @@ -56,8 +58,9 @@ def clean_old_blocks(comm_inst): comm_inst.decrementThreadCount('clean_old_blocks') + def clean_keys(comm_inst): - '''Delete expired forward secrecy keys''' + """Delete expired forward secrecy keys""" conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10) c = conn.cursor() time = epoch.get_epoch() @@ -75,4 +78,4 @@ def clean_keys(comm_inst): onionrusers.deleteExpiredKeys() - comm_inst.decrementThreadCount('clean_keys') \ No newline at end of file + comm_inst.decrementThreadCount('clean_keys') diff --git a/src/coredb/blockmetadb/add.py b/src/coredb/blockmetadb/add.py index b4d64b37..8874617a 100644 --- a/src/coredb/blockmetadb/add.py +++ b/src/coredb/blockmetadb/add.py @@ -33,7 +33,7 @@ def add_to_block_DB(newHash, selfInsert=False, dataSaved=False): """ if blockmetadata.has_block(newHash): - raise + raise BlockMetaEntryExists conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() currentTime = epoch.get_epoch() + secrets.randbelow(301) diff --git a/src/filepaths/__init__.py b/src/filepaths/__init__.py index 04fde83c..c104f8be 100644 --- a/src/filepaths/__init__.py +++ b/src/filepaths/__init__.py @@ -17,7 +17,7 @@ announce_cache = home + 'announcecache.dat' export_location = home + 'block-export/' upload_list = home + 'upload-list.json' config_file = home + 'config.json' -daemon_mark_file = app_root + '/daemon-true.txt' +daemon_mark_file = home + '/daemon-true.txt' lock_file = home + 'onionr.lock' site_cache = home + 'onionr-sites.txt' diff --git a/src/onionrcommands/parser/__init__.py b/src/onionrcommands/parser/__init__.py index 287e028d..0edda636 100644 --- a/src/onionrcommands/parser/__init__.py +++ b/src/onionrcommands/parser/__init__.py @@ -5,6 +5,12 @@ This module loads in the Onionr arguments and their help messages import sys import os +try: + if sys.argv[1] not in ('start', 'details', 'show-details'): + os.chdir(os.environ['ORIG_ONIONR_RUN_DIR']) +except (KeyError, IndexError) as _: + pass + import logger import onionrexceptions import onionrplugins @@ -74,19 +80,14 @@ def register(): try: cmd = sys.argv[1] except IndexError: - logger.debug("Detected Onionr run with no commands specified") - return + logger.info('Run with --help to see available commands', terminal=True) + sys.exit(10) is_help_cmd = False if cmd.replace('--', '').lower() == 'help': is_help_cmd = True try: - try: - if cmd not in ('start', 'details', 'show-details'): - os.chdir(os.environ['ORIG_ONIONR_RUN_DIR']) - except KeyError: - pass try: arguments.get_func(cmd)() except KeyboardInterrupt: diff --git a/src/runtests/__init__.py b/src/runtests/__init__.py index 4299d386..ca379af0 100644 --- a/src/runtests/__init__.py +++ b/src/runtests/__init__.py @@ -12,6 +12,7 @@ from . import ownnode from .webpasstest import webpass_test from .osver import test_os_ver_endpoint from .clearnettor import test_clearnet_tor_request +from .housekeeping import test_inserted_housekeeping """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,7 +35,8 @@ RUN_TESTS = [uicheck.check_ui, stresstest.stress_test_block_insert, webpass_test, test_os_ver_endpoint, - test_clearnet_tor_request + test_clearnet_tor_request, + test_inserted_housekeeping ] SUCCESS_FILE = os.path.dirname(os.path.realpath(__file__)) + '/../../tests/runtime-result.txt' diff --git a/src/runtests/housekeeping.py b/src/runtests/housekeeping.py new file mode 100644 index 00000000..e6c2042a --- /dev/null +++ b/src/runtests/housekeeping.py @@ -0,0 +1,25 @@ +import os + +from gevent import sleep + +from onionrblocks import insert +import logger +from coredb.blockmetadb import get_block_list +from onionrutils import epoch + + +def test_inserted_housekeeping(testmanager): + """Tests that inserted blocks are proprely deleted""" + bl = insert('testdata', expire=12) + wait_seconds = 132 # Wait two minutes plus expire time + count = 0 + if bl in get_block_list(): + while count < wait_seconds: + if bl in get_block_list(): + sleep(1) + count += 1 + else: + return + raise ValueError('Inserted block with expiry not erased') + else: + raise ValueError('Inserted block in expiry test not present in list') diff --git a/src/utils/identifyhome.py b/src/utils/identifyhome.py index 31dafca7..a73663e0 100644 --- a/src/utils/identifyhome.py +++ b/src/utils/identifyhome.py @@ -29,10 +29,6 @@ def identify_home() -> str: path = os.environ.get('ONIONR_HOME', None) - if path is not None and not os.getcwd().endswith('src') \ - and 'test' not in path: - path = 'src/' + path - if path is None: system = platform.system() if system == 'Linux': diff --git a/tests/integration-tests/export-test.py b/tests/integration-tests/export-test.py index fa374f3b..dcbbb455 100644 --- a/tests/integration-tests/export-test.py +++ b/tests/integration-tests/export-test.py @@ -25,7 +25,10 @@ class OnionrTests(unittest.TestCase): def test_export(self): testargs = ["onionr.py", "flowsend", "tests", "hello"] with patch.object(sys, 'argv', testargs): - parser.register() + try: + parser.register() + except SystemExit: + pass bl = blockmetadb.get_block_list()[0] testargs = ["onionr.py", "export-block", bl] with patch.object(sys, 'argv', testargs): diff --git a/tests/integration-tests/no-command-run.py b/tests/integration-tests/no-command-run.py index 48d051fa..6fd0cadd 100644 --- a/tests/integration-tests/no-command-run.py +++ b/tests/integration-tests/no-command-run.py @@ -7,10 +7,13 @@ TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' os.environ["ONIONR_HOME"] = TEST_DIR print(f'running integration test for {__file__}') -with Popen(['./onionr.sh'], stdout=PIPE) as onionr_proc: - output = onionr_proc.stdout.read().decode() -if onionr_proc.returncode != 0: - raise ValueError('Raised non zero exit ' + str(onionr_proc.returncode)) +try: + with Popen(['./onionr.sh'], stdout=PIPE) as onionr_proc: + output = onionr_proc.stdout.read().decode() +except SystemExit: + pass +if onionr_proc.returncode != 10: + raise ValueError('Raised non 10 exit ' + str(onionr_proc.returncode)) -if output != '': +if 'Run with --help to see available commands' not in output: raise ValueError('No command run returned non-blank output') diff --git a/tests/integration-tests/vanity-test.py b/tests/integration-tests/vanity-test.py index 40d4856f..029596ee 100644 --- a/tests/integration-tests/vanity-test.py +++ b/tests/integration-tests/vanity-test.py @@ -25,7 +25,10 @@ class OnionrTests(unittest.TestCase): def test_vanity(self): testargs = ["onionr.py"] with patch.object(sys, 'argv', testargs): - parser.register() + try: + parser.register() + except SystemExit: + pass testargs = ["onionr.py", "add-vanity", "jolt"] with patch.object(sys, 'argv', testargs): parser.register() diff --git a/tests/runtime-result.txt b/tests/runtime-result.txt index 39f6c82b..13451494 100644 --- a/tests/runtime-result.txt +++ b/tests/runtime-result.txt @@ -1 +1 @@ -1583020786 \ No newline at end of file +1583304780 \ No newline at end of file diff --git a/tests/test_blocks.py b/tests/test_blocks.py index b6c1b458..ddf2f5c1 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -4,6 +4,10 @@ sys.path.append(".") sys.path.append("src/") import unittest, uuid, hashlib +TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR + import onionrblocks import onionrstorage from utils import createdirs @@ -24,7 +28,7 @@ class OnionrBlockTests(unittest.TestCase): bl = onionrblocks.insert(message) self.assertTrue(bl.startswith('0')) self.assertIn(bytesconverter.str_to_bytes(message), onionrstorage.getData(bl)) - + def test_encrypted_insert(self): setup_test() message = 'hello world2' diff --git a/tests/test_commands_basic.py b/tests/test_commands_basic.py index 0bad6830..ea7cde0d 100644 --- a/tests/test_commands_basic.py +++ b/tests/test_commands_basic.py @@ -11,10 +11,6 @@ from onionrcommands import parser import onionrsetup as setup from netcontroller.torcontrol import customtorrc class OnionrTests(unittest.TestCase): - def test_no_command(self): - testargs = ["onionr.py"] - with patch.object(sys, 'argv', testargs): - parser.register() def test_version_command(self): testargs = ["onionr.py", "version"] with patch.object(sys, 'argv', testargs): diff --git a/tests/test_duplicate_block_meta_entry.py b/tests/test_duplicate_block_meta_entry.py new file mode 100644 index 00000000..3e38e401 --- /dev/null +++ b/tests/test_duplicate_block_meta_entry.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +import sys, os +sys.path.append(".") +sys.path.append("src/") +import unittest, uuid +import json +TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR + +from utils import identifyhome, createdirs +from onionrsetup import setup_config +from coredb import blockmetadb +from onionrexceptions import BlockMetaEntryExists +createdirs.create_dirs() +setup_config() + +class TestDuplicateMetaEntry(unittest.TestCase): + def test_no_duplicate(self): + bl_hash = '0c88c7d4515363310f0a2522706c49f3f21def5f6fd69af1f91a1849239e7ea6' + blockmetadb.add_to_block_DB(bl_hash) + self.assertRaises( + BlockMetaEntryExists, blockmetadb.add_to_block_DB, bl_hash) + +unittest.main() diff --git a/tests/test_identifyhome.py b/tests/test_identifyhome.py index a2bc9e3f..b2cd3705 100644 --- a/tests/test_identifyhome.py +++ b/tests/test_identifyhome.py @@ -1,7 +1,10 @@ #!/usr/bin/env python3 -import sys, os +import sys, os, uuid sys.path.append(".") sys.path.append("src/") +TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR import unittest, uuid from utils import identifyhome diff --git a/tests/test_timeinsert.py b/tests/test_timeinsert.py index 3d637020..c351aaff 100644 --- a/tests/test_timeinsert.py +++ b/tests/test_timeinsert.py @@ -1,10 +1,19 @@ #!/usr/bin/env python3 -import unittest, sys +import sys, os sys.path.append(".") sys.path.append("src/") - +import unittest, uuid +TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR from onionrblocks import time_insert from onionrblocks import onionrblockapi +from onionrsetup import setup_config, setup_default_plugins +from utils import createdirs + +createdirs.create_dirs() +setup_config() +setup_default_plugins() class TestTimeInsert(unittest.TestCase): def test_time_insert_none(self): diff --git a/tests/test_vanity.py b/tests/test_vanity.py index f7ec76db..75b5db1c 100644 --- a/tests/test_vanity.py +++ b/tests/test_vanity.py @@ -1,6 +1,10 @@ import sys, os +import uuid sys.path.append(".") sys.path.append("src/") +TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR import unittest import vanityonionr diff --git a/tests/test_zfill.py b/tests/test_zfill.py index d706f1e5..dca76314 100644 --- a/tests/test_zfill.py +++ b/tests/test_zfill.py @@ -1,5 +1,8 @@ #!/usr/bin/env python3 -import unittest, sys +import unittest, sys, uuid, os +TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR sys.path.append(".") sys.path.append("src/") @@ -11,7 +14,7 @@ class ZFill_Hash(unittest.TestCase): self.assertEqual(reconstructhash.reconstruct_hash(h), b"0000" + h) h = b"4d20d791cbc293999b97cc627aa011692d317dede3d0fbd390c763210b0d" self.assertEqual(reconstructhash.reconstruct_hash(h, 62), b"00" + h) - + def test_deconstruct(self): h = b"0000e918d24999ad9b0ff00c1d414f36b74afc93871a0ece4bd452f82b56af87" h_no = b"e918d24999ad9b0ff00c1d414f36b74afc93871a0ece4bd452f82b56af87"