oguimbal / pg-mem

An in memory postgres DB instance for your unit tests
MIT License
1.98k stars 97 forks source link

Stand-alone instance of pg-mem #360

Closed rkristelijn closed 2 months ago

rkristelijn commented 1 year ago

It would be great to be able to spin up pg-mem as a standalone server, exposing the postgres port and having data to perform end-to-end tests, e.g. doing graphql queries to your app, specifically to run in a pipeline.

Now it feels like you still need to integrate pg-mem into your test framework, e.g. jest. It would be great if one could separate it and use start-server-and-test to fire up the app and start testing.

Before I spend a lot of time figuring how, I would like to understand if such a thing is possible using pg-mem or it is time wasted.

Thanks for the effort already so far and your reply!

rkristelijn commented 1 year ago

anyway this is how far I came setting up a stand-alone database server; it doesn't respond ok to a connect command:

https://github.com/rkristelijn/pg-mem-server

dmurvihill commented 10 months ago

I think there is other software that might be better suited for this use case.

rkristelijn commented 10 months ago

@dmurvihill can you elaborate how to spin up a db from within docker (docker in docker) in a pipeline? Thanks!

dmurvihill commented 10 months ago

Here's my Compose file. The db container starts the db and the migrate container runs the migrations. Not tested with docker-in-docker, so YMMV.

  db:
    image: 'postgres:15.3-alpine3.18'
    ports:
      - '5432:5432'
    environment:
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=myapp

  migrate:
    build:
      context: 'my-project'
      target: 'my-migrations'
    entrypoint: "sh -c 'sleep 10 && npm run migration:up && npm run seed'"
    environment:
      - DATABASE_HOST=db
      - DATABASE_PW=postgres
    volumes:
      - './my-project/src:/my-project/src'
    depends_on:
      - db
oguimbal commented 10 months ago

FYI what you seem to describe looks like an experiment I already tried here https://github.com/oguimbal/pg-server

It kind-of works, but the fact that pg-mem does not support prepared statements and long lived transactions prevents it from being really functional for all use cases.

That, and the SSL mode which is not implemented (which is mandatory for some use cases).

Having full support of this is a pretty big refactoring I'd really like to have the time to do someday, as it is kind of the only way (currently) to use pg-mem to test with Prisma ... see issue #27

... but unfortunately, I have a company to run, and thus had very few time to work on this recently.

But that said, @dmurvihill is right when he says that sometimes, an actual pg server might be a better choice, depending on your use case :) (in the end, pg-mem is meant to simplify unit testing, not to be a fully fledged pg server)

oguimbal commented 10 months ago

Oh, it seems that I read a bit too fast, and I did not see your link to https://github.com/rkristelijn/pg-mem-server :) nice

That's pretty old in my memory, but I managed to connect to a pg-server with pg-mem with DBeaver... The thing that made me loose a ton of time was the realization that most drivers try to use the SSL mode by default (which is not supported ... you might see errors about protocol version 1234.5679 if that's the case)

rkristelijn commented 10 months ago

Thanks for the tip @oguimbal I will have a look if ssl mode is the case and report back here. All I want to accomplish is just faking select queries without having to spin up a full postgres db to support integration test. By this I mean, spinning up the full app and test it's behaviour when it is doing simple select statements on the other end

oguimbal commented 2 months ago

Hi there, this is now feasible with pg-mem@3.0.1, using db.adapter.bindServer(), but expect some trouble:

To be noded: pg-mem is NOT aiming to be a fully fledged postgres in-memory server, and only targets unit testing. ... this has only be implemend to help solve Prisma integration until a more practical way of hooking Prisma is implemented