OLD | NEW |
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """This file allows the bots to be easily configure and run the tests. | 6 """This file allows the bots to be easily configure and run the tests. |
7 | 7 |
8 Running this script requires passing --config-path with a path to a config file | 8 Running this script requires passing --config-path with a path to a config file |
9 of the following structure: | 9 of the following structure: |
10 [credentials] | 10 [credentials] |
11 pkey=full_path | 11 pkey=full_path |
12 client_email=email_assigned_by_google_dev_console | 12 client_email=email_assigned_by_google_dev_console |
13 [drive] | 13 [drive] |
14 key=sheet_key_from_sheet_url | 14 key=sheet_key_from_sheet_url |
15 [data_files] | 15 [data_files] |
16 passwords_path=full_path_to_the_file_with_passwords | 16 passwords_path=full_path_to_the_file_with_passwords |
17 """ | 17 """ |
18 from Sheet import Sheet | 18 from Sheet import Sheet |
19 from apiclient.discovery import build | 19 from apiclient.discovery import build |
20 from datetime import datetime | 20 from datetime import datetime |
21 from gdata.gauth import OAuth2TokenFromCredentials | 21 from gdata.gauth import OAuth2TokenFromCredentials |
22 from gdata.spreadsheet.service import SpreadsheetsService | 22 from gdata.spreadsheet.service import SpreadsheetsService |
23 from oauth2client.client import SignedJwtAssertionCredentials | 23 from oauth2client.client import SignedJwtAssertionCredentials |
24 import ConfigParser | 24 import ConfigParser |
25 import argparse | 25 import argparse |
26 import httplib2 | 26 import httplib2 |
27 import oauth2client.tools | 27 import oauth2client.tools |
28 import os | 28 import os |
| 29 import subprocess |
29 import tempfile | 30 import tempfile |
30 | 31 |
31 from environment import Environment | 32 from environment import Environment |
32 import tests | 33 import tests |
33 | 34 |
34 _CREDENTIAL_SCOPES = "https://spreadsheets.google.com/feeds" | 35 _CREDENTIAL_SCOPES = "https://spreadsheets.google.com/feeds" |
35 | 36 |
36 # TODO(melandory): Function _authenticate belongs to separate module. | 37 # TODO(melandory): Function _authenticate belongs to separate module. |
37 def _authenticate(pkey, client_email): | 38 def _authenticate(pkey, client_email): |
38 """ Authenticates user. | 39 """ Authenticates user. |
39 | 40 |
40 Args: | 41 Args: |
41 pkey: Full path to file with private key generated by Google | 42 pkey: Full path to file with private key generated by Google |
42 Developer Console. | 43 Developer Console. |
43 client_email: Email address corresponding to private key and also | 44 client_email: Email address corresponding to private key and also |
44 generated by Google Developer Console. | 45 generated by Google Developer Console. |
45 """ | 46 """ |
46 http, token = None, None | 47 http, token = None, None |
47 with open(pkey) as pkey_file: | 48 with open(pkey) as pkey_file: |
48 private_key = pkey_file.read() | 49 private_key = pkey_file.read() |
49 credentials = SignedJwtAssertionCredentials( | 50 credentials = SignedJwtAssertionCredentials( |
50 client_email, private_key, _CREDENTIAL_SCOPES) | 51 client_email, private_key, _CREDENTIAL_SCOPES) |
51 http = httplib2.Http() | 52 http = httplib2.Http() |
52 http = credentials.authorize(http) | 53 http = credentials.authorize(http) |
53 build('drive', 'v2', http=http) | 54 build('drive', 'v2', http=http) |
54 token = OAuth2TokenFromCredentials(credentials).access_token | 55 token = OAuth2TokenFromCredentials(credentials).access_token |
55 return http, token | 56 return http, token |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 except Exception: | 93 except Exception: |
93 pass | 94 pass |
94 # TODO(rchtara): Using "timeout is just temporary until a better, | 95 # TODO(rchtara): Using "timeout is just temporary until a better, |
95 # platform-independent solution is found. | 96 # platform-independent solution is found. |
96 | 97 |
97 # The website test runs in two passes, each pass has an internal | 98 # The website test runs in two passes, each pass has an internal |
98 # timeout of 200s for waiting (see |remaining_time_to_wait| and | 99 # timeout of 200s for waiting (see |remaining_time_to_wait| and |
99 # Wait() in websitetest.py). Accounting for some more time spent on | 100 # Wait() in websitetest.py). Accounting for some more time spent on |
100 # the non-waiting execution, 300 seconds should be the upper bound on | 101 # the non-waiting execution, 300 seconds should be the upper bound on |
101 # the runtime of one pass, thus 600 seconds for the whole test. | 102 # the runtime of one pass, thus 600 seconds for the whole test. |
102 # TODO(vabr): Use subprocess.call. | 103 subprocess.call(["timeout", "600"] + test_cmd) |
103 os.system("timeout 600 %s" % test_cmd) | |
104 if os.path.isfile(results_path): | 104 if os.path.isfile(results_path): |
105 results = open(results_path, "r") | 105 results = open(results_path, "r") |
106 count = 0 # Count the number of successful tests. | 106 count = 0 # Count the number of successful tests. |
107 for line in results: | 107 for line in results: |
108 # TODO(melandory): We do not need to send all this data to sheet. | 108 # TODO(melandory): We do not need to send all this data to sheet. |
109 failures.append(line) | 109 failures.append(line) |
110 count += line.count("successful='True'") | 110 count += line.count("successful='True'") |
111 results.close() | 111 results.close() |
112 # There is only two tests running for every website: the prompt and | 112 # There is only two tests running for every website: the prompt and |
113 # the normal test. If both of the tests were successful, the tests | 113 # the normal test. If both of the tests were successful, the tests |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 results = tempfile.NamedTemporaryFile( | 145 results = tempfile.NamedTemporaryFile( |
146 dir=os.path.join(tempfile.gettempdir()), delete=False) | 146 dir=os.path.join(tempfile.gettempdir()), delete=False) |
147 results_path = results.name | 147 results_path = results.name |
148 results.close() | 148 results.close() |
149 | 149 |
150 full_path = os.path.realpath(__file__) | 150 full_path = os.path.realpath(__file__) |
151 tests_dir = os.path.dirname(full_path) | 151 tests_dir = os.path.dirname(full_path) |
152 tests_path = os.path.join(tests_dir, "tests.py") | 152 tests_path = os.path.join(tests_dir, "tests.py") |
153 | 153 |
154 for websitetest in environment.websitetests: | 154 for websitetest in environment.websitetests: |
155 test_cmd = ("python %s %s --chrome-path %s " | 155 test_cmd = ["python", tests_path, websitetest.name, |
156 "--chromedriver-path %s" | 156 "--chrome-path", chrome_path, |
157 "--passwords-path %s --profile-path %s " | 157 "--chromedriver-path", chromedriver_path, |
158 "--save-path %s" % | 158 "--passwords-path", |
159 (tests_path, websitetest.name, chrome_path, | 159 config.get("data_files", "passwords_path"), |
160 chromedriver_path, | 160 "--profile-path", profile_path, |
161 config.get("data_files", "passwords_path"), | 161 "--save-path", results_path] |
162 profile_path, results_path)) | 162 status, log = _try_run_individual_test(test_cmd, results_path) |
163 status, log = _try_run_individual_test( | |
164 websitetest, test_cmd, results_path) | |
165 try: | 163 try: |
166 sheet.InsertRow(sheet.row_count, | 164 sheet.InsertRow(sheet.row_count, |
167 [websitetest.name, status, date, " | ".join(log)]) | 165 [websitetest.name, status, date, " | ".join(log)]) |
168 except Exception: | 166 except Exception: |
169 pass # TODO(melandory): Sometimes writing to spreadsheet fails. We need | 167 pass # TODO(melandory): Sometimes writing to spreadsheet fails. We need |
170 # deal with it better that just ignoring. | 168 # deal with it better that just ignoring. |
171 finally: | 169 finally: |
172 try: | 170 try: |
173 os.remove(results_path) | 171 os.remove(results_path) |
174 except Exception: | 172 except Exception: |
(...skipping 14 matching lines...) Expand all Loading... |
189 help="File with configuration data: drive credentials, password path", | 187 help="File with configuration data: drive credentials, password path", |
190 required=True) | 188 required=True) |
191 parser.add_argument( | 189 parser.add_argument( |
192 "--profile-path", action="store", dest="profile_path", | 190 "--profile-path", action="store", dest="profile_path", |
193 help="Set the profile path (required). You just need to choose a " | 191 help="Set the profile path (required). You just need to choose a " |
194 "temporary empty folder. If the folder is not empty all its content " | 192 "temporary empty folder. If the folder is not empty all its content " |
195 "is going to be removed.", | 193 "is going to be removed.", |
196 required=True) | 194 required=True) |
197 args = vars(parser.parse_args()) | 195 args = vars(parser.parse_args()) |
198 run_tests(**args) | 196 run_tests(**args) |
OLD | NEW |