Adding system tests to make sure token exchange works as expected.

- Updates CONTRIBUTING.md to explain how to set-up and run these tests.
- Requires a version of httplib2 that has not been released on PyPI
  yet in order to work on Python 3.
- Simply creates 3 different token types (JSON key for svc. acct.,
  P12 key for svc. acct., JSON key for user acct.) and then authorizes
  an httplib2.Http object to hit the USERINFO API.
This commit is contained in:
Danny Hermes
2015-04-13 10:06:18 -07:00
parent 0a6241c792
commit 659869f19a
7 changed files with 211 additions and 1 deletions

3
.gitignore vendored
View File

@@ -15,3 +15,6 @@ docs/_build
.coverage
coverage.xml
nosetests.xml
# Files with private / local data
scripts/local_test_setup

View File

@@ -90,6 +90,49 @@ Running Tests
$ tox
```
Running System Tests
--------------------
- To run system tests you can execute:
```bash
$ tox -e system-tests
$ tox -e system-tests3
```
This alone will not run the tests. You'll need to change some local
auth settings and download some service account configuration files
from your project to run all the tests.
- System tests will be run against an actual project and so you'll need to
provide some environment variables to facilitate this.
- `OAUTH2CLIENT_TEST_JSON_KEY_PATH`: The path to a service account JSON
key file; see `tests/data/gcloud/application_default_credentials.json`
as an example. Such a file can be downloaded directly from the
developer's console by clicking "Generate new JSON key". See private
key [docs][3] for more details.
- `OAUTH2CLIENT_TEST_P12_KEY_PATH`: The path to a service account
P12/PKCS12 key file. You can download this in the same way as a JSON
key, just select "P12 Key" as your "Key type" when downloading.
- `OAUTH2CLIENT_TEST_P12_KEY_EMAIL`: The service account email
corresponding to the P12/PKCS12 key file.
- `OAUTH2CLIENT_TEST_USER_KEY_PATH`: The path to a JSON key file for a
user. If this is not set, the file created by running
`gcloud auth login` will be used. See
`tests/data/gcloud/application_default_credentials_authorized_user.json`
for an example.
- `OAUTH2CLIENT_TEST_USER_KEY_EMAIL`: The user account email
corresponding to the user JSON key file.
- Examples of these can be found in `scripts/local_test_setup.sample`. We
recommend copying this to `scripts/local_test_setup`, editing the values
and sourcing them into your environment:
```bash
$ source scripts/local_test_setup
```
Contributor License Agreements
------------------------------

View File

@@ -0,0 +1,5 @@
export OAUTH2CLIENT_TEST_JSON_KEY_PATH="tests/data/gcloud/application_default_credentials.json"
export OAUTH2CLIENT_TEST_P12_KEY_PATH="tests/data/privatekey.p12"
export OAUTH2CLIENT_TEST_P12_KEY_EMAIL="project-foo@developer.gserviceaccount.com"
export OAUTH2CLIENT_TEST_USER_KEY_PATH="tests/data/gcloud/application_default_credentials_authorized_user.json"
export OAUTH2CLIENT_TEST_USER_KEY_EMAIL="foo@gmail.com"

107
scripts/run_system_tests.py Normal file
View File

@@ -0,0 +1,107 @@
import json
import os
import httplib2
from oauth2client import client
from oauth2client import service_account
JSON_KEY_PATH = os.getenv('OAUTH2CLIENT_TEST_JSON_KEY_PATH')
P12_KEY_PATH = os.getenv('OAUTH2CLIENT_TEST_P12_KEY_PATH')
P12_KEY_EMAIL = os.getenv('OAUTH2CLIENT_TEST_P12_KEY_EMAIL')
USER_KEY_PATH = os.getenv('OAUTH2CLIENT_TEST_USER_KEY_PATH',
client._get_well_known_file())
USER_KEY_EMAIL = os.getenv('OAUTH2CLIENT_TEST_USER_KEY_EMAIL')
SCOPE = ('https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile')
USER_INFO = 'https://www.googleapis.com/oauth2/v2/userinfo'
def _require_environ():
if (JSON_KEY_PATH is None or P12_KEY_PATH is None or
P12_KEY_EMAIL is None or USER_KEY_PATH is None or
USER_KEY_EMAIL is None):
raise EnvironmentError('Expected environment variables to be set:',
'OAUTH2CLIENT_TEST_JSON_KEY_PATH',
'OAUTH2CLIENT_TEST_P12_KEY_PATH',
'OAUTH2CLIENT_TEST_P12_KEY_EMAIL',
'OAUTH2CLIENT_TEST_USER_KEY_PATH',
'OAUTH2CLIENT_TEST_USER_KEY_EMAIL')
if not os.path.isfile(JSON_KEY_PATH):
raise EnvironmentError(JSON_KEY_PATH, 'is not a file')
if not os.path.isfile(P12_KEY_PATH):
raise EnvironmentError(P12_KEY_PATH, 'is not a file')
if not os.path.isfile(USER_KEY_PATH):
raise EnvironmentError(USER_KEY_PATH, 'is not a file')
def _check_user_info(credentials, expected_email):
http = credentials.authorize(httplib2.Http())
response, content = http.request(USER_INFO)
if response.status != 200:
raise ValueError('Expected 200 response.')
content = content.decode('utf-8')
payload = json.loads(content)
if payload['email'] != expected_email:
raise ValueError('User info email does not match credentials.')
def run_json():
with open(JSON_KEY_PATH, 'r') as file_object:
client_credentials = json.load(file_object)
credentials = service_account._ServiceAccountCredentials(
service_account_id=client_credentials['client_id'],
service_account_email=client_credentials['client_email'],
private_key_id=client_credentials['private_key_id'],
private_key_pkcs8_text=client_credentials['private_key'],
scopes=SCOPE,
)
_check_user_info(credentials, client_credentials['client_email'])
def run_p12():
with open(P12_KEY_PATH, 'rb') as file_object:
private_key_contents = file_object.read()
credentials = client.SignedJwtAssertionCredentials(
service_account_name=P12_KEY_EMAIL,
private_key=private_key_contents,
scope=SCOPE,
)
_check_user_info(credentials, P12_KEY_EMAIL)
def run_user_json():
with open(USER_KEY_PATH, 'r') as file_object:
client_credentials = json.load(file_object)
credentials = client.GoogleCredentials(
access_token=None,
client_id=client_credentials['client_id'],
client_secret=client_credentials['client_secret'],
refresh_token=client_credentials['refresh_token'],
token_expiry=None,
token_uri=client.GOOGLE_TOKEN_URI,
user_agent='Python client library',
)
_check_user_info(credentials, USER_KEY_EMAIL)
def main():
_require_environ()
run_json()
run_p12()
run_user_json()
if __name__ == '__main__':
main()

34
scripts/run_system_tests.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -ev
# If we're on Travis, we need to set up the environment.
if [[ "${TRAVIS}" == "true" ]]; then
# If merging to master and not a pull request, run system test.
if [[ "${TRAVIS_BRANCH}" == "master" ]] && \
[[ "${TRAVIS_PULL_REQUEST}" == "false" ]]; then
echo "Running in Travis during merge, not setup correctly yet."
exit 1
else
echo "Running in Travis during non-merge to master, doing nothing."
exit
fi
fi
# Run the system tests for each tested package.
python scripts/run_system_tests.py

View File

@@ -35,7 +35,7 @@ packages = [
]
install_requires = [
'httplib2>=0.8',
'httplib2>=0.9.1',
'pyasn1==0.1.7',
'pyasn1_modules==0.0.5',
'rsa==3.1.4',

18
tox.ini
View File

@@ -72,3 +72,21 @@ basepython = python2.7
deps = {[testenv]basedeps}
django>=1.5,<1.6
pyopenssl<0.14
[testenv:system-tests]
basepython =
python2.7
commands =
{toxinidir}/scripts/run_system_tests.sh
deps =
pycrypto==2.6
pyopenssl==0.14
[testenv:system-tests3]
basepython =
python3.4
commands =
{toxinidir}/scripts/run_system_tests.sh
deps =
pycrypto==2.6
pyopenssl==0.14