diff --git a/.travis.yml b/.travis.yml index 992d84eec04..58b60aaf72c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: python services: - memcached - mysql +- redis-server branches: only: - master diff --git a/appengine/flexible/redis/app.yaml b/appengine/flexible/redis/app.yaml new file mode 100644 index 00000000000..6959de368c5 --- /dev/null +++ b/appengine/flexible/redis/app.yaml @@ -0,0 +1,13 @@ +runtime: python +vm: true +entrypoint: gunicorn -b :$PORT main:app + +runtime_config: + python_version: 3 + +# [START env_variables] +env_variables: + REDIS_HOST: your-redis-host + REDIS_PORT: your-redis-port + REDIS_PASSWORD: your-redis-password +# [END env_variables] diff --git a/appengine/flexible/redis/main.py b/appengine/flexible/redis/main.py new file mode 100644 index 00000000000..08102e031ff --- /dev/null +++ b/appengine/flexible/redis/main.py @@ -0,0 +1,59 @@ +# 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. + +import logging +import os + +from flask import Flask +import redis + + +app = Flask(__name__) + + +# [START client] +redis_host = os.environ.get('REDIS_HOST', 'localhost') +redis_port = int(os.environ.get('REDIS_PORT', 6379)) +redis_password = os.environ.get('REDIS_PASSWORD', None) +redis_client = redis.StrictRedis( + host=redis_host, port=redis_port, password=redis_password) +# [END client] + + +# [START example] +@app.route('/') +def index(): + # Set initial value if necessary + if not redis_client.get('counter'): + redis_client.set('counter', 0) + + value = redis_client.incr('counter', 1) + + return 'Value is {}'.format(value) +# [END example] + + +@app.errorhandler(500) +def server_error(e): + logging.exception('An error occurred during a request.') + return """ + An internal error occurred:
{}+ See logs for full stacktrace. + """.format(e), 500 + + +if __name__ == '__main__': + # This is used when running locally. Gunicorn is used to run the + # application on Google App Engine. See entrypoint in app.yaml. + app.run(host='127.0.0.1', port=8080, debug=True) diff --git a/appengine/flexible/redis/main_test.py b/appengine/flexible/redis/main_test.py new file mode 100644 index 00000000000..fb4562d6cac --- /dev/null +++ b/appengine/flexible/redis/main_test.py @@ -0,0 +1,34 @@ +# 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. + +import main +import pytest + + +def test_index(): + try: + main.redis_client.set('counter', 0) + except Exception: + pytest.skip('Redis is unavailable.') + + main.app.testing = True + client = main.app.test_client() + + r = client.get('/') + assert r.status_code == 200 + assert '1' in r.data.decode('utf-8') + + r = client.get('/') + assert r.status_code == 200 + assert '2' in r.data.decode('utf-8') diff --git a/appengine/flexible/redis/requirements.txt b/appengine/flexible/redis/requirements.txt new file mode 100644 index 00000000000..ae1f74f8b93 --- /dev/null +++ b/appengine/flexible/redis/requirements.txt @@ -0,0 +1,3 @@ +Flask==0.11.1 +gunicorn==19.6.0 +redis==2.10.5 diff --git a/nox.py b/nox.py index 7980569104f..5b742e85f41 100644 --- a/nox.py +++ b/nox.py @@ -137,9 +137,14 @@ def run_tests_in_sesssion( for reqfile in list_files(dirname, 'requirements*.txt'): session.install('-r', reqfile) + # Ignore lib and env directories + ignore_args = [ + '--ignore', os.path.join(sample, 'lib'), + '--ignore', os.path.join(sample, 'env')] + session.run( 'py.test', sample, - *pytest_args, + *(pytest_args + ignore_args), success_codes=[0, 5]) # Treat no test collected as success.