Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update test memory leaks #2394

Merged
merged 18 commits into from Feb 27, 2024
Merged

chore: update test memory leaks #2394

merged 18 commits into from Feb 27, 2024

Conversation

mkurapov
Copy link
Contributor

@mkurapov mkurapov commented Feb 5, 2024

Changes proposed in this pull request

  • Fixes memory leak related to nock, backend tests can now be run serially (via --runInBand) without running out of memory. This was verified using the --detectLeaks flag for jest tests, which would throw an error if detected a memory leak during a test.
  • Properly spins down tigerbeetle container during tests using a custom environment
  • Sets log level to silent for tests
  • Improves commands related to app shutdown & tests teardown (should help with the amount of open handles the tests have). I fixed this error message:

"A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them."

when running the test:ci command, but at 100% workers, it still appears on my machine 🤷 . But at least some progress there.

Context

Fixes #2393
Fixes #1094 (even though it seemed like the thread panic wasn't an issue with newer versions of tigerbeetle)

Checklist

  • Related issues linked using fixes #number
  • Tests added/updated
  • Documentation added
  • Make sure that all checks pass
  • Postman collection updated

Copy link

netlify bot commented Feb 5, 2024

Deploy Preview for brilliant-pasca-3e80ec canceled.

Name Link
🔨 Latest commit 924b90f
🔍 Latest deploy log https://app.netlify.com/sites/brilliant-pasca-3e80ec/deploys/65ddb68435417d000885c6b2

@github-actions github-actions bot added type: tests Testing related pkg: backend Changes in the backend package. type: source Changes business logic labels Feb 5, 2024
@mkurapov mkurapov changed the title 2393/mk/memory leak chore: update test memory leaks Feb 5, 2024
@@ -43,7 +43,6 @@
"jest": "^29.7.0",
"npm-run-all2": "^5.0.2",
"prettier": "^3.2.4",
"ts-jest": "^29.1.2",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use @swc/jest instead, not needed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BlairCurrey was about to merge until I saw this, fixed now 👍

Comment on lines +614 to 616
if (this.apolloServer) {
await this.apolloServer.stop()
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we do plugins: [ApolloServerPluginDrainHttpServer({ httpServer })] when creating the apollo server, the httpServer will be automatically stopped/connections will be drained. However, before we weren't closing the actual apollo server that does other operations as well: https://www.apollographql.com/docs/apollo-server/api/apollo-server/#stop

await redis.flushall()
})

afterAll(async () => {
redis.disconnect()
jest.useRealTimers()
await redis.quit()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be the preferred way to stop redis connections: redis/ioredis#1088

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about resetting the timers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it to the afterEach

@@ -33,10 +36,14 @@ describe('Accounting Service', (): void => {
}

beforeAll(async (): Promise<void> => {
const { port } = await startTigerbeetleContainer()
Config.tigerbeetleReplicaAddresses = [port.toString()]
const tigerbeetlePort = (global as unknown as { tigerbeetlePort: number })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gets injected via the tigerbeetle test environment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this suggestion applies here as well: https://github.com/interledger/rafiki/pull/2394/files#r1480529987

@@ -106,7 +112,7 @@ describe('Accounting Service', (): void => {
},
LiquidityAccountType.ASSET
)
).rejects.toThrowError(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using toThrowError gave me a deprecated warning

@@ -5,7 +5,7 @@ import { faker } from '@faker-js/faker'

export const IlpPrepareFactory = Factory.define<IlpPrepare>('IlpPrepare').attrs(
{
amount: faker.finance.amount(1, 100, 0),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this type signature is deprecated (was giving me warnings)

@@ -0,0 +1,9 @@
import { TestEnvironment } from 'jest-environment-node'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Main change. Described here: nock/nock#2358

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess these nock changes are needed even after this fix? nock/nock#2572 It looks like we are on the latest and have this fix. I suppose there were two issues:

  • nock leaking from simply being imported (fixed above)
  • us not cleaning it up properly which still require these changes

Comment on lines +1 to +3
/**
* @jest-environment ./packages/backend/jest.tigerbeetle-environment.ts
*/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

specifies specific environment for this test suite

@mkurapov mkurapov marked this pull request as ready for review February 5, 2024 19:51
@BlairCurrey
Copy link
Contributor

I was not familiar with --runInBand so I looked it up. In doing so it seems like it might be faster to use --runInBand in CI? This is tangential, but perhaps its worth testing if we haven't already. --runInBand took about 50% longer for me locally FWIW but thats on an m2 Max and the ubuntu runner is 4 cores/16gb memory so maybe it could be faster? 🤷‍♂️

@@ -20,6 +19,8 @@ import { CreateOrUpdatePeerByUrlInput } from '../generated/graphql'
import { AutoPeeringService } from '../../payment-method/ilp/auto-peering/service'
import { v4 as uuid } from 'uuid'

const nock = (global as unknown as { nock: typeof import('nock') }).nock
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this?

add this to a new file at rafiki/packages/backend/src/global.d.ts:

declare module globalThis {
  var nock: typeof import('nock')
}

which lets us just do:

const nock = global.nock

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I dont love that this suggests nock is on global anywhere (including outside tests, or outside the that specific test environment) ... was just thinking maybe we could avoid doing all this casting every time we want to use it. alternatively maybe we can initialize it like this once somewhere and export it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too fond of this long casting, but I think I prefer not mixing the shipped code vs the testing code IMO

@BlairCurrey
Copy link
Contributor

Runs fine for me locally (including maxWorkers=100% for whatever that is worth)

@sabineschaller
Copy link
Member

I was not familiar with --runInBand so I looked it up. In doing so it seems like it might be faster to use --runInBand in CI? This is tangential, but perhaps its worth testing if we haven't already. --runInBand took about 50% longer for me locally FWIW but thats on an m2 Max and the ubuntu runner is 4 cores/16gb memory so maybe it could be faster? 🤷‍♂️

Very interesting. I think we should give it a try. I also didn't know that flag.

@sabineschaller
Copy link
Member

@mkurapov ♥️♥️♥️ Thank you for tackling this ♥️♥️♥️

@mkurapov
Copy link
Contributor Author

mkurapov commented Feb 15, 2024

@BlairCurrey --runInBand instead of --maxWorkers=2 in the CI took about 50% longer

https://github.com/interledger/rafiki/actions/runs/7919005784/job/21618820101 (6 mins)
https://github.com/interledger/rafiki/actions/runs/7788547057 (4 mins)

@sabineschaller
Copy link
Member

Are we ready to get this merged as is then?

@mkurapov
Copy link
Contributor Author

@sabineschaller going to try one final test to move some imports around to see if the "fix" from the nock issue might work for us, otherwise, I'll merge

@mkurapov
Copy link
Contributor Author

@sabineschaller yeah, the order of imports don't seem to make a difference in the repo

@BlairCurrey
Copy link
Contributor

@BlairCurrey --runInBand instead of --maxWorkers=2 in the CI took about 50% longer

https://github.com/interledger/rafiki/actions/runs/7919005784/job/21618820101 (6 mins) https://github.com/interledger/rafiki/actions/runs/7788547057 (4 mins)

Good to know, thanks for testing it out.

# Conflicts:
#	packages/backend/package.json
#	packages/backend/src/index.ts
#	packages/backend/src/tests/app.ts
#	pnpm-lock.yaml
BlairCurrey
BlairCurrey previously approved these changes Feb 26, 2024
@mkurapov mkurapov merged commit de4b0e3 into main Feb 27, 2024
22 checks passed
@mkurapov mkurapov deleted the 2393/mk/memory-leak branch February 27, 2024 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: backend Changes in the backend package. type: source Changes business logic type: tests Testing related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix memory leaks in tests Gracefully stop individual TB testcontainers
3 participants