X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=apt_p2p%2Fapt_p2p_conf.py;h=de7cc60aea95e225c99d87bb505e171df8545038;hb=194d18a4f4f1c615eecc7d93f379497e0eb586cd;hp=e5c0f379d8761c0f16e5f7b6ff07a94b28f10975;hpb=6d23f1559df1435172f1da25ae0f57ae11a24bde;p=quix0rs-apt-p2p.git diff --git a/apt_p2p/apt_p2p_conf.py b/apt_p2p/apt_p2p_conf.py index e5c0f37..de7cc60 100644 --- a/apt_p2p/apt_p2p_conf.py +++ b/apt_p2p/apt_p2p_conf.py @@ -14,6 +14,7 @@ import os, sys from ConfigParser import SafeConfigParser from twisted.python import log, versions +from twisted.trial import unittest class ConfigError(Exception): """Errors that occur in the loading of configuration variables.""" @@ -22,7 +23,7 @@ class ConfigError(Exception): def __str__(self): return repr(self.message) -version = versions.Version('apt-p2p', 0, 0, 0) +version = versions.Version('apt-p2p', 0, 1, 0) # Set the home parameter home = os.path.expandvars('${HOME}') @@ -43,6 +44,12 @@ DEFAULTS = { # Set this to 0 to not limit the upload bandwidth. 'UPLOAD_LIMIT': '0', + # The minimum number of peers before the mirror is not used. + # If there are fewer peers than this for a file, the mirror will also be + # used to speed up the download. Set to 0 to never use the mirror if + # there are peers. + 'MIN_DOWNLOAD_PEERS': '3', + # Directory to store the downloaded files in 'CACHE_DIR': home + '/.apt-p2p/cache', @@ -51,12 +58,12 @@ DEFAULTS = { # for everybody to download 'OTHER_DIRS': """""", - # User name to try and run as - 'USERNAME': '', - # Whether it's OK to use an IP address from a known local/private range 'LOCAL_OK': 'no', + # Whether a remote peer can access the statistics page + 'REMOTE_STATS': 'yes', + # Unload the packages cache after an interval of inactivity this long. # The packages cache uses a lot of memory, and only takes a few seconds # to reload when a new request arrives. @@ -64,8 +71,11 @@ DEFAULTS = { # Refresh the DHT keys after this much time has passed. # This should be a time slightly less than the DHT's KEY_EXPIRE value. - 'KEY_REFRESH': '57m', + 'KEY_REFRESH': '2.5h', + # The user name to try and run as (leave blank to run as current user) + 'USERNAME': 'apt-p2p', + # Which DHT implementation to use. # It must be possible to do "from .DHT import DHT" to get a class that # implements the IDHT interface. @@ -82,12 +92,6 @@ DHT_DEFAULTS = { # whether this node is a bootstrap node 'BOOTSTRAP_NODE': "no", - # Kademlia "K" constant, this should be an even number - 'K': '8', - - # SHA1 is 160 bits long - 'HASH_LENGTH': '160', - # checkpoint every this many seconds 'CHECKPOINT_INTERVAL': '5m', # five minutes @@ -117,10 +121,21 @@ DHT_DEFAULTS = { 'BUCKET_STALENESS': '1h', # one hour # expire entries older than this - 'KEY_EXPIRE': '1h', # 60 minutes + 'KEY_EXPIRE': '3h', # 3 hours + + # Timeout KRPC requests to nodes after this time. + 'KRPC_TIMEOUT': '14s', + # KRPC requests are resent using exponential backoff starting with this delay. + # The request will first be resent after the delay set here. + # The request will be resent again after twice the delay set here. etc. + # e.g. if TIMEOUT is 14 sec., and INITIAL_DELAY is 2 sec., then requests will + # be resent at times 0, 2 (2 sec. later), and 6 (4 sec. later), and then will + # timeout at 14. + 'KRPC_INITIAL_DELAY': '2s', + # whether to spew info about the requests/responses in the protocol - 'SPEW': 'yes', + 'SPEW': 'no', } class AptP2PConfigParser(SafeConfigParser): @@ -147,7 +162,7 @@ class AptP2PConfigParser(SafeConfigParser): if suffix in self.time_multipliers.keys(): mult = self.time_multipliers[suffix] value = value[:-1] - return int(value)*mult + return int(float(value)*mult) def getstring(self, section, option): """Read the config parameter as a string.""" @@ -166,3 +181,54 @@ config = AptP2PConfigParser(DEFAULTS) config.add_section(config.get('DEFAULT', 'DHT')) for k in DHT_DEFAULTS: config.set(config.get('DEFAULT', 'DHT'), k, DHT_DEFAULTS[k]) + +class TestConfigParser(unittest.TestCase): + """Unit tests for the config parser.""" + + def test_uppercase(self): + config.set('DEFAULT', 'case_tester', 'foo') + self.failUnless(config.get('DEFAULT', 'CASE_TESTER') == 'foo') + self.failUnless(config.get('DEFAULT', 'case_tester') == 'foo') + config.set('DEFAULT', 'TEST_CASE', 'bar') + self.failUnless(config.get('DEFAULT', 'TEST_CASE') == 'bar') + self.failUnless(config.get('DEFAULT', 'test_case') == 'bar') + config.set('DEFAULT', 'FINAL_test_CASE', 'foobar') + self.failUnless(config.get('DEFAULT', 'FINAL_TEST_CASE') == 'foobar') + self.failUnless(config.get('DEFAULT', 'final_test_case') == 'foobar') + self.failUnless(config.get('DEFAULT', 'FINAL_test_CASE') == 'foobar') + self.failUnless(config.get('DEFAULT', 'final_TEST_case') == 'foobar') + + def test_time(self): + config.set('DEFAULT', 'time_tester_1', '2d') + self.failUnless(config.gettime('DEFAULT', 'time_tester_1') == 2*86400) + config.set('DEFAULT', 'time_tester_2', '3h') + self.failUnless(config.gettime('DEFAULT', 'time_tester_2') == 3*3600) + config.set('DEFAULT', 'time_tester_3', '4m') + self.failUnless(config.gettime('DEFAULT', 'time_tester_3') == 4*60) + config.set('DEFAULT', 'time_tester_4', '37s') + self.failUnless(config.gettime('DEFAULT', 'time_tester_4') == 37) + + def test_floating_time(self): + config.set('DEFAULT', 'time_float_tester_1', '2.5d') + self.failUnless(config.gettime('DEFAULT', 'time_float_tester_1') == int(2.5*86400)) + config.set('DEFAULT', 'time_float_tester_2', '0.5h') + self.failUnless(config.gettime('DEFAULT', 'time_float_tester_2') == int(0.5*3600)) + config.set('DEFAULT', 'time_float_tester_3', '4.3333m') + self.failUnless(config.gettime('DEFAULT', 'time_float_tester_3') == int(4.3333*60)) + + def test_string(self): + config.set('DEFAULT', 'string_test', 'foobar') + self.failUnless(type(config.getstring('DEFAULT', 'string_test')) == str) + self.failUnless(config.getstring('DEFAULT', 'string_test') == 'foobar') + + def test_stringlist(self): + config.set('DEFAULT', 'stringlist_test', """foo + bar + foobar """) + l = config.getstringlist('DEFAULT', 'stringlist_test') + self.failUnless(type(l) == list) + self.failUnless(len(l) == 3) + self.failUnless(l[0] == 'foo') + self.failUnless(l[1] == 'bar') + self.failUnless(l[2] == 'foobar') + \ No newline at end of file