FatalError when testing more than the cases of the book

Steps to reproduce: Clone my project from GitHub and run all tests or alternatively duplicate the AcronymTests.swift file (in the folder “final” of chapter 11 or later) twice and rename the classes to AdditionalTests and AnotherSuiteOfTests (or whatever). Then run all the tests at once. It will fail at the 30th test which is more than the book offers.

The error reads: Thread 1: Fatal error: ‘try!’ expression unexpectedly raised an error: :warning: PostgreSQL Error: sorry, too many clients already

I have done some digging already, but can’t find a solution so far: https://github.com/bennokress/EventsAPI/issues/4

@0xtim Can you please help with this when you get a chance? Thank you - much appreciated! :]

There’s a bug in Application and tests where it doesn’t close the PSQL connections properly. Can you try adding this to each test case’s shutdown? That apparently is a fix

Sadly that seems like it’s not the fix for my problem. I’m still getting the same error. If you want to try it yourself, I’ve added your proposed fix on branch #4 of my repo.

Hmm I’m wondering if there’s another issue. Are you on the Discord channel? Since the project is available on GH, it could be a good candidate to track the bug down.

Also, it may be worth investigating the repository pattern and abstracting away the database. This should significantly speed up the tests as a side benefit!

I get the same error, even with the syncShutdownGracefully() code in teardown.
The PostgreSQL connections start up and then go idle. Once you hit max_connections, the error kicks in!
I’m experimenting with a connection pool now to see if it makes a difference.

Same results using a connection pool. Looks like not all connections are getting closed.

I set postgreSQL to log connections and disconnections. If I run a test with 4 test cases, I wind up with 38 connections being made. If I let the test run to completion, all 38 connections get disconnected. However, if I put a breakpoint at the end of my last test case, I have 9 or 10 connections that don’t get disconnected until I resume after the breakpoint.

Any ideas? Still digging!

Think I’ve got it!!!

The call to syncShutdownGracefully also needs to be done to the two apps created by the reset() method in Application+Testable.swift.

I changed this:

static func reset() throws {
  let revertEnvironment = ["vapor", "revert", "--all", "-y"]
  try Application.testable(envArgs: revertEnvironment).asyncRun().wait()
  let migrateEnvironment = ["vapor", "migrate", "-y"]
  try Application.testable(envArgs: migrateEnvironment).asyncRun().wait()

to this:

static func reset() throws {
  let revertEnvironment = ["vapor", "revert", "--all", "-y"]
  let app1 = try Application.testable(envArgs: revertEnvironment)
  try app1.asyncRun().wait()
  try app1.syncShutdownGracefully()
  let migrateEnvironment = ["vapor", "migrate", "-y"]
  let app2 = try Application.testable(envArgs: migrateEnvironment)
  try app2.asyncRun().wait()
  try app2.syncShutdownGracefully()

That will close out the connections used by the reset method.

Have fun!

1 Like

Sorry for not replying earlier. I had a lot on my plate for the last two weeks and didn’t come around to doing anything on the Vapor project.

@rcasey: your solution works perfectly on the book project and my own as well, thanks a lot for looking into it!

1 Like