testing/mozbase/mozhttpd/tests/api.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 #!/usr/bin/env python
michael@0 2
michael@0 3 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 # You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 6
michael@0 7 import mozhttpd
michael@0 8 import urllib2
michael@0 9 import os
michael@0 10 import unittest
michael@0 11 import re
michael@0 12 import json
michael@0 13 import tempfile
michael@0 14
michael@0 15 here = os.path.dirname(os.path.abspath(__file__))
michael@0 16
michael@0 17 class ApiTest(unittest.TestCase):
michael@0 18 resource_get_called = 0
michael@0 19 resource_post_called = 0
michael@0 20 resource_del_called = 0
michael@0 21
michael@0 22 @mozhttpd.handlers.json_response
michael@0 23 def resource_get(self, request, objid):
michael@0 24 self.resource_get_called += 1
michael@0 25 return (200, { 'called': self.resource_get_called,
michael@0 26 'id': objid,
michael@0 27 'query': request.query })
michael@0 28
michael@0 29 @mozhttpd.handlers.json_response
michael@0 30 def resource_post(self, request):
michael@0 31 self.resource_post_called += 1
michael@0 32 return (201, { 'called': self.resource_post_called,
michael@0 33 'data': json.loads(request.body),
michael@0 34 'query': request.query })
michael@0 35
michael@0 36 @mozhttpd.handlers.json_response
michael@0 37 def resource_del(self, request, objid):
michael@0 38 self.resource_del_called += 1
michael@0 39 return (200, { 'called': self.resource_del_called,
michael@0 40 'id': objid,
michael@0 41 'query': request.query })
michael@0 42
michael@0 43 def get_url(self, path, server_port, querystr):
michael@0 44 url = "http://127.0.0.1:%s%s" % (server_port, path)
michael@0 45 if querystr:
michael@0 46 url += "?%s" % querystr
michael@0 47 return url
michael@0 48
michael@0 49 def try_get(self, server_port, querystr):
michael@0 50 self.resource_get_called = 0
michael@0 51
michael@0 52 f = urllib2.urlopen(self.get_url('/api/resource/1', server_port, querystr))
michael@0 53 try:
michael@0 54 self.assertEqual(f.getcode(), 200)
michael@0 55 except AttributeError:
michael@0 56 pass # python 2.4
michael@0 57 self.assertEqual(json.loads(f.read()), { 'called': 1, 'id': str(1), 'query': querystr })
michael@0 58 self.assertEqual(self.resource_get_called, 1)
michael@0 59
michael@0 60 def try_post(self, server_port, querystr):
michael@0 61 self.resource_post_called = 0
michael@0 62
michael@0 63 postdata = { 'hamburgers': '1234' }
michael@0 64 try:
michael@0 65 f = urllib2.urlopen(self.get_url('/api/resource/', server_port, querystr),
michael@0 66 data=json.dumps(postdata))
michael@0 67 except urllib2.HTTPError, e:
michael@0 68 # python 2.4
michael@0 69 self.assertEqual(e.code, 201)
michael@0 70 body = e.fp.read()
michael@0 71 else:
michael@0 72 self.assertEqual(f.getcode(), 201)
michael@0 73 body = f.read()
michael@0 74 self.assertEqual(json.loads(body), { 'called': 1,
michael@0 75 'data': postdata,
michael@0 76 'query': querystr })
michael@0 77 self.assertEqual(self.resource_post_called, 1)
michael@0 78
michael@0 79 def try_del(self, server_port, querystr):
michael@0 80 self.resource_del_called = 0
michael@0 81
michael@0 82 opener = urllib2.build_opener(urllib2.HTTPHandler)
michael@0 83 request = urllib2.Request(self.get_url('/api/resource/1', server_port, querystr))
michael@0 84 request.get_method = lambda: 'DEL'
michael@0 85 f = opener.open(request)
michael@0 86
michael@0 87 try:
michael@0 88 self.assertEqual(f.getcode(), 200)
michael@0 89 except AttributeError:
michael@0 90 pass # python 2.4
michael@0 91 self.assertEqual(json.loads(f.read()), { 'called': 1, 'id': str(1), 'query': querystr })
michael@0 92 self.assertEqual(self.resource_del_called, 1)
michael@0 93
michael@0 94 def test_api(self):
michael@0 95 httpd = mozhttpd.MozHttpd(port=0,
michael@0 96 urlhandlers = [ { 'method': 'GET',
michael@0 97 'path': '/api/resource/([^/]+)/?',
michael@0 98 'function': self.resource_get },
michael@0 99 { 'method': 'POST',
michael@0 100 'path': '/api/resource/?',
michael@0 101 'function': self.resource_post },
michael@0 102 { 'method': 'DEL',
michael@0 103 'path': '/api/resource/([^/]+)/?',
michael@0 104 'function': self.resource_del }
michael@0 105 ])
michael@0 106 httpd.start(block=False)
michael@0 107
michael@0 108 server_port = httpd.httpd.server_port
michael@0 109
michael@0 110 # GET
michael@0 111 self.try_get(server_port, '')
michael@0 112 self.try_get(server_port, '?foo=bar')
michael@0 113
michael@0 114 # POST
michael@0 115 self.try_post(server_port, '')
michael@0 116 self.try_post(server_port, '?foo=bar')
michael@0 117
michael@0 118 # DEL
michael@0 119 self.try_del(server_port, '')
michael@0 120 self.try_del(server_port, '?foo=bar')
michael@0 121
michael@0 122 # GET: By default we don't serve any files if we just define an API
michael@0 123 f = None
michael@0 124 exception_thrown = False
michael@0 125 try:
michael@0 126 f = urllib2.urlopen(self.get_url('/', server_port, None))
michael@0 127 except urllib2.HTTPError, e:
michael@0 128 self.assertEqual(e.code, 404)
michael@0 129 exception_thrown = True
michael@0 130 self.assertTrue(exception_thrown)
michael@0 131
michael@0 132 def test_nonexistent_resources(self):
michael@0 133 # Create a server with a placeholder handler so we don't fall back
michael@0 134 # to serving local files
michael@0 135 httpd = mozhttpd.MozHttpd(port=0)
michael@0 136 httpd.start(block=False)
michael@0 137 server_port = httpd.httpd.server_port
michael@0 138
michael@0 139 # GET: Return 404 for non-existent endpoint
michael@0 140 f = None
michael@0 141 exception_thrown = False
michael@0 142 try:
michael@0 143 f = urllib2.urlopen(self.get_url('/api/resource/', server_port, None))
michael@0 144 except urllib2.HTTPError, e:
michael@0 145 self.assertEqual(e.code, 404)
michael@0 146 exception_thrown = True
michael@0 147 self.assertTrue(exception_thrown)
michael@0 148
michael@0 149 # POST: POST should also return 404
michael@0 150 f = None
michael@0 151 exception_thrown = False
michael@0 152 try:
michael@0 153 f = urllib2.urlopen(self.get_url('/api/resource/', server_port, None),
michael@0 154 data=json.dumps({}))
michael@0 155 except urllib2.HTTPError, e:
michael@0 156 self.assertEqual(e.code, 404)
michael@0 157 exception_thrown = True
michael@0 158 self.assertTrue(exception_thrown)
michael@0 159
michael@0 160 # DEL: DEL should also return 404
michael@0 161 f = None
michael@0 162 exception_thrown = False
michael@0 163 try:
michael@0 164 opener = urllib2.build_opener(urllib2.HTTPHandler)
michael@0 165 request = urllib2.Request(self.get_url('/api/resource/', server_port,
michael@0 166 None))
michael@0 167 request.get_method = lambda: 'DEL'
michael@0 168 f = opener.open(request)
michael@0 169 except urllib2.HTTPError, e:
michael@0 170 self.assertEqual(e.code, 404)
michael@0 171 exception_thrown = True
michael@0 172 self.assertTrue(exception_thrown)
michael@0 173
michael@0 174 def test_api_with_docroot(self):
michael@0 175 httpd = mozhttpd.MozHttpd(port=0, docroot=here,
michael@0 176 urlhandlers = [ { 'method': 'GET',
michael@0 177 'path': '/api/resource/([^/]+)/?',
michael@0 178 'function': self.resource_get } ])
michael@0 179 httpd.start(block=False)
michael@0 180 server_port = httpd.httpd.server_port
michael@0 181
michael@0 182 # We defined a docroot, so we expect a directory listing
michael@0 183 f = urllib2.urlopen(self.get_url('/', server_port, None))
michael@0 184 try:
michael@0 185 self.assertEqual(f.getcode(), 200)
michael@0 186 except AttributeError:
michael@0 187 pass # python 2.4
michael@0 188 self.assertTrue('Directory listing for' in f.read())
michael@0 189
michael@0 190 # Make sure API methods still work
michael@0 191 self.try_get(server_port, '')
michael@0 192 self.try_get(server_port, '?foo=bar')
michael@0 193
michael@0 194 class ProxyTest(unittest.TestCase):
michael@0 195
michael@0 196 def tearDown(self):
michael@0 197 # reset proxy opener in case it changed
michael@0 198 urllib2.install_opener(None)
michael@0 199
michael@0 200 def test_proxy(self):
michael@0 201 docroot = tempfile.mkdtemp()
michael@0 202 hosts = ('mozilla.com', 'mozilla.org')
michael@0 203 unproxied_host = 'notmozilla.org'
michael@0 204 def url(host): return 'http://%s/' % host
michael@0 205
michael@0 206 index_filename = 'index.html'
michael@0 207 def index_contents(host): return '%s index' % host
michael@0 208
michael@0 209 index = file(os.path.join(docroot, index_filename), 'w')
michael@0 210 index.write(index_contents('*'))
michael@0 211 index.close()
michael@0 212
michael@0 213 httpd = mozhttpd.MozHttpd(port=0, docroot=docroot)
michael@0 214 httpd.start(block=False)
michael@0 215 server_port = httpd.httpd.server_port
michael@0 216
michael@0 217 proxy_support = urllib2.ProxyHandler({'http': 'http://127.0.0.1:%d' %
michael@0 218 server_port})
michael@0 219 urllib2.install_opener(urllib2.build_opener(proxy_support))
michael@0 220
michael@0 221 for host in hosts:
michael@0 222 f = urllib2.urlopen(url(host))
michael@0 223 try:
michael@0 224 self.assertEqual(f.getcode(), 200)
michael@0 225 except AttributeError:
michael@0 226 pass # python 2.4
michael@0 227 self.assertEqual(f.read(), index_contents('*'))
michael@0 228
michael@0 229 httpd.stop()
michael@0 230
michael@0 231 # test separate directories per host
michael@0 232
michael@0 233 httpd = mozhttpd.MozHttpd(port=0, docroot=docroot, proxy_host_dirs=True)
michael@0 234 httpd.start(block=False)
michael@0 235 server_port = httpd.httpd.server_port
michael@0 236
michael@0 237 proxy_support = urllib2.ProxyHandler({'http': 'http://127.0.0.1:%d' %
michael@0 238 server_port})
michael@0 239 urllib2.install_opener(urllib2.build_opener(proxy_support))
michael@0 240
michael@0 241 # set up dirs
michael@0 242 for host in hosts:
michael@0 243 os.mkdir(os.path.join(docroot, host))
michael@0 244 file(os.path.join(docroot, host, index_filename), 'w') \
michael@0 245 .write(index_contents(host))
michael@0 246
michael@0 247 for host in hosts:
michael@0 248 f = urllib2.urlopen(url(host))
michael@0 249 try:
michael@0 250 self.assertEqual(f.getcode(), 200)
michael@0 251 except AttributeError:
michael@0 252 pass # python 2.4
michael@0 253 self.assertEqual(f.read(), index_contents(host))
michael@0 254
michael@0 255 exc = None
michael@0 256 try:
michael@0 257 urllib2.urlopen(url(unproxied_host))
michael@0 258 except urllib2.HTTPError, e:
michael@0 259 exc = e
michael@0 260 self.assertNotEqual(exc, None)
michael@0 261 self.assertEqual(exc.code, 404)
michael@0 262
michael@0 263
michael@0 264 if __name__ == '__main__':
michael@0 265 unittest.main()

mercurial