Skip to content

Call to pg_ctl fails (exception raised) when creating test database #1051

Open
@jamesfowkes

Description

@jamesfowkes

In summary, my issue is that when pytest-postgresql tries to use pg_ctl to create the test database, an exception is thrown. I can't see any particular information in the exception that might narrow down the specifics of what is happening.

I am pretty new to using postgres so please forgive any stupidity on my part.

System/environment information:

  • Windows 10
  • Running in VScode
  • Python 3.12.0 virtual environment
  • pytest-postgresql version 6.1.1
  • pg_ctl --version output is pg_ctl (PostgreSQL) 17.0

As far as I can see from various old issues, running on windows should be supported?

Issue Details
I am using the following code to create my application fixture:

from pytest_postgresql import factories
test_db = factories.postgresql_proc(port=None, dbname="test_db")

@pytest.fixture(scope="session")
def app(test_db):

    pg_host, pg_port, pg_user, pg_pass, pg_dbname = test_db.host, test_db.port, test_db.user, test_db.password, test_db.dbname
    connection_str = f"postgresql+psycopg2://{pg_user}:@{pg_host}:{pg_port}/{pg_dbname}"
    
    _app = create_app({
        "SQLALCHEMY_DATABASE_URI": connection_str
    })

    with _app.app_context():
        db.drop_all()
        db.create_all()

    yield _app

When I try to run a test, an exception is thrown at the point where pg_ctl is invoked to create the database (line 186 of executor.py):

.venv\Lib\site-packages\mirakuru\base.py:180: in __enter__
    return self.start()
.venv\Lib\site-packages\pytest_postgresql\executor.py:147: in start
    self.init_directory()
.venv\Lib\site-packages\pytest_postgresql\executor.py:186: in init_directory
    subprocess.check_output(init_directory, env=self._envvars, stderr=subprocess.STDOUT)
..\..\..\.pyenv\pyenv-win\versions\3.12.0\Lib\subprocess.py:466: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True
popenargs = (['C:/PROGRA~1/POSTGR~1/17/bin\\pg_ctl', 'initdb', '--pgdata', 'C:\\Users\\James\\AppData\\Local\\Temp\\pytest-of-James\\pytest-20\\pytest-postgresql-test_db0\\data-17330', '-o', '--username=postgres --auth=trust'],)
kwargs = {'env': {'LANG': 'C.UTF-8', 'LC_ALL': 'C.UTF-8', 'LC_CTYPE': 'C.UTF-8'}, 'stderr': -2, 'stdout': -1}
process = <Popen: returncode: 3221225477 args: ['C:/PROGRA~1/POSTGR~1/17/bin\\pg_ctl',...>
stdout = b'', stderr = None, retcode = 3221225477

< ... snip some lines for clarity ... >

>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['C:/PROGRA~1/POSTGR~1/17/bin\\pg_ctl', 'initdb', '--pgdata', 'C:\\Users\\James\\AppData\\Local\\Temp\\pytest-of-James\\pytest-20\\pytest-postgresql-test_db0\\data-17330', '-o', '--username=postgres --auth=trust']' returned non-zero exit status 3221225477.

..\..\..\.pyenv\pyenv-win\versions\3.12.0\Lib\subprocess.py:571: CalledProcessError

As far as I can tell there's no useful information captured by the exception.
If I try running this command on the terminal, I get this:

(.venv) PS C:\Users\James\Documents\Projects\glogbook-db> pg_ctl initdb --pgdata C:\\Users\\James\\AppData\\Local\\Temp\\pytest-of-James\\pytest-20\\pytest-postgresql-test_db0\\data-17330 -o --username=postgres --auth=trust
726b3549C:\Program Files\PostgreSQL\17\bin\pg_ctl.exe: illegal option -- auth=trust

so I commented out line 183 (options += ["--auth=trust"]), which resulted the same exception above being raised. If I run that command (i..e without --auth=trust) in the terminal, it appears to succeed:

(.venv) PS C:\Users\James\Documents\Projects\glogbook-db> pg_ctl initdb --pgdata C:\\Users\\James\\AppData\\Local\\Temp\\pytest-of-James\\pytest-20\\pytest-postgresql-test_db0\\data-17330 -o --username=postgres         
3;CThe files belonging to this database system will be owned by user "James".
This user must also own the server process.

The database cluster will be initialized with locale "English_United Kingdom.1252".
The default database encoding has accordingly been set to "WIN1252".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory C:/Users/James/AppData/Local/Temp/pytest-of-James/pytest-20/pytest-postgresql-test_db0/data-17330 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... windows
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Europe/London
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    "C:\Program Files\PostgreSQL\17\bin\pg_ctl" -D C:/Users/James/AppData/Local/Temp/pytest-of-James/pytest-20/pytest-postgresql-test_db0/data-17330 -l logfile start

Given I can run this command from a terminal, maybe there is a permissions issue with running under python/pytest (that's a guess)? Honestly I'm at a loss from here. Any advice would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageGathering informations

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions