-
Notifications
You must be signed in to change notification settings - Fork 311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add App Engine system tests #59
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
lib | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
api_version: 1 | ||
service: google-auth-system-tests | ||
runtime: python27 | ||
threadsafe: true | ||
|
||
handlers: | ||
- url: .* | ||
script: main.app | ||
|
||
libraries: | ||
- name: ssl | ||
version: 2.7.11 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Copyright 2016 Google Inc. | ||
# | ||
# 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. | ||
|
||
from google.appengine.ext import vendor | ||
|
||
# Add any libraries installed in the "lib" folder. | ||
vendor.add('lib') | ||
|
||
|
||
# Patch os.path.expanduser. This should be fixed in GAE | ||
# versions released after Nov 2016. | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
import os.path | ||
|
||
|
||
def patched_expanduser(path): | ||
return path | ||
|
||
os.path.expanduser = patched_expanduser |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# Copyright 2016 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. | ||
|
||
"""App Engine standard application that runs basic system tests for | ||
google.auth.app_engine. | ||
|
||
This application has to run tests manually instead of using py.test because | ||
py.test currently doesn't work on App Engine standard. | ||
""" | ||
|
||
import contextlib | ||
import json | ||
import sys | ||
from StringIO import StringIO | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
import traceback | ||
|
||
from google.appengine.api import app_identity | ||
import google.auth | ||
from google.auth import _helpers | ||
from google.auth import app_engine | ||
import google.auth.transport.urllib3 | ||
import urllib3.contrib.appengine | ||
import webapp2 | ||
|
||
TOKEN_INFO_URL = 'https://www.googleapis.com/oauth2/v3/tokeninfo' | ||
EMAIL_SCOPE = 'https://www.googleapis.com/auth/userinfo.email' | ||
HTTP = urllib3.contrib.appengine.AppEngineManager() | ||
HTTP_REQUEST = google.auth.transport.urllib3.Request(HTTP) | ||
|
||
|
||
def test_credentials(): | ||
credentials = app_engine.Credentials() | ||
scoped_credentials = credentials.with_scopes([EMAIL_SCOPE]) | ||
|
||
scoped_credentials.refresh(None) | ||
|
||
assert scoped_credentials.valid | ||
assert scoped_credentials.token is not None | ||
|
||
# Get token info and verify scope | ||
url = _helpers.update_query(TOKEN_INFO_URL, { | ||
'access_token': scoped_credentials.token, | ||
}) | ||
response = HTTP_REQUEST(url=url, method='GET') | ||
token_info = json.loads(response.data.decode('utf-8')) | ||
|
||
assert token_info['scope'] == EMAIL_SCOPE | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
|
||
def test_default(): | ||
credentials, project_id = google.auth.default() | ||
|
||
assert isinstance(credentials, app_engine.Credentials) | ||
assert project_id == app_identity.get_application_id() | ||
|
||
|
||
@contextlib.contextmanager | ||
def capture(): | ||
"""Context manager that captures stderr and stdout.""" | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
oldout, olderr = sys.stdout, sys.stderr | ||
try: | ||
out = StringIO() | ||
sys.stdout, sys.stderr = out, out | ||
yield out | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
finally: | ||
sys.stdout, sys.stderr = oldout, olderr | ||
|
||
|
||
def run_test_func(func): | ||
with capture() as capsys: | ||
try: | ||
func() | ||
return True, '' | ||
except Exception as exc: | ||
output = ( | ||
'Test {} failed: {}\n\n' | ||
'Stacktrace:\n{}\n\n' | ||
'Captured output:\n{}').format( | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
func.func_name, exc, traceback.format_exc(), | ||
capsys.getvalue()) | ||
return False, output | ||
|
||
|
||
def run_tests(): | ||
"""Runs all tests. | ||
|
||
Returns: | ||
Tuple[bool, str]: A tuple containing True if all tests pass, False | ||
otherwise, and any captured output from the tests. | ||
""" | ||
status = True | ||
output = '' | ||
|
||
tests = (test_credentials, test_default) | ||
|
||
for test in tests: | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
test_status, test_output = run_test_func(test) | ||
status = status and test_status | ||
output += test_output | ||
|
||
return status, output | ||
|
||
|
||
class MainHandler(webapp2.RequestHandler): | ||
def get(self): | ||
self.response.headers['content-type'] = 'text/plain' | ||
|
||
status, output = run_tests() | ||
|
||
if not status: | ||
self.response.status = 500 | ||
|
||
self.response.write(output) | ||
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
|
||
app = webapp2.WSGIApplication([ | ||
('/', MainHandler), | ||
], debug=True) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
urllib3 | ||
# Relative path to google-auth-python's source. | ||
../../.. | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Copyright 2016 Google Inc. | ||
# | ||
# 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. | ||
|
||
import os | ||
import subprocess | ||
|
||
from google.auth import _cloud_sdk | ||
import pytest | ||
|
||
SKIP_TEST_ENV = 'SKIP_APP_ENGINE_SYSTEM_TEST' | ||
HERE = os.path.dirname(__file__) | ||
TEST_APP_DIR = os.path.join(HERE, 'app') | ||
TEST_APP_SERVICE = 'google-auth-system-tests' | ||
|
||
|
||
def vendor_app_dependencies(): | ||
"""Vendors in the test application's third-party dependencies.""" | ||
subprocess.check_call( | ||
['pip', 'install', '--target', 'lib', '-r', 'requirements.txt']) | ||
|
||
|
||
def deploy_app(): | ||
"""Deploys the test application using gcloud.""" | ||
subprocess.check_call( | ||
['gcloud', 'app', 'deploy', '-q', 'app.yaml']) | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
|
||
|
||
@pytest.fixture | ||
def app(monkeypatch): | ||
monkeypatch.chdir(TEST_APP_DIR) | ||
|
||
vendor_app_dependencies() | ||
deploy_app() | ||
|
||
application_id = _cloud_sdk.get_project_id() | ||
application_url = 'https://{}-dot-{}.appspot.com'.format( | ||
TEST_APP_SERVICE, application_id) | ||
|
||
yield application_url | ||
|
||
|
||
@pytest.mark.skipif( | ||
SKIP_TEST_ENV in os.environ, | ||
reason='Explicitly skipping App Engine system tests.') | ||
def test_live_application(app, http_request): | ||
response = http_request(method='GET', url=app) | ||
assert response.status == 200, response.data.decode('utf-8') | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
This comment was marked as spam.
Sorry, something went wrong.