X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=apt_p2p%2Fapt_p2p_conf.py;h=8494a0be7119419cc3e3d7a16fda4c8815a07040;hb=d23afa1f067faf56007facad2dcd204f77e2a984;hp=c4ecb93aad214de4fa63227a90bbb89d8392eea6;hpb=ce20dde0bf4440dbb651bae51f85750aa8afdb8e;p=quix0rs-apt-p2p.git diff --git a/apt_p2p/apt_p2p_conf.py b/apt_p2p/apt_p2p_conf.py index c4ecb93..8494a0b 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.""" @@ -39,6 +40,16 @@ DEFAULTS = { # Port to listen on for all requests (TCP and UDP) 'PORT': '9977', + # The rate to limit sending data to peers to, in KBytes/sec. + # 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', @@ -47,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 addres from a known local/private range + # 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. @@ -60,10 +71,13 @@ 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 possile to do "from .DHT import DHT" to get a class that + # It must be possible to do "from .DHT import DHT" to get a class that # implements the IDHT interface. 'DHT': 'apt_p2p_Khashmir', @@ -78,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 @@ -113,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): @@ -143,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.""" @@ -162,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