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