Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: swarm_client/tests/url_open_timeout_test.py

Issue 69143004: Delete swarm_client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « swarm_client/tests/trace_inputs_test.py ('k') | swarm_client/tests/zip_package_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import BaseHTTPServer
7 import logging
8 import os
9 import re
10 import SocketServer
11 import sys
12 import threading
13 import time
14 import unittest
15
16 import auto_stub
17
18 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
19 sys.path.insert(0, ROOT_DIR)
20
21 from utils import net
22
23
24 class SleepingServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
25 """Multithreaded server that serves requests that block at various stages."""
26
27 # Lingering keep-alive HTTP connections keep (not very smart) HTTPServer
28 # threads alive as well. Convert them to deamon threads so that they don't
29 # block process exit.
30 daemon_threads = True
31
32 def __init__(self):
33 BaseHTTPServer.HTTPServer.__init__(self, ('127.0.0.1', 0), SleepingHandler)
34 self.dying = False
35 self.dying_cv = threading.Condition()
36 self.serving_thread = None
37
38 def handle_error(self, _request, _client_address):
39 # Mute "error: [Errno 32] Broken pipe" errors.
40 pass
41
42 def start(self):
43 self.serving_thread = threading.Thread(target=self.serve_forever,
44 kwargs={'poll_interval': 0.05})
45 self.serving_thread.start()
46
47 def stop(self):
48 with self.dying_cv:
49 self.dying = True
50 self.dying_cv.notifyAll()
51 self.shutdown()
52
53 @property
54 def url(self):
55 return 'http://%s:%d' % self.socket.getsockname()
56
57 def sleep(self, timeout):
58 deadline = time.time() + timeout
59 with self.dying_cv:
60 while not self.dying and time.time() < deadline:
61 self.dying_cv.wait(deadline - time.time())
62
63
64 class SleepingHandler(BaseHTTPServer.BaseHTTPRequestHandler):
65 protocol_version = 'HTTP/1.1'
66
67 path_re = re.compile(r'/(.*)/([\.\d]*)(\?.*)?')
68
69 first_line = 'FIRST LINE\n'
70 second_line = 'SECOND LINE\n'
71 full_response = first_line + second_line
72
73 modes = {
74 'sleep_before_response': ['SLEEP', 'HEADERS', 'FIRST', 'SECOND'],
75 'sleep_after_headers': ['HEADERS', 'SLEEP', 'FIRST', 'SECOND'],
76 'sleep_during_response': ['HEADERS', 'FIRST', 'SLEEP', 'SECOND'],
77 'sleep_after_response': ['HEADERS', 'FIRST', 'SECOND', 'SLEEP'],
78 }
79
80 def send_headers(self):
81 self.send_response(200)
82 self.send_header('Content-Length', len(self.full_response))
83 self.end_headers()
84
85 def log_message(self, _format, *_args):
86 # Mute "GET /sleep_before_response/0.000000 HTTP/1.1" 200 -" messages.
87 pass
88
89 def do_GET(self):
90 # Split request string like '/sleep/0.1?param=1' into ('sleep', 0.1) pair.
91 match = self.path_re.match(self.path)
92 if not match:
93 self.send_error(404)
94 return
95 mode, timeout, _ = match.groups()
96 # Ensure timeout is float.
97 try:
98 timeout = float(timeout)
99 except ValueError:
100 self.send_error(400)
101 return
102 # Ensure mode is known.
103 if mode not in self.modes:
104 self.send_error(404)
105 return
106 # Mapping mode's action -> function to call.
107 actions = {
108 'SLEEP': lambda: self.server.sleep(timeout),
109 'HEADERS': self.send_headers,
110 'FIRST': lambda: self.wfile.write(self.first_line),
111 'SECOND': lambda: self.wfile.write(self.second_line),
112 }
113 # Execute all actions defined by the mode.
114 for action in self.modes[mode]:
115 actions[action]()
116
117
118 class UrlOpenTimeoutTest(auto_stub.TestCase):
119 def setUp(self):
120 super(UrlOpenTimeoutTest, self).setUp()
121 self.server = SleepingServer()
122 self.server.start()
123
124 def tearDown(self):
125 self.server.stop()
126 self.server = None
127 super(UrlOpenTimeoutTest, self).tearDown()
128
129 def call(self, mode, sleep_duration, **kwargs):
130 url = self.server.url + '/%s/%f' % (mode, sleep_duration)
131 kwargs['max_attempts'] = 2
132 return net.url_open(url, **kwargs)
133
134 def test_urlopen_success(self):
135 # Server doesn't block.
136 for mode in SleepingHandler.modes:
137 self.assertEqual(self.call(mode, 0, read_timeout=0.1).read(),
138 SleepingHandler.full_response)
139 # Server does block, but url_open called without read timeout.
140 for mode in SleepingHandler.modes:
141 self.assertEqual(self.call(mode, 0.25, read_timeout=None).read(),
142 SleepingHandler.full_response)
143
144 def test_urlopen_retry(self):
145 # This should trigger retry logic and eventually return None.
146 self.mock(net, 'sleep_before_retry', lambda *_: None)
147 stream = self.call('sleep_before_response', 0.25, read_timeout=0.1)
148 self.assertIsNone(stream)
149
150 def test_urlopen_keeping_connection(self):
151 # Sleeping after request is sent -> it's just connection keep alive.
152 stream = self.call('sleep_after_response', 0.25, read_timeout=0.1)
153 self.assertEqual(stream.read(), SleepingHandler.full_response)
154
155 def test_urlopen_timeouts(self):
156 # Timeouts while reading from the stream.
157 for mode in ('sleep_after_headers', 'sleep_during_response'):
158 stream = self.call(mode, 0.25, read_timeout=0.1)
159 self.assertTrue(stream)
160 with self.assertRaises(net.TimeoutError):
161 stream.read()
162
163
164 if __name__ == '__main__':
165 VERBOSE = '-v' in sys.argv
166 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR)
167 unittest.main()
OLDNEW
« no previous file with comments | « swarm_client/tests/trace_inputs_test.py ('k') | swarm_client/tests/zip_package_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698