1 """Test the various means of instantiating and invoking tools."""
2
3 import gzip, StringIO
4 import time
5 timeout = 0.2
6
7 import types
8 from cherrypy.test import test
9 test.prefer_parent_path()
10
11 import cherrypy
12 from cherrypy import tools
13
14
15 europoundUnicode = u'\x80\xa3'
16
25 myauthtools.check_access = cherrypy.Tool('before_request_body', check_access)
26
27 def numerify():
28 def number_it(body):
29 for chunk in body:
30 for k, v in cherrypy.request.numerify_map:
31 chunk = chunk.replace(k, v)
32 yield chunk
33 cherrypy.response.body = number_it(cherrypy.response.body)
34
35 class NumTool(cherrypy.Tool):
36 def _setup(self):
37 def makemap():
38 m = self._merged_args().get("map", {})
39 cherrypy.request.numerify_map = m.items()
40 cherrypy.request.hooks.attach('on_start_resource', makemap)
41
42 def critical():
43 cherrypy.request.error_response = cherrypy.HTTPError(502).set_response
44 critical.failsafe = True
45
46 cherrypy.request.hooks.attach('on_start_resource', critical)
47 cherrypy.request.hooks.attach(self._point, self.callable)
48
49 tools.numerify = NumTool('before_finalize', numerify)
50
51
52 class NadsatTool:
53
54 def __init__(self):
55 self.ended = {}
56 self._name = "nadsat"
57
58 def nadsat(self):
59 def nadsat_it_up(body):
60 for chunk in body:
61 chunk = chunk.replace("good", "horrorshow")
62 chunk = chunk.replace("piece", "lomtick")
63 yield chunk
64 cherrypy.response.body = nadsat_it_up(cherrypy.response.body)
65 nadsat.priority = 0
66
67 def cleanup(self):
68
69 cherrypy.response.body = "razdrez"
70 id = cherrypy.request.params.get("id")
71 if id:
72 self.ended[id] = True
73 cleanup.failsafe = True
74
75 def _setup(self):
76 cherrypy.request.hooks.attach('before_finalize', self.nadsat)
77 cherrypy.request.hooks.attach('on_end_request', self.cleanup)
78 tools.nadsat = NadsatTool()
79
80 def pipe_body():
81 cherrypy.request.process_request_body = False
82 clen = int(cherrypy.request.headers['Content-Length'])
83 cherrypy.request.body = cherrypy.request.rfile.read(clen)
84
85
86 class Rotator(object):
87 def __call__(self, scale):
88 r = cherrypy.response
89 r.collapse_body()
90 r.body = [chr(ord(x) + scale) for x in r.body]
91 cherrypy.tools.rotator = cherrypy.Tool('before_finalize', Rotator())
92
93 class Root:
94 def index(self):
95 return "Howdy earth!"
96 index.exposed = True
97
98 def euro(self):
99 hooks = list(cherrypy.request.hooks['before_finalize'])
100 hooks.sort()
101 assert [x.callback.__name__ for x in hooks] == ['encode', 'gzip']
102 assert [x.priority for x in hooks] == [70, 80]
103 yield u"Hello,"
104 yield u"world"
105 yield europoundUnicode
106 euro.exposed = True
107
108
109 def pipe(self):
110 return cherrypy.request.body
111 pipe.exposed = True
112 pipe._cp_config = {'hooks.before_request_body': pipe_body}
113
114
115
116 def decorated_euro(self, *vpath):
117 yield u"Hello,"
118 yield u"world"
119 yield europoundUnicode
120 decorated_euro.exposed = True
121 decorated_euro = tools.gzip(compress_level=6)(decorated_euro)
122 decorated_euro = tools.encode(errors='ignore')(decorated_euro)
123
124 root = Root()
125
126
127 class TestType(type):
128 """Metaclass which automatically exposes all functions in each subclass,
129 and adds an instance of the subclass as an attribute of root.
130 """
131 def __init__(cls, name, bases, dct):
132 type.__init__(name, bases, dct)
133 for value in dct.itervalues():
134 if isinstance(value, types.FunctionType):
135 value.exposed = True
136 setattr(root, name.lower(), cls())
137 class Test(object):
138 __metaclass__ = TestType
139
140
141
142
143 class Demo(Test):
144
145 _cp_config = {"tools.nadsat.on": True}
146
147 def index(self, id=None):
148 return "A good piece of cherry pie"
149
150 def ended(self, id):
151 return repr(tools.nadsat.ended[id])
152
153 def err(self, id=None):
154 raise ValueError()
155
156 def errinstream(self, id=None):
157 raise ValueError()
158 yield "confidential"
159
160
161
162
163 def restricted(self):
164 return "Welcome!"
165 restricted = myauthtools.check_access()(restricted)
166 userid = restricted
167
168 def err_in_onstart(self):
169 return "success!"
170
171 def stream(self, id=None):
172 for x in xrange(100000000):
173 yield str(x)
174 stream._cp_config = {'response.stream': True}
175
176
177 cherrypy.config.update({'environment': 'test_suite'})
178
179 conf = {
180
181
182 '/demo': {
183 'tools.numerify.on': True,
184 'tools.numerify.map': {"pie": "3.14159"},
185 },
186 '/demo/restricted': {
187 'request.show_tracebacks': False,
188 },
189 '/demo/userid': {
190 'request.show_tracebacks': False,
191 'myauth.check_access.default': True,
192 },
193 '/demo/errinstream': {
194 'response.stream': True,
195 },
196 '/demo/err_in_onstart': {
197
198 'tools.numerify.map': "pie->3.14159"
199 },
200
201 '/euro': {
202 'tools.gzip.on': True,
203 'tools.encode.on': True,
204 },
205
206 '/decorated_euro/subpath': {
207 'tools.gzip.priority': 10,
208 },
209 }
210 cherrypy.tree.mount(root, config=conf)
211
212
213
214
215 from cherrypy.test import helper
216
217