OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/python | |
2 | |
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can be | |
5 # found in the LICENSE file. | |
6 | |
7 """Tests for Constrained Network Server.""" | |
8 | |
9 import os | |
10 import signal | |
11 import subprocess | |
12 import tempfile | |
13 import time | |
14 import unittest | |
15 import urllib2 | |
16 | |
17 import cns | |
18 | |
19 | |
20 class PortAllocatorTest(unittest.TestCase): | |
21 """Unit tests for the Port Allocator class.""" | |
22 | |
23 # Use low expiry time for easy testing. Use 2 instead of 1 so we have an | |
24 # integer sleep time for staggering when / 2. Timing is too tight otherwise. | |
25 _EXPIRY_TIME = 2 | |
Ami GONE FROM CHROMIUM
2011/11/16 03:11:22
Ouch to real time and sleeps.
Inject a clock into
DaleCurtis
2011/11/16 20:20:15
Done.
| |
26 | |
27 def setUp(self): | |
28 # TODO(dalecurtis): Mock out actual calls to shadi's port setup. | |
29 self._pa = cns.PortAllocator(cns._DEFAULT_CNS_PORT_RANGE, self._EXPIRY_TIME) | |
30 | |
31 def tearDown(self): | |
32 self._pa.Cleanup(all_ports=True) | |
33 # Ensure ports are cleaned properly. | |
34 self.assertEquals(self._pa._ports, {}) | |
35 | |
36 def testPortAllocator(self): | |
37 # Ensure Get() succeeds and returns the correct port. | |
38 self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0]) | |
39 | |
40 # Call again with the same key and make sure we get the same port. | |
41 self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0]) | |
42 | |
43 # Call with a different key and make sure we get a different port. | |
44 self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1) | |
45 | |
46 # Wait for ports to expire. | |
47 time.sleep(self._EXPIRY_TIME) | |
48 | |
49 # Test to make sure cache is checked before expiring ports. | |
50 self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1) | |
51 | |
52 # Wait for ports to expire again. | |
53 time.sleep(self._EXPIRY_TIME) | |
54 | |
55 # Request a new port, old ports should be expired, so we should get the | |
56 # first port in the range. Make sure this is the only allocated port. | |
57 self.assertEquals(self._pa.Get('test3'), cns._DEFAULT_CNS_PORT_RANGE[0]) | |
58 self.assertEquals(self._pa._ports.keys(), [cns._DEFAULT_CNS_PORT_RANGE[0]]) | |
59 | |
60 def testPortAllocatorExpiresOnlyCorrectPorts(self): | |
61 # Ensure Get() succeeds and returns the correct port. | |
62 self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0]) | |
63 | |
64 # Stagger port allocation and so we can ensure only ports older than the | |
65 # expiry time are actually expired. | |
66 time.sleep(self._EXPIRY_TIME / 2) | |
67 | |
68 # Call with a different key and make sure we get a different port. | |
69 self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1) | |
70 | |
71 # After this sleep the port with key 'test' should expire on the next Get(). | |
72 time.sleep(self._EXPIRY_TIME / 2) | |
73 | |
74 # Call with a different key and make sure we get the first port. | |
75 self.assertEquals(self._pa.Get('test3'), cns._DEFAULT_CNS_PORT_RANGE[0]) | |
76 self.assertEquals(set(self._pa._ports.keys()), set([ | |
77 cns._DEFAULT_CNS_PORT_RANGE[0], cns._DEFAULT_CNS_PORT_RANGE[0] + 1])) | |
78 | |
79 | |
80 class ConstrainedNetworkServerTest(unittest.TestCase): | |
81 """End to end tests for ConstrainedNetworkServer system.""" | |
82 | |
83 # Amount of time to wait for the CNS to start up. | |
84 _SERVER_START_SLEEP_SECS = 1 | |
85 | |
86 # Sample data used to verify file serving. | |
87 _TEST_DATA = 'The quick brown fox jumps over the lazy dog' | |
88 | |
89 # Server information. | |
90 _SERVER_PORT = 8000 | |
91 _SERVER_URL = 'http://127.0.0.1:%d/ServeConstrained?' % _SERVER_PORT | |
92 | |
93 # Setting for latency testing. | |
94 _LATENCY_TEST_SECS = 5 | |
95 | |
96 def _StartServer(self): | |
97 """Starts the CNS, returns pid.""" | |
98 cmd = ['python', 'cns.py', '--port', str(self._SERVER_PORT)] | |
99 process = subprocess.Popen(cmd) | |
100 | |
101 # Wait for server to startup. | |
102 time.sleep(self._SERVER_START_SLEEP_SECS) | |
Ami GONE FROM CHROMIUM
2011/11/16 03:11:22
Ouch. Can you instead emit a stdout from cns sayi
DaleCurtis
2011/11/16 20:20:15
Done.
| |
103 return process.pid | |
104 | |
105 def setUp(self): | |
106 # Create temp file for serving. | |
107 f, self._file = tempfile.mkstemp(dir=os.getcwd()) | |
108 os.write(f, self._TEST_DATA) | |
109 os.close(f) | |
110 | |
111 # Strip cwd off so we have a proper relative path. | |
112 self._relative_fn = self._file[len(os.getcwd()) + 1:] | |
113 | |
114 # Start the CNS. | |
115 self._server_pid = self._StartServer() | |
116 | |
117 def tearDown(self): | |
118 os.unlink(self._file) | |
119 os.kill(self._server_pid, signal.SIGKILL) | |
120 | |
121 def testServerServesFiles(self): | |
122 f = urllib2.urlopen('%sf=%s' % (self._SERVER_URL, self._relative_fn)) | |
123 | |
124 # Verify file data is served correctly. | |
125 self.assertEqual(self._TEST_DATA, f.read()) | |
126 | |
127 def testServerLatencyConstraint(self): | |
128 now = time.time() | |
129 | |
130 base_url = '%sf=%s' % (self._SERVER_URL, self._relative_fn) | |
131 url = '%s&latency=%d' % (base_url, self._LATENCY_TEST_SECS * 1000) | |
132 f = urllib2.urlopen(url) | |
133 | |
134 # Verify file data is served correctly. | |
135 self.assertEqual(self._TEST_DATA, f.read()) | |
136 | |
137 # Verify the request took longer than the requested latency. | |
Ami GONE FROM CHROMIUM
2011/11/16 03:11:22
Would be a more convincing test if the un-latency'
DaleCurtis
2011/11/16 20:20:15
Done.
| |
138 self.assertTrue(time.time() - now > self._LATENCY_TEST_SECS) | |
139 | |
140 # Verify the server properly redirected the URL. | |
141 self.assertEquals(f.geturl(), base_url.replace( | |
142 str(self._SERVER_PORT), str(cns._DEFAULT_CNS_PORT_RANGE[0]))) | |
143 | |
144 | |
145 if __name__ == '__main__': | |
146 unittest.main() | |
OLD | NEW |