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

Speed up loop.spec.ts #15674

Merged
merged 14 commits into from
Mar 5, 2025
Merged

Speed up loop.spec.ts #15674

merged 14 commits into from
Mar 5, 2025

Conversation

samwho
Copy link
Collaborator

@samwho samwho commented Mar 4, 2025

Description

This should solve the timeouts we've been seeing with loop.spec.ts recently. I've left comments inline explaining, it was quite a journey to debug.

CleanShot 2025-03-04 at 18 04 13@2x

Copy link

qa-wolf bot commented Mar 4, 2025

QA Wolf here! As you write new code it's important that your test coverage is keeping up.
Click here to request test coverage for this PR!

@github-actions github-actions bot added firestorm Data/Infra/Revenue Team size/l labels Mar 4, 2025
@samwho samwho changed the title Speed up server tests. Speed up loop.spec.ts Mar 4, 2025
Comment on lines +91 to +100

[httpd]
socket_options = [{nodelay, true}]

[couchdb]
single_node = true

[cluster]
n = 1
q = 1
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I went through https://docs.couchdb.org/en/stable/maintenance/performance.html and enabled a few things. I don't think it had much of a performance impact, but it did get rid of some errors in the logs so I'm going to leave it in.

@@ -290,8 +290,7 @@ describe("/automations", () => {
await setup.delay(500)
let elements = await getAllTableRows(config)
// don't test it unless there are values to test
if (elements.length > 1) {
expect(elements.length).toBeGreaterThanOrEqual(MAX_RETRIES)
if (elements.length >= 1) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was previously relying on the automation created in this test chaining with itself. Under normal circumstances, only 1 row should be created.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The quota stuff in this file, and a few others, is leftover from my attempt to speed up tests by disabling quota checking everywhere except tests that relied on it. I've gotten rid of it now but liked these changes, so kept them.

@@ -20,9 +20,12 @@ export interface TriggerOutput {

export interface AutomationContext {
trigger: AutomationTriggerResultOutputs
steps: [AutomationTriggerResultOutputs, ...AutomationStepResultOutputs[]]
stepsById: Record<string, AutomationStepResultOutputs>
steps: Record<
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Previously we would track context in this shape and before each time we used it, we'd call a function called prepareContext that slightly transformed it. This ended up being quite expensive, so I made it such that the transformation is no longer needed.

Comment on lines +37 to +38
_stepIndex: number
_error: boolean
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

_stepIndex tracks what numerical index to use next for step output (e.g. for {{ steps.0.output }}), and _error tracks whether a step has failed. This removes the need for us to loop over all of the output to check.

Comment on lines +35 to +36
} else if (env.isTest()) {
return 0
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was the key to solving the reason loop.spec.ts has been timing out. We had lots of automations that triggered themselves, which was causing havoc in the background while other tests were running. This prevents that, unless chaining is explicitly enabled in the app metadata.

@@ -23,6 +23,6 @@ nock.enableNetConnect(host => {

testContainerUtils.setupEnv(env, coreEnv)

afterAll(() => {
afterAll(async () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Leftover from attempt to disable quota during tests, left in by accident. Can change it back if you want but I don't think it causes any harm.

try {
return await req
resp = await req
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Did this to make debugging easier.

const job = cloneDeep(this.job)
delete job.data.event.appId
delete job.data.event.metadata
const data = cloneDeep(this.job.data)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was another big part of why automation tests became slow. this.job contains a reference to InMemoryQueue, which in turn has a reference to _messages which contains all automation queue messages fired during tests. Cloning it in full was expensive.

@samwho samwho marked this pull request as ready for review March 4, 2025 18:00
@samwho samwho requested a review from a team as a code owner March 4, 2025 18:00
@samwho samwho requested review from mike12345567 and removed request for a team March 4, 2025 18:00
@samwho samwho enabled auto-merge March 5, 2025 10:50
Copy link
Collaborator

@adrinr adrinr left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for the detailed comments!

@@ -165,6 +162,9 @@ export class InMemoryQueue<T = any> implements Partial<Queue<T>> {
opts,
}
this._messages.push(message)
if (this._messages.length > 1000) {
this._messages.shift()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this have a side effect? Could we not remove it when processed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Unfortunately I don't think we can remove it when the job finishes, because cron jobs will need to be triggered multiple times.

It may have a side effect, but I tried to think of a sufficiently large number so as to prevent side effects.

@samwho samwho merged commit eaa6997 into master Mar 5, 2025
21 checks passed
@samwho samwho deleted the test-speedup branch March 5, 2025 14:27
@github-actions github-actions bot locked and limited conversation to collaborators Mar 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
firestorm Data/Infra/Revenue Team size/l
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants