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

feat: Add n8n-benchmark cli (no-changelog) #10410

Merged
merged 19 commits into from
Aug 22, 2024
Merged

feat: Add n8n-benchmark cli (no-changelog) #10410

merged 19 commits into from
Aug 22, 2024

Conversation

tomi
Copy link
Contributor

@tomi tomi commented Aug 14, 2024

Summary

Adds a new cli tool for executing benchmark tests against any n8n instance. The tool consists of following parts:

  • Test scenarios
    • Consists of test data (workflow(s)) and k6 script to run the benchmark
    • In the testScenarios folder
  • n8n-benchmark cli
    • In the src folder
    • Based on oclif
    • Two commands:
      • list : lists all available test scenarios
      • run : runs all available test scenarios (or specified ones in the future)

Test scenario execution works as follows:

  • Setup: setup owner if needed, login
  • For each test scenario:
    • Import the specified test data using n8n internal API
    • Run the benchmark and print out results

This is the first step in creating an automated benchmark test setup. Next step is to
add the test environment setup and orchestration to run the benchmarks there.
The feasibility of the approach has been validated in CAT-26
See the linear project for more details

Example outputs:

List:

➜ ./bin/n8n-benchmark list
Available test scenarios:

         CodeNode : Workflow with a single code node that is triggered using a webhook
         SingleWebhook : A single webhook trigger that responds with a 200 status code

Run:

./bin/n8n-benchmark run
Waiting for n8n http://localhost:5678 to become online
Setting up owner
Owner already set up
Running scenario: CodeNode
Loading and importing test data
Executing test script

     ✓ is status 200

     checks.........................: 100.00% ✓ 9381       ✗ 0   
     data_received..................: 4.4 MB  73 kB/s
     data_sent......................: 910 kB  15 kB/s
     http_req_blocked...............: avg=4.12µs  min=0s     med=3µs     max=1.38ms   p(90)=5µs     p(95)=6µs    
     http_req_connecting............: avg=133ns   min=0s     med=0s      max=467µs    p(90)=0s      p(95)=0s     
     http_req_duration..............: avg=15.84ms min=5.05ms med=15.12ms max=170.48ms p(90)=24.74ms p(95)=27.99ms
       { expected_response:true }...: avg=15.84ms min=5.05ms med=15.12ms max=170.48ms p(90)=24.74ms p(95)=27.99ms
     http_req_failed................: 0.00%   ✓ 0          ✗ 9381
     http_req_receiving.............: avg=67.92µs min=7µs    med=49µs    max=11.34ms  p(90)=98µs    p(95)=125µs  
     http_req_sending...............: avg=17.49µs min=2µs    med=14µs    max=3.61ms   p(90)=26µs    p(95)=31µs   
     http_req_tls_handshaking.......: avg=0s      min=0s     med=0s      max=0s       p(90)=0s      p(95)=0s     
     http_req_waiting...............: avg=15.75ms min=4.96ms med=15.04ms max=170.43ms p(90)=24.65ms p(95)=27.89ms
     http_reqs......................: 9381    156.290412/s
     iteration_duration.............: avg=15.98ms min=5.2ms  med=15.23ms max=170.59ms p(90)=24.9ms  p(95)=28.2ms 
     iterations.....................: 9381    156.290412/s
     vus............................: 4       min=1        max=4 
     vus_max........................: 5       min=5        max=5 


Running scenario: SingleWebhook
Loading and importing test data
Executing test script

     ✓ is status 200

     checks.........................: 100.00% ✓ 15725      ✗ 0    
     data_received..................: 4.2 MB  71 kB/s
     data_sent......................: 1.6 MB  27 kB/s
     http_req_blocked...............: avg=5.29µs  min=0s     med=3µs    max=4.83ms   p(90)=5µs     p(95)=6µs    
     http_req_connecting............: avg=75ns    min=0s     med=0s     max=410µs    p(90)=0s      p(95)=0s     
     http_req_duration..............: avg=9.36ms  min=1.45ms med=9.21ms max=164.77ms p(90)=14.56ms p(95)=15.53ms
       { expected_response:true }...: avg=9.36ms  min=1.45ms med=9.21ms max=164.77ms p(90)=14.56ms p(95)=15.53ms
     http_req_failed................: 0.00%   ✓ 0          ✗ 15725
     http_req_receiving.............: avg=67.73µs min=7µs    med=52µs   max=4.43ms   p(90)=95µs    p(95)=129µs  
     http_req_sending...............: avg=19.92µs min=1µs    med=15µs   max=5.73ms   p(90)=25µs    p(95)=31µs   
     http_req_tls_handshaking.......: avg=0s      min=0s     med=0s     max=0s       p(90)=0s      p(95)=0s     
     http_req_waiting...............: avg=9.27ms  min=1.38ms med=9.12ms max=164.68ms p(90)=14.48ms p(95)=15.45ms
     http_reqs......................: 15725   262.022199/s
     iteration_duration.............: avg=9.52ms  min=1.55ms med=9.38ms max=164.85ms p(90)=14.68ms p(95)=15.66ms
     iterations.....................: 15725   262.022199/s
     vus............................: 4       min=1        max=4  
     vus_max........................: 5       min=5        max=5  


Related Linear tickets, Github issues, and Community forum posts

CAT-25

Review / Merge checklist

  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.
  • PR Labeled with release/backport (if the PR is an urgent fix that needs to be backported)

Adds a new cli tool for executing benchmark tests against any n8n instance. The
idea is to treat n8n as a black box and use webhook triggers to initiate workflow
executions.

The tool consists of following parts:
- Test scenarios
  - Consists of test data (workflow(s)) and k6 script to run the benchmark
  - In the `testScenarios` folder
- n8n-benchmark cli
  - In the `src` folder
  - Based on oclif
  - Two commands:
    - list : lists all available test scenarios
    - run : runs all available test scenarios (or specified ones in the future)

Test scenario execution works as follows:
- Setup: setup owner if needed, login
- For each test scenario:
  - Import the specified test data using n8n internal API
  - Run the benchmark and print out results

This is the first step in creating an automated benchmark test setup. Next step is to
add the test environment setup and orchestration to run the benchmarks there.
The feasibility of the approach has been validated in [CAT-26](https://linear.app/n8n/issue/CAT-26/spike-select-infra-to-run-the-benchmarks)
See the [linear project](https://linear.app/n8n/project/n8n-benchmarking-suite-3e7679d176b4/overview) for more details
@tomi tomi force-pushed the benchmark-suite-spike branch from 2af83e3 to cdb9308 Compare August 14, 2024 14:16
@tomi tomi changed the title feat: Add n8n-benchmark cli feat: Add n8n-benchmark cli (CAT-25) (no-changelog) Aug 14, 2024
@n8n-assistant n8n-assistant bot added the n8n team Authored by the n8n team label Aug 14, 2024
tomi added a commit that referenced this pull request Aug 15, 2024
tomi added a commit that referenced this pull request Aug 15, 2024
@ivov ivov self-requested a review August 19, 2024 08:58
packages/benchmark/Dockerfile Outdated Show resolved Hide resolved
packages/benchmark/Dockerfile Outdated Show resolved Hide resolved
packages/benchmark/Dockerfile Outdated Show resolved Hide resolved
packages/benchmark/README.md Outdated Show resolved Hide resolved
packages/benchmark/README.md Outdated Show resolved Hide resolved
packages/benchmark/src/n8nApiClient/n8nApiClient.ts Outdated Show resolved Hide resolved
packages/benchmark/src/n8nApiClient/n8nApiClient.types.ts Outdated Show resolved Hide resolved
packages/benchmark/src/n8nApiClient/workflowsApiClient.ts Outdated Show resolved Hide resolved
packages/benchmark/tsconfig.json Outdated Show resolved Hide resolved
@ivov
Copy link
Contributor

ivov commented Aug 20, 2024

Forgot to mention, the PR title shouldn't contain ticket ID. This is validated by the PR title GH action but needs updating so it wasn't caught.

packages/benchmark/package.json Outdated Show resolved Hide resolved
"main": "dist/index",
"scripts": {
"build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
"start": "./bin/n8n-benchmark",
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we adding prettier and the .vscode folder to make sure prettier is used to format and to format on save by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I follow. Do we have some prettier config in .vscode? We have the .prettierrc.js in the repo root, which AFAIK should apply to all packages?

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant the formatter configuration in vscode as in here -> https://github.com/n8n-io/ai-assistant-service/blob/main/.vscode/settings.json

Copy link
Contributor Author

@tomi tomi Aug 22, 2024

Choose a reason for hiding this comment

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

Think we have those already. I think it's a better pattern to provide "default" settings for the repository, but allow devs to customize them however they want. Should probably do it the same way in the AI Assistant service

@tomi
Copy link
Contributor Author

tomi commented Aug 20, 2024

@ivov Thank you for a great review 🙏 Addressed the issues you raised. LMK if I missed something

@tomi tomi changed the title feat: Add n8n-benchmark cli (CAT-25) (no-changelog) feat: Add n8n-benchmark cli (no-changelog) Aug 20, 2024
@tomi
Copy link
Contributor Author

tomi commented Aug 20, 2024

Can we use the new watch flag that comes with node out of the box?

@RicardoE105 the nodemon was actually a leftover which is not needed anymore. tsc and tsc-alias both provide watch out of the box

@tomi tomi requested review from ivov and RicardoE105 August 20, 2024 18:21
Copy link
Contributor

@ivov ivov left a comment

Choose a reason for hiding this comment

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

Nice work! Final thoughts, no blockers, so approving.

  • When the path to the k6 executable is not found, it'd be nice to fall back to /opt/homebrew/bin/k6. Most of the team is on mac and will be using homebrew when running the cli locally.
  • Now that we have the @n8n/config package I tend to think all monorepo config should go in there, even if as in this case it's a CLI tool rather than the app itself, but that's only my opinion. The purpose of @n8n/config is to have full type safety, better inline docs for DX, and to allow us to build tooling for all env vars for the docs team.
  • In future I'd love to see some documentation on (1) best practices to create a benchmark scenario, and (2) how best to make sense of the results reported.
K6_PATH=/opt/homebrew/bin/k6 [email protected] N8N_USER_PASSWORD=test1234A ./bin/n8n-benchmark run
Waiting for n8n http://localhost:5678 to become online
Setting up owner
Owner already set up
Running scenario: SingleWebhook
Loading and importing data
Executing scenario script

     ✓ is status 200

     checks.........................: 100.00% ✓ 9161       ✗ 0
     data_received..................: 2.5 MB  41 kB/s
     data_sent......................: 934 kB  16 kB/s
     http_req_blocked...............: avg=1.63µs  min=0s     med=1µs     max=452µs    p(90)=2µs     p(95)=3µs
     http_req_connecting............: avg=82ns    min=0s     med=0s      max=208µs    p(90)=0s      p(95)=0s
     http_req_duration..............: avg=16.31ms min=4.66ms med=15.17ms max=332.68ms p(90)=23.01ms p(95)=26.76ms
       { expected_response:true }...: avg=16.31ms min=4.66ms med=15.17ms max=332.68ms p(90)=23.01ms p(95)=26.76ms
     http_req_failed................: 0.00%   ✓ 0          ✗ 9161
     http_req_receiving.............: avg=26.8µs  min=7µs    med=27µs    max=244µs    p(90)=41µs    p(95)=48µs
     http_req_sending...............: avg=6.99µs  min=1µs    med=7µs     max=230µs    p(90)=11µs    p(95)=12µs
     http_req_tls_handshaking.......: avg=0s      min=0s     med=0s      max=0s       p(90)=0s      p(95)=0s
     http_req_waiting...............: avg=16.27ms min=4.62ms med=15.15ms max=332.62ms p(90)=22.98ms p(95)=26.72ms
     http_reqs......................: 9161    152.648771/s
     iteration_duration.............: avg=16.37ms min=4.73ms med=15.22ms max=332.81ms p(90)=23.04ms p(95)=26.82ms
     iterations.....................: 9161    152.648771/s
     vus............................: 4       min=1        max=4
     vus_max........................: 5       min=5        max=5

Copy link

cypress bot commented Aug 22, 2024



Test summary

414 0 0 0Flakiness 0


Run details

Project n8n
Status Passed
Commit 3823de6
Started Aug 22, 2024 8:03 AM
Ended Aug 22, 2024 8:08 AM
Duration 04:46 💡
OS Linux Debian -
Browser Electron 118

View run in Cypress Cloud ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Cloud

Copy link
Contributor

✅ All Cypress E2E specs passed

@tomi tomi merged commit ea6ca04 into master Aug 22, 2024
33 checks passed
@tomi tomi deleted the benchmark-suite-spike branch August 22, 2024 08:33
@tomi
Copy link
Contributor Author

tomi commented Aug 22, 2024

@ivov thank you for the review 🙏 I'll address the comments in follow-up PRs

MiloradFilipovic added a commit that referenced this pull request Aug 22, 2024
* master:
  ci: Fix benchmark cli path (no-changelog) (#10506)
  refactor(core): Standardize filenames in `cli` (no-changelog) (#10484)
  fix(AI Agent Node): Allow AWS Bedrock Chat to be used with conversational agent (#10489)
  feat(AI Agent Node): Add tutorial link to agent node (#10493)
  feat: Add n8n-benchmark cli (no-changelog) (#10410)
  feat(core): Logout should invalidate the auth token (no-changelog) (#10335)
  refactor(editor): Add types to importCurlEventBus (no-changelog) (#10497)
  refactor(editor): Add types to htmlEditorEventBus (no-changelog) (#10498)
  refactor(editor): Add types for dataPinningEventBus (no-changelog) (#10499)
  refactor(editor): Add types to codeNodeEditorEventBus (no-changelog) (#10501)
@janober
Copy link
Member

janober commented Aug 28, 2024

Got released with [email protected]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
n8n team Authored by the n8n team Released
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants