Merge lp:~gesha/linaro-license-protection/clickthrough-testing into lp:~linaro-automation/linaro-license-protection/trunk
- clickthrough-testing
- Merge into trunk
Proposed by
Georgy Redkozubov
Status: | Superseded |
---|---|
Proposed branch: | lp:~gesha/linaro-license-protection/clickthrough-testing |
Merge into: | lp:~linaro-automation/linaro-license-protection/trunk |
Diff against target: |
553 lines (+486/-4) (has conflicts) 8 files modified
.htaccess (+12/-4) .testr.conf (+3/-0) licenses/nolicense.html (+9/-0) testing/__init__.py (+11/-0) testing/apache2.conf.tmpl (+104/-0) testing/filefetcher.py (+129/-0) testing/mime.types (+6/-0) testing/test_click_through_license.py (+212/-0) Conflict adding file licenses/nolicense.html. Moved existing file to licenses/nolicense.html.moved. |
To merge this branch: | bzr merge lp:~gesha/linaro-license-protection/clickthrough-testing |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Linaro Infrastructure | Pending | ||
Review via email: mp+88387@code.launchpad.net |
This proposal supersedes a proposal from 2012-01-10.
This proposal has been superseded by a proposal from 2012-01-13.
Commit message
Description of the change
Added tests for click-through license feature using Testtools and Testrepository.
To post a comment you must log in.
- 33. By Georgy Redkozubov
-
Fixed issue with non-standart http port
Revision history for this message
James Tunnicliffe (dooferlad) wrote : | # |
- 34. By Georgy Redkozubov
-
Added port autoselection adviced by James Tunnicliffe and corrected to match pep8 style
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.htaccess' | |||
2 | --- .htaccess 2011-12-19 16:57:20 +0000 | |||
3 | +++ .htaccess 2012-01-13 11:52:24 +0000 | |||
4 | @@ -3,6 +3,14 @@ | |||
5 | 3 | 3 | ||
6 | 4 | RewriteEngine On | 4 | RewriteEngine On |
7 | 5 | 5 | ||
8 | 6 | RewriteCond %{SERVER_PORT} !^80$ | ||
9 | 7 | RewriteCond %{HTTP_HOST} (.*)(\:.*) | ||
10 | 8 | RewriteRule .* - [E=CO_DOMAIN:%1] | ||
11 | 9 | |||
12 | 10 | RewriteCond %{SERVER_PORT} ^80$ | ||
13 | 11 | RewriteCond %{HTTP_HOST} (^.*$) | ||
14 | 12 | RewriteRule .* - [E=CO_DOMAIN:%1] | ||
15 | 13 | |||
16 | 6 | ## Let internal hosts through always. | 14 | ## Let internal hosts through always. |
17 | 7 | # android-build.linaro.org. | 15 | # android-build.linaro.org. |
18 | 8 | RewriteCond %{REMOTE_ADDR} 50.17.250.69 [OR] | 16 | RewriteCond %{REMOTE_ADDR} 50.17.250.69 [OR] |
19 | @@ -45,11 +53,11 @@ | |||
20 | 45 | # Samsung. | 53 | # Samsung. |
21 | 46 | RewriteCond %{REQUEST_URI} licenses/samsung-accepted.html$ | 54 | RewriteCond %{REQUEST_URI} licenses/samsung-accepted.html$ |
22 | 47 | RewriteCond %{HTTP_COOKIE} downloadrequested=([^\;]*\/)([^/\;]*) | 55 | RewriteCond %{HTTP_COOKIE} downloadrequested=([^\;]*\/)([^/\;]*) |
24 | 48 | RewriteRule .* %1%2 [CO=samsunglicenseaccepted-v1:true:.%{HTTP_HOST}:5:%1,R,L] | 56 | RewriteRule .* %1%2 [CO=samsunglicenseaccepted-v1:true:.%{ENV:CO_DOMAIN}:5:%1,R,L] |
25 | 49 | # ST-E. | 57 | # ST-E. |
26 | 50 | RewriteCond %{REQUEST_URI} licenses/ste-accepted.html$ | 58 | RewriteCond %{REQUEST_URI} licenses/ste-accepted.html$ |
27 | 51 | RewriteCond %{HTTP_COOKIE} downloadrequested=([^\;]*\/)([^/\;]*) | 59 | RewriteCond %{HTTP_COOKIE} downloadrequested=([^\;]*\/)([^/\;]*) |
29 | 52 | RewriteRule .* %1%2 [CO=stelicenseaccepted-v1:true:.%{HTTP_HOST}:60:%1,R,L] | 60 | RewriteRule .* %1%2 [CO=stelicenseaccepted-v1:true:.%{ENV:CO_DOMAIN}:60:%1,R,L] |
30 | 53 | 61 | ||
31 | 54 | ## When license is being declined, show the notice that you have to accept it. | 62 | ## When license is being declined, show the notice that you have to accept it. |
32 | 55 | # Samsung. | 63 | # Samsung. |
33 | @@ -69,7 +77,7 @@ | |||
34 | 69 | ## Redirect to the license file protected builds. | 77 | ## Redirect to the license file protected builds. |
35 | 70 | # Samsung. | 78 | # Samsung. |
36 | 71 | RewriteCond %{REQUEST_URI} ^/.*origen.*$ | 79 | RewriteCond %{REQUEST_URI} ^/.*origen.*$ |
38 | 72 | RewriteRule .* /licenses/samsung-v2.html [CO=downloadrequested:%{REQUEST_URI}:.%{HTTP_HOST},R,L] | 80 | RewriteRule .* /licenses/samsung-v2.html [CO=downloadrequested:%{REQUEST_URI}:.%{ENV:CO_DOMAIN},R,L] |
39 | 73 | # ST-E. | 81 | # ST-E. |
40 | 74 | RewriteCond %{REQUEST_URI} ^/.*snowball.* | 82 | RewriteCond %{REQUEST_URI} ^/.*snowball.* |
42 | 75 | RewriteRule .* /licenses/ste.html [CO=downloadrequested:%{REQUEST_URI}:.%{HTTP_HOST},R,L] | 83 | RewriteRule .* /licenses/ste.html [CO=downloadrequested:%{REQUEST_URI}:.%{ENV:CO_DOMAIN},R,L] |
43 | 76 | 84 | ||
44 | === added file '.testr.conf' | |||
45 | --- .testr.conf 1970-01-01 00:00:00 +0000 | |||
46 | +++ .testr.conf 2012-01-13 11:52:24 +0000 | |||
47 | @@ -0,0 +1,3 @@ | |||
48 | 1 | [DEFAULT] | ||
49 | 2 | test_command=python -m subunit.run $IDLIST | ||
50 | 3 | test_id_list_default=testing.test_suite | ||
51 | 0 | 4 | ||
52 | === added file 'licenses/nolicense.html' | |||
53 | --- licenses/nolicense.html 1970-01-01 00:00:00 +0000 | |||
54 | +++ licenses/nolicense.html 2012-01-13 11:52:24 +0000 | |||
55 | @@ -0,0 +1,9 @@ | |||
56 | 1 | <html> | ||
57 | 2 | <head> | ||
58 | 3 | <title>License has not been accepted</title> | ||
59 | 4 | </head> | ||
60 | 5 | <body> | ||
61 | 6 | <h1>License has not been accepted</h1> | ||
62 | 7 | <p>Without accepting the license, you can not download the requested files.</p> | ||
63 | 8 | </body> | ||
64 | 9 | </html> | ||
65 | 0 | 10 | ||
66 | === renamed file 'licenses/nolicense.html' => 'licenses/nolicense.html.moved' | |||
67 | === added directory 'testing' | |||
68 | === added file 'testing/__init__.py' | |||
69 | --- testing/__init__.py 1970-01-01 00:00:00 +0000 | |||
70 | +++ testing/__init__.py 2012-01-13 11:52:24 +0000 | |||
71 | @@ -0,0 +1,11 @@ | |||
72 | 1 | import os | ||
73 | 2 | import unittest | ||
74 | 3 | |||
75 | 4 | def test_suite(): | ||
76 | 5 | module_names = [ | ||
77 | 6 | 'testing.test_click_through_license', | ||
78 | 7 | ] | ||
79 | 8 | loader = unittest.TestLoader() | ||
80 | 9 | suite = loader.loadTestsFromNames(module_names) | ||
81 | 10 | return suite | ||
82 | 11 | |||
83 | 0 | 12 | ||
84 | === added file 'testing/apache2.conf.tmpl' | |||
85 | --- testing/apache2.conf.tmpl 1970-01-01 00:00:00 +0000 | |||
86 | +++ testing/apache2.conf.tmpl 2012-01-13 11:52:24 +0000 | |||
87 | @@ -0,0 +1,104 @@ | |||
88 | 1 | ServerRoot "" | ||
89 | 2 | |||
90 | 3 | LockFile click_through_license.lock | ||
91 | 4 | PidFile click_through_license.pid | ||
92 | 5 | |||
93 | 6 | Timeout 300 | ||
94 | 7 | |||
95 | 8 | KeepAlive On | ||
96 | 9 | |||
97 | 10 | KeepAliveTimeout 5 | ||
98 | 11 | |||
99 | 12 | Listen | ||
100 | 13 | |||
101 | 14 | ServerAdmin you@example.com | ||
102 | 15 | |||
103 | 16 | #ServerName www.example.com:80 | ||
104 | 17 | |||
105 | 18 | DocumentRoot "" | ||
106 | 19 | |||
107 | 20 | AccessFileName .htaccess | ||
108 | 21 | |||
109 | 22 | LoadModule authz_host_module /usr/lib/apache2/modules/mod_authz_host.so | ||
110 | 23 | LoadModule cache_module /usr/lib/apache2/modules/mod_cache.so | ||
111 | 24 | LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so | ||
112 | 25 | LoadModule autoindex_module /usr/lib/apache2/modules/mod_autoindex.so | ||
113 | 26 | LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so | ||
114 | 27 | |||
115 | 28 | User daemon | ||
116 | 29 | Group daemon | ||
117 | 30 | |||
118 | 31 | <IfModule mpm_prefork_module> | ||
119 | 32 | StartServers 5 | ||
120 | 33 | MinSpareServers 5 | ||
121 | 34 | MaxSpareServers 10 | ||
122 | 35 | MaxClients 150 | ||
123 | 36 | MaxRequestsPerChild 0 | ||
124 | 37 | </IfModule> | ||
125 | 38 | |||
126 | 39 | <IfModule mpm_worker_module> | ||
127 | 40 | StartServers 2 | ||
128 | 41 | MinSpareThreads 25 | ||
129 | 42 | MaxSpareThreads 75. | ||
130 | 43 | ThreadLimit 64 | ||
131 | 44 | ThreadsPerChild 25 | ||
132 | 45 | MaxClients 150 | ||
133 | 46 | MaxRequestsPerChild 0 | ||
134 | 47 | </IfModule> | ||
135 | 48 | |||
136 | 49 | <IfModule mpm_event_module> | ||
137 | 50 | StartServers 2 | ||
138 | 51 | MinSpareThreads 25 | ||
139 | 52 | MaxSpareThreads 75. | ||
140 | 53 | ThreadLimit 64 | ||
141 | 54 | ThreadsPerChild 25 | ||
142 | 55 | MaxClients 150 | ||
143 | 56 | MaxRequestsPerChild 0 | ||
144 | 57 | </IfModule> | ||
145 | 58 | |||
146 | 59 | <Directory /> | ||
147 | 60 | Options +FollowSymLinks | ||
148 | 61 | AllowOverride All | ||
149 | 62 | Order deny,allow | ||
150 | 63 | Deny from all | ||
151 | 64 | </Directory> | ||
152 | 65 | |||
153 | 66 | <Directory ""> | ||
154 | 67 | Options Indexes +FollowSymLinks MultiViews | ||
155 | 68 | AllowOverride All | ||
156 | 69 | Order allow,deny | ||
157 | 70 | Allow from all | ||
158 | 71 | </Directory> | ||
159 | 72 | |||
160 | 73 | <IfModule dir_module> | ||
161 | 74 | DirectoryIndex index.html | ||
162 | 75 | </IfModule> | ||
163 | 76 | |||
164 | 77 | <FilesMatch "^\.ht"> | ||
165 | 78 | Order allow,deny | ||
166 | 79 | Deny from all | ||
167 | 80 | Satisfy All | ||
168 | 81 | </FilesMatch> | ||
169 | 82 | |||
170 | 83 | ErrorLog "click_through_license_error.log" | ||
171 | 84 | |||
172 | 85 | LogLevel warn | ||
173 | 86 | |||
174 | 87 | <IfModule log_config_module> | ||
175 | 88 | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined | ||
176 | 89 | LogFormat "%h %l %u %t \"%r\" %>s %b" common | ||
177 | 90 | |||
178 | 91 | <IfModule logio_module> | ||
179 | 92 | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio | ||
180 | 93 | </IfModule> | ||
181 | 94 | |||
182 | 95 | CustomLog "click_through_license_access.log" common | ||
183 | 96 | |||
184 | 97 | </IfModule> | ||
185 | 98 | |||
186 | 99 | DefaultType text/plain | ||
187 | 100 | |||
188 | 101 | IndexOptions FancyIndexing VersionSort HTMLTable NameWidth=* DescriptionWidth=* Charset=UTF-8 | ||
189 | 102 | ReadmeName README.html | ||
190 | 103 | HeaderName HEADER.html | ||
191 | 104 | IndexIgnore .??* *~ *# RCS CVS *,v *,t. | ||
192 | 0 | 105 | ||
193 | === added file 'testing/filefetcher.py' | |||
194 | --- testing/filefetcher.py 1970-01-01 00:00:00 +0000 | |||
195 | +++ testing/filefetcher.py 2012-01-13 11:52:24 +0000 | |||
196 | @@ -0,0 +1,129 @@ | |||
197 | 1 | #!/usr/bin/env python | ||
198 | 2 | |||
199 | 3 | # Changes required to address EULA for the origen hwpacks | ||
200 | 4 | |||
201 | 5 | import argparse | ||
202 | 6 | import os | ||
203 | 7 | import pycurl | ||
204 | 8 | import re | ||
205 | 9 | import urlparse | ||
206 | 10 | |||
207 | 11 | |||
208 | 12 | class LicenseProtectedFileFetcher: | ||
209 | 13 | """Fetch a file from the web that may be protected by a license redirect | ||
210 | 14 | |||
211 | 15 | This is designed to run on snapshots.linaro.org. License HTML file are in | ||
212 | 16 | the form: | ||
213 | 17 | |||
214 | 18 | <vendor>.html has a link to <vendor>-accept.html | ||
215 | 19 | |||
216 | 20 | If self.get is pointed at a file that has to go through one of these | ||
217 | 21 | licenses, it should be able to automatically accept the license and | ||
218 | 22 | download the file. | ||
219 | 23 | |||
220 | 24 | Once a license has been accepted, it will be used for all following | ||
221 | 25 | downloads. | ||
222 | 26 | |||
223 | 27 | If self.close() is called before the object is deleted, cURL will store | ||
224 | 28 | the license accept cookie to cookies.txt, so it can be used for later | ||
225 | 29 | downloads. | ||
226 | 30 | |||
227 | 31 | """ | ||
228 | 32 | def __init__(self): | ||
229 | 33 | """Set up cURL""" | ||
230 | 34 | self.curl = pycurl.Curl() | ||
231 | 35 | self.curl.setopt(pycurl.FOLLOWLOCATION, 1) | ||
232 | 36 | self.curl.setopt(pycurl.WRITEFUNCTION, self._write_body) | ||
233 | 37 | self.curl.setopt(pycurl.HEADERFUNCTION, self._write_header) | ||
234 | 38 | self.curl.setopt(pycurl.COOKIEFILE, "cookies.txt") | ||
235 | 39 | self.curl.setopt(pycurl.COOKIEJAR, "cookies.txt") | ||
236 | 40 | |||
237 | 41 | def _get(self, url): | ||
238 | 42 | """Clear out header and body storage, fetch URL, filling them in.""" | ||
239 | 43 | self.curl.setopt(pycurl.URL, url) | ||
240 | 44 | |||
241 | 45 | self.body = "" | ||
242 | 46 | self.header = "" | ||
243 | 47 | |||
244 | 48 | self.curl.perform() | ||
245 | 49 | |||
246 | 50 | def get(self, url, ignore_license=False, accept_license=True): | ||
247 | 51 | """Fetch the requested URL, ignoring license at all or | ||
248 | 52 | accepting or declining licenses, returns file body. | ||
249 | 53 | |||
250 | 54 | Fetches the file at url. If a redirect is encountered, it is | ||
251 | 55 | expected to be to a license that has an accept or decline link. | ||
252 | 56 | Follow that link, then download original file or nolicense notice. | ||
253 | 57 | |||
254 | 58 | """ | ||
255 | 59 | self._get(url) | ||
256 | 60 | |||
257 | 61 | if ignore_license: | ||
258 | 62 | return self.body | ||
259 | 63 | |||
260 | 64 | location = self._get_location() | ||
261 | 65 | if location: | ||
262 | 66 | # Off to the races - we have been redirected. | ||
263 | 67 | # Expect to find a link to self.location with -accepted or | ||
264 | 68 | # -declined inserted before the .html, | ||
265 | 69 | # i.e. ste.html -> ste-accepted.html | ||
266 | 70 | |||
267 | 71 | # Get the file from the URL (full path) | ||
268 | 72 | file = urlparse.urlparse(location).path | ||
269 | 73 | |||
270 | 74 | # Get the file without the rest of the path | ||
271 | 75 | file = os.path.split(file)[-1] | ||
272 | 76 | |||
273 | 77 | # Look for a link with accepted.html or declined.html | ||
274 | 78 | # in the page name. Follow it. | ||
275 | 79 | new_file = None | ||
276 | 80 | for line in self.body.splitlines(): | ||
277 | 81 | if accept_license: | ||
278 | 82 | link_search = re.search("""href=.*?["'](.*?-accepted.html)""", | ||
279 | 83 | line) | ||
280 | 84 | else: | ||
281 | 85 | link_search = re.search("""href=.*?["'](.*?-declined.html)""", | ||
282 | 86 | line) | ||
283 | 87 | if link_search: | ||
284 | 88 | # Have found license decline URL! | ||
285 | 89 | new_file = link_search.group(1) | ||
286 | 90 | |||
287 | 91 | if new_file: | ||
288 | 92 | # accept or decline the license... | ||
289 | 93 | next_url = re.sub(file, new_file, location) | ||
290 | 94 | self._get(next_url) | ||
291 | 95 | |||
292 | 96 | # The above get *should* take us to the file requested via | ||
293 | 97 | # a redirect. If we manually need to follow that redirect, | ||
294 | 98 | # do that now. | ||
295 | 99 | |||
296 | 100 | if accept_license and self._get_location(): | ||
297 | 101 | # If we haven't been redirected to our original file, | ||
298 | 102 | # we should be able to just download it now. | ||
299 | 103 | self._get(url) | ||
300 | 104 | |||
301 | 105 | return self.body | ||
302 | 106 | |||
303 | 107 | def _search_header(self, field): | ||
304 | 108 | """Search header for the supplied field, return field / None""" | ||
305 | 109 | for line in self.header.splitlines(): | ||
306 | 110 | search = re.search(field + ":\s+(.*?)$", line) | ||
307 | 111 | if search: | ||
308 | 112 | return search.group(1) | ||
309 | 113 | return None | ||
310 | 114 | |||
311 | 115 | def _get_location(self): | ||
312 | 116 | """Return content of Location field in header / None""" | ||
313 | 117 | return self._search_header("Location") | ||
314 | 118 | |||
315 | 119 | def _write_body(self, buf): | ||
316 | 120 | """Used by curl as a sink for body content""" | ||
317 | 121 | self.body += buf | ||
318 | 122 | |||
319 | 123 | def _write_header(self, buf): | ||
320 | 124 | """Used by curl as a sink for header content""" | ||
321 | 125 | self.header += buf | ||
322 | 126 | |||
323 | 127 | def close(self): | ||
324 | 128 | """Wrapper to close curl - this will allow curl to write out cookies""" | ||
325 | 129 | self.curl.close() | ||
326 | 0 | 130 | ||
327 | === added file 'testing/mime.types' | |||
328 | --- testing/mime.types 1970-01-01 00:00:00 +0000 | |||
329 | +++ testing/mime.types 2012-01-13 11:52:24 +0000 | |||
330 | @@ -0,0 +1,6 @@ | |||
331 | 1 | text/css css | ||
332 | 2 | text/directory | ||
333 | 3 | text/html html htm shtml | ||
334 | 4 | text/plain asc txt text pot brf | ||
335 | 5 | text/uri-list | ||
336 | 6 | |||
337 | 0 | 7 | ||
338 | === added file 'testing/test_click_through_license.py' | |||
339 | --- testing/test_click_through_license.py 1970-01-01 00:00:00 +0000 | |||
340 | +++ testing/test_click_through_license.py 2012-01-13 11:52:24 +0000 | |||
341 | @@ -0,0 +1,212 @@ | |||
342 | 1 | #!/usr/bin/env python | ||
343 | 2 | |||
344 | 3 | import re | ||
345 | 4 | import os | ||
346 | 5 | import shutil | ||
347 | 6 | import shlex | ||
348 | 7 | import subprocess | ||
349 | 8 | import socket | ||
350 | 9 | |||
351 | 10 | from testtools import TestCase | ||
352 | 11 | from testtools.matchers import Mismatch | ||
353 | 12 | from filefetcher import LicenseProtectedFileFetcher | ||
354 | 13 | |||
355 | 14 | fetcher = LicenseProtectedFileFetcher() | ||
356 | 15 | cwd = os.getcwd() | ||
357 | 16 | docroot = cwd | ||
358 | 17 | srvroot = os.path.abspath(os.path.join(*([cwd] + ['testing']))) | ||
359 | 18 | local_rewrite = 'RewriteCond %{REMOTE_ADDR} 127.0.0.1 [OR]' | ||
360 | 19 | |||
361 | 20 | host = 'http://127.0.0.1' | ||
362 | 21 | port = '0' # 0 == Pick a free port. | ||
363 | 22 | samsung_license_path = '/licenses/samsung-v2.html' | ||
364 | 23 | ste_license_path = '/licenses/ste.html' | ||
365 | 24 | samsung_test_file = '/android/~linaro-android/staging-origen/test.txt' | ||
366 | 25 | ste_test_file = '/android/~linaro-android/staging-snowball/test.txt' | ||
367 | 26 | not_protected_test_file = '/android/~linaro-android/staging-panda/test.txt' | ||
368 | 27 | |||
369 | 28 | |||
370 | 29 | class Contains(object): | ||
371 | 30 | '''Match if a string contains substring''' | ||
372 | 31 | def __init__(self, substr): | ||
373 | 32 | self.substr = substr | ||
374 | 33 | |||
375 | 34 | def __str__(self): | ||
376 | 35 | return 'Contains(%s)' % (self.substr,) | ||
377 | 36 | |||
378 | 37 | def match(self, actual): | ||
379 | 38 | for line in actual.splitlines(): | ||
380 | 39 | res = re.search(self.substr, line) | ||
381 | 40 | if res: | ||
382 | 41 | return None | ||
383 | 42 | return Mismatch("Initial string doesn't contain substring (%s)" % | ||
384 | 43 | self.substr) | ||
385 | 44 | |||
386 | 45 | |||
387 | 46 | class CommandNotFoundException(Exception): | ||
388 | 47 | ''' Unable to find command ''' | ||
389 | 48 | |||
390 | 49 | |||
391 | 50 | class NonZeroReturnValueException(Exception): | ||
392 | 51 | ''' Command exited with nonzero return value ''' | ||
393 | 52 | |||
394 | 53 | |||
395 | 54 | class TestLicense(TestCase): | ||
396 | 55 | '''Tests for accessing files and directories with license protection''' | ||
397 | 56 | |||
398 | 57 | @classmethod | ||
399 | 58 | def setUpClass(cls): | ||
400 | 59 | global host | ||
401 | 60 | global port | ||
402 | 61 | if port == '0': | ||
403 | 62 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
404 | 63 | s.bind(('127.0.0.1', 0)) | ||
405 | 64 | port = str(s.getsockname()[1]) | ||
406 | 65 | s.close() | ||
407 | 66 | host = host + ':' + port | ||
408 | 67 | shutil.copy("%s/apache2.conf.tmpl" % srvroot, "%s/apache2.conf" % | ||
409 | 68 | srvroot) | ||
410 | 69 | shutil.copy("%s/.htaccess" % docroot, "%s/dothtaccess" % docroot) | ||
411 | 70 | subprocess.Popen(['sed', '-i', 's/ServerRoot \"\"/ServerRoot \"%s\"/' | ||
412 | 71 | % srvroot.replace('/', '\/'), '%s/apache2.conf' % srvroot], | ||
413 | 72 | stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT).wait() | ||
414 | 73 | subprocess.Popen(['sed', '-i', 's/DocumentRoot \"\"/DocumentRoot ' | ||
415 | 74 | '\"%s\"/' % docroot.replace('/', '\/'), '%s/apache2.conf' | ||
416 | 75 | % srvroot], stdout=open('/dev/null', 'w'), | ||
417 | 76 | stderr=subprocess.STDOUT).wait() | ||
418 | 77 | subprocess.Popen(['sed', '-i', 's/Directory \"\"/Directory \"%s\"/' | ||
419 | 78 | % docroot.replace('/', '\/'), '%s/apache2.conf' % srvroot], | ||
420 | 79 | stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT).wait() | ||
421 | 80 | subprocess.Popen(['sed', '-i', 's/Listen/Listen %s/' % port, | ||
422 | 81 | '%s/apache2.conf' % srvroot], stdout=open('/dev/null', 'w'), | ||
423 | 82 | stderr=subprocess.STDOUT).wait() | ||
424 | 83 | if subprocess.Popen(['which', 'apache2'], | ||
425 | 84 | stdout=open('/dev/null', 'w'), | ||
426 | 85 | stderr=subprocess.STDOUT).wait(): | ||
427 | 86 | raise CommandNotFoundException("apache2 command not found. Please " | ||
428 | 87 | "install apache2 web server and rerun tests.") | ||
429 | 88 | args = shlex.split('apache2 -d %s -f apache2.conf -k start' % srvroot) | ||
430 | 89 | rc = subprocess.Popen(args, stdout=open('/dev/null', 'w'), | ||
431 | 90 | stderr=subprocess.STDOUT).wait() | ||
432 | 91 | if rc: | ||
433 | 92 | raise NonZeroReturnValueException("apache2 server exited with " | ||
434 | 93 | "error %s" % rc) | ||
435 | 94 | |||
436 | 95 | @classmethod | ||
437 | 96 | def tearDownClass(cls): | ||
438 | 97 | if os.path.exists("%s/cookies.txt" % docroot): | ||
439 | 98 | os.unlink("%s/cookies.txt" % docroot) | ||
440 | 99 | args = shlex.split('apache2 -d %s -f apache2.conf -k stop' % srvroot) | ||
441 | 100 | subprocess.Popen(args, stdout=open('/dev/null', 'w'), | ||
442 | 101 | stderr=subprocess.STDOUT).wait() | ||
443 | 102 | if os.path.exists("%s/apache2.conf" % srvroot): | ||
444 | 103 | os.unlink("%s/apache2.conf" % srvroot) | ||
445 | 104 | if os.path.exists("%s/click_through_license_access.log" % srvroot): | ||
446 | 105 | os.unlink("%s/click_through_license_access.log" % srvroot) | ||
447 | 106 | if os.path.exists("%s/click_through_license_error.log" % srvroot): | ||
448 | 107 | os.unlink("%s/click_through_license_error.log" % srvroot) | ||
449 | 108 | os.rename("%s/dothtaccess" % docroot, "%s/.htaccess" % docroot) | ||
450 | 109 | |||
451 | 110 | def setUp(self): | ||
452 | 111 | super(TestLicense, self).setUp() | ||
453 | 112 | global fetcher | ||
454 | 113 | fetcher = LicenseProtectedFileFetcher() | ||
455 | 114 | |||
456 | 115 | def tearDown(self): | ||
457 | 116 | super(TestLicense, self).tearDown() | ||
458 | 117 | if isinstance(fetcher, LicenseProtectedFileFetcher): | ||
459 | 118 | fetcher.close() | ||
460 | 119 | if os.path.exists("%s/cookies.txt" % docroot): | ||
461 | 120 | os.unlink("%s/cookies.txt" % docroot) | ||
462 | 121 | |||
463 | 122 | def test_licensefile_directly_samsung(self): | ||
464 | 123 | search = "Index of /" | ||
465 | 124 | testfile = fetcher.get(host + samsung_license_path) | ||
466 | 125 | self.assertThat(testfile, Contains(search)) | ||
467 | 126 | |||
468 | 127 | def test_licensefile_directly_ste(self): | ||
469 | 128 | search = "Index of /" | ||
470 | 129 | testfile = fetcher.get(host + ste_license_path) | ||
471 | 130 | self.assertThat(testfile, Contains(search)) | ||
472 | 131 | |||
473 | 132 | def test_redirect_to_license_samsung(self): | ||
474 | 133 | search = "SAMSUNG DEVELOPMENT TOOL KIT END-USER LICENSE AGREEMENT" | ||
475 | 134 | testfile = fetcher.get(host + samsung_test_file, ignore_license=True) | ||
476 | 135 | self.assertThat(testfile, Contains(search)) | ||
477 | 136 | |||
478 | 137 | def test_redirect_to_license_ste(self): | ||
479 | 138 | search = "LIMITED LICENSE AGREEMENT FOR APPLICATION DEVELOPERS" | ||
480 | 139 | testfile = fetcher.get(host + ste_test_file, ignore_license=True) | ||
481 | 140 | self.assertThat(testfile, Contains(search)) | ||
482 | 141 | |||
483 | 142 | def test_decline_license_samsung(self): | ||
484 | 143 | search = "License has not been accepted" | ||
485 | 144 | testfile = fetcher.get(host + samsung_test_file, accept_license=False) | ||
486 | 145 | self.assertThat(testfile, Contains(search)) | ||
487 | 146 | |||
488 | 147 | def test_decline_license_ste(self): | ||
489 | 148 | search = "License has not been accepted" | ||
490 | 149 | testfile = fetcher.get(host + ste_test_file, accept_license=False) | ||
491 | 150 | self.assertThat(testfile, Contains(search)) | ||
492 | 151 | |||
493 | 152 | def test_non_protected_dirs(self): | ||
494 | 153 | search = "This is always available." | ||
495 | 154 | testfile = fetcher.get(host + not_protected_test_file) | ||
496 | 155 | self.assertThat(testfile, Contains(search)) | ||
497 | 156 | |||
498 | 157 | def test_accept_license_samsung_file(self): | ||
499 | 158 | search = "This is a protected with click-through Samsung license." | ||
500 | 159 | testfile = fetcher.get(host + samsung_test_file) | ||
501 | 160 | fetcher.close() | ||
502 | 161 | if os.path.exists("%s/cookies.txt" % docroot): | ||
503 | 162 | os.rename("%s/cookies.txt" % docroot, | ||
504 | 163 | "%s/cookies.samsung" % docroot) | ||
505 | 164 | self.assertThat(testfile, Contains(search)) | ||
506 | 165 | |||
507 | 166 | def test_accept_license_samsung_dir(self): | ||
508 | 167 | search = "Index of /android/~linaro-android/staging-origen" | ||
509 | 168 | testfile = fetcher.get(host + os.path.dirname(samsung_test_file)) | ||
510 | 169 | self.assertThat(testfile, Contains(search)) | ||
511 | 170 | |||
512 | 171 | def test_accept_license_ste_file(self): | ||
513 | 172 | search = "This is a protected with click-through ST-E license." | ||
514 | 173 | testfile = fetcher.get(host + ste_test_file) | ||
515 | 174 | fetcher.close() | ||
516 | 175 | if os.path.exists("%s/cookies.txt" % docroot): | ||
517 | 176 | os.rename("%s/cookies.txt" % docroot, "%s/cookies.ste" % docroot) | ||
518 | 177 | self.assertThat(testfile, Contains(search)) | ||
519 | 178 | |||
520 | 179 | def test_accept_license_ste_dir(self): | ||
521 | 180 | search = "Index of /android/~linaro-android/staging-snowball" | ||
522 | 181 | testfile = fetcher.get(host + os.path.dirname(ste_test_file)) | ||
523 | 182 | self.assertThat(testfile, Contains(search)) | ||
524 | 183 | |||
525 | 184 | def test_license_accepted_samsung(self): | ||
526 | 185 | search = "This is a protected with click-through Samsung license." | ||
527 | 186 | os.rename("%s/cookies.samsung" % docroot, "%s/cookies.txt" % docroot) | ||
528 | 187 | testfile = fetcher.get(host + samsung_test_file, ignore_license=True) | ||
529 | 188 | self.assertThat(testfile, Contains(search)) | ||
530 | 189 | |||
531 | 190 | def test_license_accepted_ste(self): | ||
532 | 191 | search = "This is a protected with click-through ST-E license." | ||
533 | 192 | os.rename("%s/cookies.ste" % docroot, "%s/cookies.txt" % docroot) | ||
534 | 193 | testfile = fetcher.get(host + ste_test_file, ignore_license=True) | ||
535 | 194 | self.assertThat(testfile, Contains(search)) | ||
536 | 195 | |||
537 | 196 | def test_internal_host_samsung(self): | ||
538 | 197 | search = "This is a protected with click-through Samsung license." | ||
539 | 198 | subprocess.Popen(['sed', '-i', '/## Let internal hosts through ' | ||
540 | 199 | 'always./ a %s' % local_rewrite, '%s/.htaccess' % docroot], | ||
541 | 200 | stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT).wait() | ||
542 | 201 | testfile = fetcher.get(host + samsung_test_file, ignore_license=True) | ||
543 | 202 | shutil.copy("%s/dothtaccess" % docroot, "%s/.htaccess" % docroot) | ||
544 | 203 | self.assertThat(testfile, Contains(search)) | ||
545 | 204 | |||
546 | 205 | def test_internal_host_ste(self): | ||
547 | 206 | search = "This is a protected with click-through ST-E license." | ||
548 | 207 | subprocess.Popen(['sed', '-i', '/## Let internal hosts through ' | ||
549 | 208 | 'always./ a %s' % local_rewrite, '%s/.htaccess' % docroot], | ||
550 | 209 | stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT).wait() | ||
551 | 210 | testfile = fetcher.get(host + ste_test_file, ignore_license=True) | ||
552 | 211 | shutil.copy("%s/dothtaccess" % docroot, "%s/.htaccess" % docroot) | ||
553 | 212 | self.assertThat(testfile, Contains(search)) |
Hi,
I have stuff running on port 8080, I modified through_ license. py to get a free port from the OS:
test_click_
=== modified file 'testing/ test_click_ through_ license. py' test_click_ through_ license. py 2012-01-13 08:02:11 +0000 test_click_ through_ license. py 2012-01-13 11:04:58 +0000
--- testing/
+++ testing/
@@ -2,14 +2,13 @@
import re
import os
-import sys
import shutil
import shlex
import subprocess
+import socket
from testtools import TestCase dFileFetcher
from testtools.matchers import Mismatch
-from testtools.matchers import MatchesAny
from filefetcher import LicenseProtecte
fetcher = LicenseProtecte dFileFetcher( )
@@ -19,7 +18,7 @@
local_rewrite = 'RewriteCond %{REMOTE_ADDR} 127.0.0.1 [OR]'
host = 'http:// 127.0.0. 1' license_ path = '/licenses/ samsung- v2.html' ste.html' ~linaro- android/ staging- origen/ test.txt' socket( socket. AF_INET, socket.SOCK_STREAM) ('127.0. 0.1', 0)) me()[1] )
shutil. copy("% s/apache2. conf.tmpl" % srvroot, "%s/apache2.conf" %
srvroot)
-port = '8080'
+port = '0' # 0 == Pick a free port.
samsung_
ste_license_path = '/licenses/
samsung_test_file = '/android/
@@ -55,7 +54,12 @@
@classmethod
def setUpClass(cls):
global host
- if port != '80':
+ global port
+ if port == '0':
+ s = socket.
+ s.bind(
+ port = str(s.getsockna
+ s.close()
host = host + ':' + port
I think you missed checking in a file: licenses/ nolicense. html - after
the above modification I have failing tests because of this.
I also deleted a few unused libraries. If you use the pep8 tool you
will find a string of issues that it has found with style. If you use
gedit you can install pep8 and pylint they will nag you about all
sorts of things :-) If you use gedit and install pylint, activate all
the plugins that ship with it and you will find that when you save a
python file you get the pep8 output as a sidebar, which is quite
useful. We also have a license for pycharm, which is a nice Python
IDE:
https:/ /wiki.linaro. org/Internal/ Licenses/ PyCharm
This has some stuff built in that makes hacking easier, but doesn't do
quite as much style nagging.
Nice start though - thanks for testing this.
James
On 12 January 2012 14:39, Georgy Redkozubov infrastructure) /code.launchpad .net/~gesha/ linaro- license- protection/ clickthrough- testing/ +merge/ 88387 /code.launchpad .net/~gesha/ linaro- license- protection/ clickthrough- testing/ +merge/ 88387
<email address hidden> wrote:
> Georgy Redkozubov has proposed merging lp:~gesha/linaro-license-protection/clickthrough-testing into lp:linaro-license-protection.
>
> Requested reviews:
> Linaro Infrastructure (linaro-
>
> For more details, see:
> https:/
>
> Added tests for click-through license feature using Testtools and Testrepository.
> --
> https:/
> Your team Linaro Infrastructure is requested to review the proposed merge of lp:~gesha/linaro-license-protection/clickthrough-testing into lp:linaro-license-protection.
>
> === modified file '.htaccess'
> --- .htaccess 2011-12-19 16:57:20 +0000
> +++ .htaccess 2012-01-12 14:37:26 +0000
> @@ -6,6 +6,8 @@
> ## Let internal hosts through always.
> ...