Docker 化されたバージョンの wercker を使用して Python アプリで単体テストを実行しようとしていますが、ほとんどの単体テストがエラーで失敗しますsqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: No route to host
。wercker のドキュメントには、この接続を行うための構成がありません。
おそらく単純なものが欠けていますが、必要以上の時間を費やした後、このデータベース接続を確立してテストを実行することはできません。とにかく、Rails アプリに関する同様の質問がありますが、回答が役に立たないため、おそらく質問は Python アプリを使用している他の人に役立つでしょう。SOヘルプを探しています!
以下は私の現在のwercker.ymlです:
# http://devcenter.wercker.com/docs/containers/index.html
box: python:3.4.4-onbuild
# You can also use services such as databases. Read more on our dev center:
# http://devcenter.wercker.com/docs/services/index.html
services:
# http://devcenter.wercker.com/docs/services/postgresql.html
- id: postgres:9.4
env:
POSTGRES_PASSWORD: mylittlesecret
POSTGRES_USER: postgres # optional
# This is the build pipeline. Pipelines are the core of wercker
# Read more about pipelines on our dev center
# http://devcenter.wercker.com/docs/pipelines/index.html
build:
# The steps that will be executed on build
# Steps make up the actions in your pipeline
# Read more about steps on our dev center:
# http://devcenter.wercker.com/docs/steps/index.html
steps:
# A step that sets up the python virtual environment
- script:
name: virtualenv install
code: |
pip install virtualenv
- virtualenv:
name: venv
- pip-install:
requirements_file: "requirements.txt"
# A custom script step, name value is used in the UI
# and the code value contains the command that get executed
- script:
name: echo python information
code: |
echo "python version $(python --version) running"
echo "pip version $(pip --version) running"
# A step that loads the database schema in order to run the tests - perhaps not needed!!
- script:
name: Set up db
code: |
echo "Start postgresql server ..."
echo "Create test db ..."
echo "Created test db ..."
# Debug lines I've used in above script
# export PATH=/usr/pgsql-9.4.6/bin:$PATH ==> no impact
# export PATH=/usr/lib/postgresql/9.4/bin:$PATH ==> no impact
# psql -c "CREATE DATABASE scrdbtest;" ==> ERROR: psql command not found
# postgres -D /var/lib/postgresql/data ==> ERROR: postgres not found
- script:
name: run aoscrdb tests
code: |
/root/venv/bin/python -m pytest ./tests
そして、ここに私のアプリのテスト構成があります:
class TestConfig(Config):
TESTING = True
DEBUG = True
# wercker
SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://postgres:mylittlesecret@{}:5432/postgres'\
.format(os.environ.get('POSTGRES_PORT_5432_TCP_ADDR'))
最後に、失敗した wercker のテストの 1 つを次に示します。
============================= test session starts ==============================
platform linux -- Python 3.4.4, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: /pipeline/source/tests, inifile:
collected 39 items
tests/test_config.py ..
tests/test_forms.py EEEEEEEEEEEEEEE
tests/test_functional.py EEEEEEE
tests/test_models.py EEEEEEEEEEEEEEE
==================================== ERRORS ====================================
___ ERROR at setup of TestRegisterForm.test_validate_user_already_registered ___
app = <Flask 'aoscrdb_app.app'>
@pytest.yield_fixture(scope='function')
def db(app):
"""A database for the tests."""
_db.app = app
with app.app_context():
> _db.create_all()
tests/conftest.py:36:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/root/venv/lib/python3.4/site-packages/flask_sqlalchemy/__init__.py:972: in create_all
self._execute_for_all_tables(app, bind, 'create_all')
/root/venv/lib/python3.4/site-packages/flask_sqlalchemy/__init__.py:964: in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
/root/venv/lib/python3.4/site-packages/sqlalchemy/sql/schema.py:3695: in create_all
tables=tables)
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py:1855: in _run_visitor
with self._optional_conn_ctx_manager(connection) as conn:
/usr/local/lib/python3.4/contextlib.py:59: in __enter__
return next(self.gen)
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py:1848: in _optional_conn_ctx_manager
with self.contextual_connect() as conn:
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py:2039: in contextual_connect
self._wrap_pool_connect(self.pool.connect, None),
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py:2078: in _wrap_pool_connect
e, dialect, self)
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py:1405: in _handle_dbapi_exception_noconnection
exc_info
/root/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py:189: in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=exc_value)
/root/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py:182: in reraise
raise value.with_traceback(tb)
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py:2074: in _wrap_pool_connect
return fn()
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:376: in connect
return _ConnectionFairy._checkout(self)
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:713: in _checkout
fairy = _ConnectionRecord.checkout(pool)
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:480: in checkout
rec = pool._do_get()
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:1060: in _do_get
self._dec_overflow()
/root/venv/lib/python3.4/site-packages/sqlalchemy/util/langhelpers.py:60: in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
/root/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py:183: in reraise
raise value
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:1057: in _do_get
return self._create_connection()
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:323: in _create_connection
return _ConnectionRecord(self)
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:449: in __init__
self.connection = self.__connect()
/root/venv/lib/python3.4/site-packages/sqlalchemy/pool.py:607: in __connect
connection = self.__pool._invoke_creator(self)
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/strategies.py:97: in connect
return dialect.connect(*cargs, **cparams)
/root/venv/lib/python3.4/site-packages/sqlalchemy/engine/default.py:385: in connect
return self.dbapi.connect(*cargs, **cparams)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
dsn = 'dbname=postgres user=postgres password=mysecretpassword host=172.17.0.10'
database = 'postgres', user = 'postgres', password = 'mysecretpassword'
host = '172.17.0.10', port = None, connection_factory = None
cursor_factory = None, async = False, kwargs = {}
items = [('dbname', 'postgres'), ('user', 'postgres'), ('password', 'mysecretpassword'), ('host', '172.17.0.10')]
def connect(dsn=None,
database=None, user=None, password=None, host=None, port=None,
connection_factory=None, cursor_factory=None, async=False, **kwargs):
"""
Create a new database connection.
The connection parameters can be specified either as a string:
conn = psycopg2.connect("dbname=test user=postgres password=secret")
or using a set of keyword arguments:
conn = psycopg2.connect(database="test", user="postgres", password="secret")
The basic connection parameters are:
- *dbname*: the database name (only in dsn string)
- *database*: the database name (only as keyword argument)
- *user*: user name used to authenticate
- *password*: password used to authenticate
- *host*: database host address (defaults to UNIX socket if not provided)
- *port*: connection port number (defaults to 5432 if not provided)
Using the *connection_factory* parameter a different class or connections
factory can be specified. It should be a callable object taking a dsn
argument.
Using the *cursor_factory* parameter, a new default cursor factory will be
used by cursor().
Using *async*=True an asynchronous connection will be created.
Any other keyword parameter will be passed to the underlying client
library: the list of supported parameters depends on the library version.
"""
items = []
if database is not None:
items.append(('dbname', database))
if user is not None:
items.append(('user', user))
if password is not None:
items.append(('password', password))
if host is not None:
items.append(('host', host))
if port is not None:
items.append(('port', port))
items.extend([(k, v) for (k, v) in kwargs.items() if v is not None])
if dsn is not None and items:
raise TypeError(
"'%s' is an invalid keyword argument when the dsn is specified"
% items[0][0])
if dsn is None:
if not items:
raise TypeError('missing dsn and no parameters')
else:
dsn = " ".join(["%s=%s" % (k, _param_escape(str(v)))
for (k, v) in items])
> conn = _connect(dsn, connection_factory=connection_factory, async=async)
E sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: No route to host
E Is the server running on host "172.17.0.10" and accepting
E TCP/IP connections on port 5432?