1 from multiprocessing import Process |
1 from multiprocessing import Process |
2 from sqlalchemy import create_engine, pool |
2 from sqlalchemy import create_engine, pool |
|
3 import unittest |
|
4 |
3 |
5 |
4 from tempfile import mkdtemp |
6 from tempfile import mkdtemp |
5 import shutil |
7 import shutil |
6 |
8 |
7 from iro.model.utils import WithSession, POOL_SIZE as DB_POOL_SIZE |
9 from iro.model.utils import WithSession, POOL_SIZE as DB_POOL_SIZE |
8 import iro.model.user as imuser |
|
9 |
10 |
10 from iro.model.schema import User, Base |
11 from iro.model.schema import User, Base |
11 |
12 |
12 from ngdatabase.mysql import Server, createConfig, Database |
13 from ngdatabase.mysql import Server, createConfig, Database |
|
14 |
|
15 from iro.main import runReactor |
|
16 |
|
17 import iro.error as IroError |
|
18 |
|
19 import time |
|
20 |
|
21 from xmlrpclib import Server as xServer, ServerProxy, Fault |
13 |
22 |
14 class SampleDatabase(Database): |
23 class SampleDatabase(Database): |
15 def createPassword(self): |
24 def createPassword(self): |
16 self.password="test" |
25 self.password="test" |
17 return self.password |
26 return self.password |
18 |
27 |
|
28 |
|
29 #activates all logging we can get. |
|
30 |
19 from twisted.python import log |
31 from twisted.python import log |
20 import logging |
32 import logging |
21 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s(%(processName)s)-%(levelname)s: %(message)s') |
33 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s(%(processName)s)-%(levelname)s: %(message)s') |
22 #observer = log.PythonLoggingObserver() |
34 observer = log.PythonLoggingObserver() |
23 #observer.start() |
35 observer.start() |
24 |
36 |
25 def xxxxx(userid): |
37 class XMLRPCTest(unittest.TestCase): |
26 import xmlrpclib |
38 """tests for the xmlrpc interface""" |
27 return xmlrpclib.ServerProxy('http://localhost:7080/RPC2').listMethods() |
39 def setUp(self): |
|
40 self.s = Process(target=startReactor, args=(md.engine,)) |
|
41 self.s.start() |
|
42 #the new process needs time to get stated, so this process has to sleep |
|
43 time.sleep(.2) |
28 |
44 |
29 def main(): |
45 def tearDown(self): |
|
46 self.__debug().stop() |
|
47 time.sleep(.2) |
|
48 self.s.join() |
|
49 |
|
50 def __debug(self): |
|
51 return xServer('http://localhost:7080/debug') |
|
52 |
|
53 def __rpc2(self): |
|
54 return ServerProxy('http://localhost:7080/RPC2') |
|
55 |
|
56 def testDebugHello(self): |
|
57 '''simple test for the connection to xmlrpc server''' |
|
58 ret=self.__debug().hello() |
|
59 self.failUnlessEqual(ret,'hello') |
|
60 |
|
61 def testListMethods(self): |
|
62 '''list of all offical Methods, that can be executed''' |
|
63 ret=self.__rpc2().listMethods() |
|
64 self.failUnlessEqual(ret, ['listMethods', 'status', 'stop', 'sms', 'fax', 'mail', 'routes', 'defaultRoute', 'statistic']) |
|
65 |
|
66 def testStatus(self): |
|
67 ret = self.__rpc2().status('abcdef123456789') |
|
68 self.failUnlessEqual(ret, "<User('test','abcdef123456789')>") |
|
69 |
|
70 def testNoSuchUser(self): |
|
71 '''a unknown user should raise a UserNotNound Exception |
|
72 bewcause xmlrpc only has a Fault exception this Exception has to be deliverd through a xmlrpclib.Fault Exception''' |
|
73 with self.assertRaises(Fault) as fault: |
|
74 self.__rpc2().status('abcdef123456788') |
|
75 exc = fault.exception |
|
76 unf=IroError.UserNotFound() |
|
77 self.failUnlessEqual(exc.faultCode, unf.code) |
|
78 self.failUnlessEqual(exc.faultString, unf.msg) |
|
79 |
|
80 def testNoSuchMethod(self): |
|
81 '''a unknown mothod should raise a Exception ''' |
|
82 with self.assertRaises(Fault) as fault: |
|
83 self.__rpc2().nosuchmethod() |
|
84 exc = fault.exception |
|
85 self.failUnlessEqual(exc.faultCode, 8001) |
|
86 self.failUnlessEqual(exc.faultString, "procedure nosuchmethod not found") |
|
87 |
|
88 def testValidation(self): |
|
89 '''a validate Exception should be translated to a xmlrpclib.Fault.''' |
|
90 with self.assertRaises(Fault) as fault: |
|
91 self.__rpc2().status('xxx') |
|
92 exc = fault.exception |
|
93 self.failUnlessEqual(exc.faultCode, 700) |
|
94 self.failUnlessEqual(exc.faultString, "Validation of 'apikey' failed.") |
|
95 |
|
96 |
|
97 |
|
98 def startReactor(engine): |
|
99 """starts the Rector with a special debug Clild, so that the reactor can be stopped remotly. """ |
30 from twisted.internet import reactor |
100 from twisted.internet import reactor |
31 from twisted.web import xmlrpc, server |
101 from twisted.web import xmlrpc, resource |
32 |
102 |
33 from iro.view.xmlrpc import getResource |
103 from iro.view.xmlrpc import appendResource |
34 |
104 |
35 class XMLRPCDebug(xmlrpc.XMLRPC): |
105 class XMLRPCDebug(xmlrpc.XMLRPC): |
36 def xmlrpc_stop(self): |
106 def xmlrpc_stop(self): |
37 reactor.callLater(0.5,reactor.stop) |
107 reactor.callLater(0.1,reactor.stop) |
38 return "" |
108 return "" |
39 |
109 |
40 root=getResource() |
110 def xmlrpc_hello(self): |
|
111 return "hello" |
|
112 |
|
113 root = resource.Resource() |
|
114 root = appendResource(root) |
41 root.putChild('debug', XMLRPCDebug()) |
115 root.putChild('debug', XMLRPCDebug()) |
42 reactor.listenTCP(7080, server.Site(root)) |
116 runReactor(reactor, engine, root) |
43 logging.info("Server is running now...") |
|
44 reactor.run() |
|
45 |
117 |
|
118 |
|
119 class ModuleData: |
|
120 def __init__(self): |
|
121 self.tdir = mkdtemp(prefix='iro-mysql-') |
|
122 self.server = Server('%s/my.cnf'%self.tdir) |
|
123 self.db = SampleDatabase("test","test",'%s/my.cnf'%self.tdir) |
|
124 self.engine = create_engine('mysql://test:test@localhost/test?unix_socket=%s/socket'%self.tdir, |
|
125 poolclass = pool.SingletonThreadPool, pool_size=DB_POOL_SIZE, ) |
|
126 |
|
127 def setUp(self): |
|
128 with open('%s/my.cnf'%self.tdir,'w') as cnf: |
|
129 cnf.write(createConfig(self.tdir)) |
|
130 self.server.create() |
|
131 self.server.start() |
|
132 self.db.create() |
|
133 Base.metadata.create_all(self.engine) |
|
134 with WithSession(self.engine, autocommit=True) as session: |
|
135 session.add(User(name='test',apikey='abcdef123456789')) |
|
136 |
|
137 def tearDown(self): |
|
138 self.server.stop() |
|
139 shutil.rmtree(self.tdir) |
|
140 |
|
141 |
|
142 md=ModuleData() |
|
143 |
|
144 def setUpModule(): |
|
145 md.setUp() |
|
146 |
|
147 def tearDownModule(): |
|
148 md.tearDown() |
|
149 |
|
150 |
46 if __name__ == '__main__': |
151 if __name__ == '__main__': |
47 tdir = mkdtemp(prefix='iro-mysql-') |
152 unittest.main() |
48 try: |
|
49 with open('%s/my.cnf'%tdir,'w') as cnf: |
|
50 cnf.write(createConfig(tdir)) |
|
51 s = Server('%s/my.cnf'%tdir) |
|
52 s.create() |
|
53 s.start() |
|
54 d=SampleDatabase("test","test",'%s/my.cnf'%tdir) |
|
55 d.create() |
|
56 engine = create_engine('mysql://test:test@localhost/test?unix_socket=%s/socket'%tdir, |
|
57 poolclass = pool.SingletonThreadPool, pool_size=DB_POOL_SIZE, ) |
|
58 |
|
59 imuser.setEngine(engine) |
|
60 |
|
61 try: |
|
62 Base.metadata.create_all(engine) |
|
63 with WithSession(engine, autocommit=True) as session: |
|
64 session.add(User(name='test',apikey='abcdef123456789')) |
|
65 p = Process(target=main) |
|
66 p.start() |
|
67 p.join() |
|
68 finally: |
|
69 s.stop() |
|
70 finally: |
|
71 shutil.rmtree(tdir) |
|