| 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 |