configurationwercker.yml在需要postgres服务的python应用程序中运行unit testing

我正在尝试使用dockerized版本的wercker在python应用程序中运行unit testing,但大部分unit testing失败,并报错sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: No route to host 。 Wercker文档缺乏configuration来build立这种连接。

也许我错过了简单的东西,但我不能让这个数据库连接运行我的testing后,花费比我应该有更多的时间。 无论如何,也有类似的问题的Rails应用程序,但答案不帮助,所以也许问题将帮助其他人与Python应用程序。 寻找这样的帮助!

以下是我目前的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 

这里是我的应用程序testingconfiguration:

 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的失败testing:

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