CloverHealth / pytest-pgsql

Clean PostgreSQL Databases for Your Tests
http://pytest-pgsql.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
65 stars 4 forks source link

Potential bug? RuntimeError: command not found: initdb when running on Windows #21

Closed bastienboutonnet closed 3 years ago

bastienboutonnet commented 3 years ago

I am getting a weird issue when running the tests in a windows-latest GitHub action which doesn't ever come up when I test locally (on MacOSX) nor when I run my tox testing suite locally.

When running on a windows container (github actions) I get the following error message RuntimeError: command not found: initdb (full traceback below). Not sure if it's a known issue or if I'm doing something wrong.

GitHub Action tox/pytest run output

________________________ ERROR at setup of test_select ________________________

request = <SubRequest 'database_uri' for <Function test_select>>

    @pytest.fixture(scope='session')
    def database_uri(request):
        """A fixture giving the connection URI of the session-wide test database."""
        # Note: due to the nature of the variable configs, the command line options
        # must be tested manually.

        work_mem = request.config.getoption('--pg-work-mem')
        if work_mem < 0:    # pragma: no cover
            pytest.exit('ERROR: --pg-work-mem value must be >= 0. Got: %d' % work_mem)
            return
        elif work_mem == 0:  # pragma: no cover
            # Disable memory tweak and use the server default.
            work_mem_setting = ''
        else:
            # User wants to change the working memory setting.
            work_mem_setting = '-c work_mem=%dMB ' % work_mem

        # pylint: disable=bad-continuation,deprecated-method
        conf_opts = request.config.getoption('--pg-conf-opt')
        if conf_opts:
            conf_opts_string = ' -c ' + ' -c '.join(conf_opts)
        else:
            conf_opts_string = ''

        with testing.postgresql.Postgresql(
            postgres_args='-c TimeZone=UTC '
                          '-c fsync=off '
                          '-c synchronous_commit=off '
                          '-c full_page_writes=off '
                          + work_mem_setting +
                          '-c checkpoint_timeout=30min '
                          '-c bgwriter_delay=10000ms'
>                         + conf_opts_string
                            ) as pgdb:

.tox\py\lib\site-packages\pytest_pgsql\plugin.py:64: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox\py\lib\site-packages\testing\common\database.py:92: in __init__
    self.initialize()
.tox\py\lib\site-packages\testing\postgresql.py:50: in initialize
    self.initdb = find_program('initdb', ['bin'])
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'initdb', subdirs = ['bin']

    def find_program(name, subdirs):
        path = get_path_of(name)
        if path:
            return path

        for base_dir in SEARCH_PATHS:
            for subdir in subdirs:
                path = os.path.join(base_dir, subdir, name)
                if os.path.exists(path):
                    return path

>       raise RuntimeError("command not found: %s" % name)
E       RuntimeError: command not found: initdb

.tox\py\lib\site-packages\testing\postgresql.py:144: RuntimeError

This is how the test is set up:

#FILE: db_test.py

from pathlib import Path

TEST_DIR = Path(__file__).resolve().parent

def test_select(postgresql_db):
    # this populates the db with stuff from the sql file.
    # We could also just run a conn.execute if we wanted to.
    postgresql_db.run_sql_file(str(TEST_DIR.joinpath("docker_postgres", "db_setup.sql")))
    with postgresql_db.engine.connect() as conn:
        r = conn.execute("SELECT * FROM test")
        results = list()
        for row in r:
            results.append(dict(row))
        print(results)

and this is the SQL it populates the db with (referred to in the previous snippet.

-- FILE: db_setup.py
CREATE TABLE test (id serial PRIMARY KEY, answer integer, question varchar);

INSERT INTO test VALUES
    (1, 11, 'hello hello world'),
    (2, 42, 'what is the meaning of life?')
    ;

To get all the context and see the code you can check the PR on my repo if you need (it's open): https://github.com/bitpicky/dbt-sugar/pull/17

dargueta commented 3 years ago

Sorry if this comes off as condescending but are you sure you have Postgres installed? Not the Python package, the actual database.

bastienboutonnet commented 3 years ago

@dargueta not condescnding at all it's a fair question. However, I was under the impression that using those fixtures mean I do not have to install postgres nor spring it up in a container or so.

Am I mistaken?

dargueta commented 3 years ago

You need Postgres installed but you don't need to set up a database. As long as the Postgres runtime library is available, Python will be able to handle the rest. The system requirements are listed in the documentation here.

bastienboutonnet commented 3 years ago

Oops sorry I ended up not ever replying to you on this.

In the end my CI setup got a little more complex so I went for a more "manual" docker setup but that does make sense what you say. Feel free to close this issue.

And thanks for your help

dargueta commented 3 years ago

@jsnb or @HelenMc do you still have ownership of the repo? I can't close the issue.

bastienboutonnet commented 3 years ago

@dargueta I can close it if you want since I created the issue.

dargueta commented 3 years ago

That works too