# HG changeset patch # User Sandro Knauß # Date 1330182727 -3600 # Node ID b381eaa774abcf1ea038a87f5158f03367999b8a # Parent 8ad6c097bc5b2ade4c3f766837606278827717e9 refactoring ifo.config diff -r 8ad6c097bc5b -r b381eaa774ab iro/config.py --- a/iro/config.py Thu Feb 23 16:59:49 2012 +0100 +++ b/iro/config.py Sat Feb 25 16:12:07 2012 +0100 @@ -1,11 +1,11 @@ -from ConfigParser import ConfigParser, NoOptionError +from ConfigParser import ConfigParser import signal from functools import partial from validate import vInteger -from error import ValidateException +from error import NeededOption -class Config(ConfigParser): +class MyConfigParser(ConfigParser): def __init__(self): ConfigParser.__init__(self) self.reloadList=[] @@ -15,16 +15,9 @@ ConfigParser.read(self, files) for s in self.sections(): if s == "main": - opts=main - for o in opts: - try: - opts[o].validate(self.get(s,o),o) - except (ValidateException, NoOptionError): - if opts[o].must: - raise + main.validate(self.items(s)) else: getProvider("tmp", self.get(s,'typ'), self.items(s)) - def reload_(self): for f in self.reloadList: @@ -41,9 +34,54 @@ self.must = must self.default = default +class Config(): + def __init__(self, name): + self.name = name + self.options={ + "hostname":Option(lambda x,y:x,long="Hostname under that twisted is running",must=True), + "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True), + "dburl":Option(lambda x,y:x,long="Connection URL to database",must=True), + } + self.read=False + + + def _read(self, cfg, write=False): + c = dict(cfg) + for o in self.options: + option = self.options[o] + try: + value = option.validate(c[o],o) + if write: + self.read = True + setattr(self,o,value) + except KeyError: + if option.must: + raise NeededOption(self.name, o) + elif write and option.default is not None: + setattr(self, o, option.default) + + def validate(self, cfg): + self._read(cfg, False) + + def load(self, cfg): + self._read(cfg, True) + + def same(self, other): + for o in self.options: + if getattr(self,o) != getattr(other,o): + return False + else: + return True + def readConfig(): - config.read(confFiles) - config.reload() + configParser.read(confFiles) + configParser.reload() + if not main.read: + main.load(configParser.items("main")) + else: + m = Config("main").load(configParser.items("main")) + if not main.same(m): + raise Exception("Main options can't be reloaded, you have to restart.") def registerSignal(): '''register readConfig to SIGUSR2''' @@ -52,8 +90,7 @@ signal.signal(signal.SIGUSR2,rC) -config=Config() +configParser = MyConfigParser() confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"] -main={"hostname":Option(lambda x,y:x,long="Hostname under that twisted is running",must=True), - "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True), - } + +main = Config("main") diff -r 8ad6c097bc5b -r b381eaa774ab iro/model/offer.py --- a/iro/model/offer.py Thu Feb 23 16:59:49 2012 +0100 +++ b/iro/model/offer.py Sat Feb 25 16:12:07 2012 +0100 @@ -1,7 +1,7 @@ from .dbdefer import dbdefer import schema -from ..config import config +from ..config import configParser from ..offer import getProvider, Offer @dbdefer @@ -22,8 +22,8 @@ def loadOffers(session): offers.clear() providers.clear() - for provider in ( s for s in config.sections() if not s in ["main",]): - p=getProvider(provider,config.get(provider,"typ"),config.items(provider)) + for provider in ( s for s in configParser.sections() if not s in ["main",]): + p=getProvider(provider,configParser.get(provider,"typ"),configParser.items(provider)) for t in p.typs: for r in p.typs[t]: n = schema.Offer.get(session, provider, r, t).name @@ -33,5 +33,5 @@ offers={} providers={} -config.registerReload(loadOffers) +configParser.registerReload(loadOffers) diff -r 8ad6c097bc5b -r b381eaa774ab iro/offer/provider.py --- a/iro/offer/provider.py Thu Feb 23 16:59:49 2012 +0100 +++ b/iro/offer/provider.py Sat Feb 25 16:12:07 2012 +0100 @@ -1,35 +1,18 @@ from functools import partial -from ..error import NoRoute, NoTyp, ValidateException, NoProvider, NeededOption -from ..config import Option +from ..error import NoRoute, NoTyp, ValidateException, NoProvider +from ..config import Option, Config -class Provider(): - def __init__(self, name, config, typs={}): - self.name = name - self.config = config +class Provider(Config): + def __init__(self, name, typs={}): + Config.__init__(self, name) self.typs=typs self.testmode = False - + self.options = { "typ":Option(vProvider, long="One available provider typ.", must=True) } - def loadConfig(self): - c=dict(self.config) - for o in self.options: - try: - value = self.options[o].validate(c[o],o) - setattr(self, o, value) - except (KeyError): - if self.options[o].must: - raise NeededOption(self.name, o) - elif self.options[o].default is not None: - setattr(self,o,self.options[o].default) - - for (n, v) in self.config: - if n == "typ": - self.typ = v - def send(self, typ, route, recipient, message): pass @@ -43,7 +26,9 @@ def getProvider(name, typ, config): try: - return providers[typ](name,config) + p = providers[typ](name) + p.load(config) + return p except KeyError: raise NoProvider(typ) diff -r 8ad6c097bc5b -r b381eaa774ab iro/offer/smstrade.py --- a/iro/offer/smstrade.py Thu Feb 23 16:59:49 2012 +0100 +++ b/iro/offer/smstrade.py Sat Feb 25 16:12:07 2012 +0100 @@ -79,13 +79,12 @@ "count":('boolean',False), "cost":('boolean',False), } - def __init__(self, name, config): + def __init__(self, name): self.url = "https://gateway.smstrade.de" - Provider.__init__(self,name,config,{"sms":["basic","economy","gold","direct"]}) + Provider.__init__(self, name, {"sms":["basic","economy","gold","direct"]}) self.options.update({ "key":Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True) }) - self.loadConfig() def send(self, route, sms, recipient): """send SMS with $sms to $recipients""" diff -r 8ad6c097bc5b -r b381eaa774ab iro/offer/smtp.py --- a/iro/offer/smtp.py Thu Feb 23 16:59:49 2012 +0100 +++ b/iro/offer/smtp.py Sat Feb 25 16:12:07 2012 +0100 @@ -21,8 +21,8 @@ from .provider import Provider, providers class SMTP(Provider): - def __init__(self, name, config): - Provider.__init__(self,name,config,{"mail":[None]}) + def __init__(self, name): + Provider.__init__(self,name,{"mail":[None]}) self.options.update({ "send_from":Option(vEmail,long="Emailaddress from which mail will be sended.",must=True), "host":Option(lambda x,y:x, long="Hostname of MTA", must=True), @@ -32,7 +32,6 @@ "TLS":Option(vBool,long="use TLS for connection to MTA", default=False), "SSL":Option(vBool,long="use SSL for connection to MTA", default=False), }) - self.loadConfig() def send(self,mail,recipient): if not self.testmode: diff -r 8ad6c097bc5b -r b381eaa774ab tests/config.py --- a/tests/config.py Thu Feb 23 16:59:49 2012 +0100 +++ b/tests/config.py Sat Feb 25 16:12:07 2012 +0100 @@ -3,25 +3,29 @@ import signal import io import ConfigParser -from iro import config +from iro import config, error from iro.offer.provider import Provider, providers class TestConfig(unittest.TestCase): '''test config class''' def setUp(self): - self._reloadList=config.config.reloadList - config.config.reloadList=[] + self._reloadList=config.configParser.reloadList + config.configParser.reloadList=[] def tearDown(self): - config.config.reloadList = self._reloadList + config.configParser.reloadList = self._reloadList - @patch('iro.config.config') - def testReadConfig(self,pConfig): + @patch('iro.config.main') + @patch('iro.config.configParser') + def testReadConfig(self,pConfig,pMain): + pMain.read = False config.readConfig() - self.assertEqual([i[0] for i in pConfig.method_calls],["read","reload"]) + self.assertEqual([i[0] for i in pConfig.method_calls],["read","reload","items"]) pConfig.read.assert_called_once_with(config.confFiles) + pConfig.items.assert_called_once_with("main") pConfig.reload.assert_called_once_with() + self.assertEqual(pMain.load.called,1) @patch('signal.signal') @patch('iro.config.readConfig') @@ -35,93 +39,97 @@ def testRegisterReload(self): def x(): pass - config.config.registerReload(x) - self.assertEqual(config.config.reloadList,[x]) + config.configParser.registerReload(x) + self.assertEqual(config.configParser.reloadList,[x]) def testReload(self): x = Mock() - config.config.reloadList = [x] - config.config.reload_() + config.configParser.reloadList = [x] + config.configParser.reload_() x.assert_called_once_with() class TestRead(unittest.TestCase): def tearDown(self): - for s in config.config.sections(): - config.config.remove_section(s) + for s in config.configParser.sections(): + config.configParser.remove_section(s) @patch('iro.config.ConfigParser.read') def testMain(self,pRead): sample_config = """[main] hostname = localhost port = 8000 +dburl = sdfdsafgsfdg """ - config.config.readfp(io.BytesIO(sample_config)) - config.config.read([]) - pRead.assert_called_once_with(config.config,[]) + config.configParser.readfp(io.BytesIO(sample_config)) + config.configParser.read([]) + pRead.assert_called_once_with(config.configParser,[]) @patch('iro.config.ConfigParser.read') def testMainBadPort(self,pRead): sample_config = """[main] hostname = localhost port = -8000 +dburl = sadfaserasg """ - config.config.readfp(io.BytesIO(sample_config)) - self.assertRaises(config.ValidateException, config.config.read, []) + config.configParser.readfp(io.BytesIO(sample_config)) + self.assertRaises(error.ValidateException, config.configParser.read, []) @patch('iro.config.ConfigParser.read') def testMainNoMust(self,pRead): sample_config = """[main] port = 8000 +dburl = asdfgdsrg """ - config.config.readfp(io.BytesIO(sample_config)) - self.assertRaises(ConfigParser.NoOptionError, config.config.read, []) + config.configParser.readfp(io.BytesIO(sample_config)) + self.assertRaises(config.NeededOption, config.configParser.read, []) @patch('iro.config.ConfigParser.read') def testMust(self,pRead): v=Mock() - config.main["test"] = config.Option(v) + config.main.options["test"] = config.Option(v) try: sample_config = """[main] hostname = localhost +dburl = sdfawersdf port = 8000 """ - config.config.readfp(io.BytesIO(sample_config)) - config.config.read([]) + config.configParser.readfp(io.BytesIO(sample_config)) + config.configParser.read([]) self.assertEqual(v.called,0) sample_config = """[main] hostname = localhost +dburl = adfgsdftsfg port = 8000 test = foohu """ - config.config.readfp(io.BytesIO(sample_config)) - config.config.read([]) + config.configParser.readfp(io.BytesIO(sample_config)) + config.configParser.read([]) v.assert_called_once_with("foohu","test") finally: - del(config.main["test"]) + del(config.main.options["test"]) @patch('iro.config.ConfigParser.read') def testProviders(self, pRead): v=Mock() class TestProvider(Provider): - def __init__(self,name,c): - Provider.__init__(self,name,c) + def __init__(self,name): + Provider.__init__(self,name) self.options.update({"test":config.Option(v)}) - self.loadConfig() providers["test"]=TestProvider try: sample_config = """[p] """ - config.config.readfp(io.BytesIO(sample_config)) - self.assertRaises(ConfigParser.NoOptionError, config.config.read, []) + config.configParser.readfp(io.BytesIO(sample_config)) + self.assertRaises(ConfigParser.NoOptionError, config.configParser.read, []) self.assertEqual(v.called,0) sample_config = """[p] typ= test test= foo """ - config.config.readfp(io.BytesIO(sample_config)) - config.config.read([]) + config.configParser.readfp(io.BytesIO(sample_config)) + config.configParser.read([]) v.assert_called_once_with("foo","test") finally: del(providers["test"]) diff -r 8ad6c097bc5b -r b381eaa774ab tests/job.py --- a/tests/job.py Thu Feb 23 16:59:49 2012 +0100 +++ b/tests/job.py Sat Feb 25 16:12:07 2012 +0100 @@ -126,7 +126,7 @@ self.user = u self.offer = o - self.provider=Provider("bla", [], {"sms":["a","b","c"]}) + self.provider=Provider("bla", {"sms":["a","b","c"]}) self.job = exJobs.create(u, [Telnumber('123456789')], SMS('test'), []) def tearDown(self): diff -r 8ad6c097bc5b -r b381eaa774ab tests/offer.py --- a/tests/offer.py Thu Feb 23 16:59:49 2012 +0100 +++ b/tests/offer.py Sat Feb 25 16:12:07 2012 +0100 @@ -4,7 +4,7 @@ import io from iro.model import offer -from iro.config import config +from iro.config import configParser from iro.offer import Offer, providers as OfferProviders, Provider from iro.model.schema import User, Offer as DBOffer, Userright from iro.controller.pool import dbPool @@ -18,8 +18,8 @@ dbPool.start(reactor) def tearDown(self): - for s in config.sections(): - config.remove_section(s) + for s in configParser.sections(): + configParser.remove_section(s) dbPool.pool.stop() offer.offers.clear() @@ -34,7 +34,7 @@ def testReloadList(self): '''test if loadOffers will be fired by reloading Config''' - self.assertTrue(offer.loadOffers in config.reloadList) + self.assertTrue(offer.loadOffers in configParser.reloadList) @inlineCallbacks def testExtendProviderUnknown(self): @@ -72,7 +72,7 @@ o=DBOffer(name="oh", provider="bla", route="a", typ="sms") u.rights.append(Userright(o)) - offer.providers={"bla":Provider("bla", [], {"sms":["a","b","c"]})} + offer.providers={"bla":Provider("bla", {"sms":["a","b","c"]})} for l in [['bla'],['oh'],['oh','bla'],['bla','oh']]: ret = yield offer.extendProvider(u, "sms", l) @@ -89,7 +89,7 @@ o=DBOffer(name="a", provider="bla", route="b", typ="sms") u.rights.append(Userright(o)) - offer.providers={"bla":Provider("bla", [], {"sms":["a","b","c"]})} + offer.providers={"bla":Provider("bla", {"sms":["a","b","c"]})} ret = yield offer.extendProvider(u, "sms", ["bla"]) self.assertEqual(ret, ["oh","a"]) @@ -104,9 +104,8 @@ def testLoadOffers(self): class TestProvider(Provider): - def __init__(self,name,config): - Provider.__init__(self,name,config,{"sms":["a",]}) - self.loadConfig() + def __init__(self,name): + Provider.__init__(self,name,{"sms":["a",]}) with self.session() as session: session.add(DBOffer(name="oh", provider="p", route="a", typ="sms")) @@ -114,7 +113,7 @@ sample_config = """[p] typ = test """ - config.readfp(io.BytesIO(sample_config)) + configParser.readfp(io.BytesIO(sample_config)) OfferProviders["test"]=TestProvider yield offer.loadOffers() self.assertEqual(offer.offers.keys(),["oh"]) @@ -130,7 +129,7 @@ sample_config = """[p] typ = unknown """ - config.readfp(io.BytesIO(sample_config)) + configParser.readfp(io.BytesIO(sample_config)) d = offer.loadOffers() self.assertFailure(d, NoProvider) return d diff -r 8ad6c097bc5b -r b381eaa774ab tests/smstrade.py --- a/tests/smstrade.py Thu Feb 23 16:59:49 2012 +0100 +++ b/tests/smstrade.py Sat Feb 25 16:12:07 2012 +0100 @@ -13,14 +13,16 @@ class TestSMStradeProvider(unittest.TestCase): def getProvider(self, c=None): - ret={"key":"XXXXXX", + _c={"key":"XXXXXXXX", "typ":"smstrade", } if c: - ret.update(c) + _c.update(c) - return Smstrade("test",ret.items()) + ret = Smstrade("test") + ret.load(_c.items()) + return ret @patch("urllib.urlopen") def testSendSMS(self,mock_urlopen): @@ -28,7 +30,7 @@ f.readlines.return_value = ["100","12345678","0.055","1"] mock_urlopen.return_value = f - params = ["key=XXXXXX","to=00491701234567", "message=Hello+World", "route=gold", "message_id=1", "cost=1","count=1",'charset=utf-8'] + params = ["key=XXXXXXXX","to=00491701234567", "message=Hello+World", "route=gold", "message_id=1", "cost=1","count=1",'charset=utf-8'] params.sort() p=self.getProvider() @@ -49,11 +51,10 @@ testStatusCode.todo = "to implement" def testNeededOption(self): - c={"key":"XXXXXXXX","typ":"smstrade"} - s=Smstrade("test",c.items()) + s= self.getProvider() self.assertEqual(s.key, "XXXXXXXX") - self.assertRaises(NeededOption,Smstrade,"test",[]) + self.assertRaises(NeededOption, s.load,[]) def testSendFunc(self): s = self.getProvider() diff -r 8ad6c097bc5b -r b381eaa774ab tests/smtp.py --- a/tests/smtp.py Thu Feb 23 16:59:49 2012 +0100 +++ b/tests/smtp.py Sat Feb 25 16:12:07 2012 +0100 @@ -24,16 +24,18 @@ self.smtp_server.close() def getSMTP(self, c=None): - ret={"send_from":"send@t.de", + _c={"send_from":"send@t.de", "host":HOST, "port":PORT, "typ":"smtp", } if c: - ret.update(c) + _c.update(c) - return SMTP("test",ret.items()) + ret = SMTP("test") + ret.load(_c.items()) + return ret def testSendMail(self): p=self.getSMTP() @@ -120,7 +122,7 @@ "password":"p", "typ":"smtp", } - s=SMTP("test",c.items()) + s = self.getSMTP(c) self.assertEqual(s.send_from, "send@t.de") self.assertEqual(s.host, HOST) self.assertEqual(s.port, PORT) @@ -130,12 +132,12 @@ self.assertEqual(s.TLS,False) c.update({"TLS":True, "SSL":True}) - s=SMTP("test", c.items()) + s = self.getSMTP(c) self.assertEqual(s.SSL,True) self.assertEqual(s.TLS,True) del c["host"] - self.assertRaises(NeededOption,SMTP,"test",c.items()) + self.assertRaises(NeededOption, s.load, c) def testSendFunc(self): s = self.getSMTP() diff -r 8ad6c097bc5b -r b381eaa774ab tests/task.py --- a/tests/task.py Thu Feb 23 16:59:49 2012 +0100 +++ b/tests/task.py Sat Feb 25 16:12:07 2012 +0100 @@ -54,7 +54,7 @@ o=DBOffer(name="test", provider="bla", route="basic", typ="sms") u.rights.append(Userright(o)) - p=Provider(name="p", config={}, typs={"sms":["test",]}) + p=Provider(name="p", typs={"sms":["test",]}) def send(typ,route,recipient,message): return Status(provider=p, route=route) p.send=send