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(tests): initial performance test #2828

Merged
merged 14 commits into from
Aug 20, 2024
Merged

feat(tests): initial performance test #2828

merged 14 commits into from
Aug 20, 2024

Conversation

njlie
Copy link
Contributor

@njlie njlie commented Jul 30, 2024

Changes proposed in this pull request

  • Adds a script that can be run against the local environment.
    • Script may be run inside a Docker container as well.
  • Basic shell script to verify that the local playground is live before running the script.

Context

Fixes #2810.

The performance test script exercises the createReceiver, createQuote, and createOutgoingPayment GraphQL endpoints.

Checklist

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

@github-actions github-actions bot added the type: tests Testing related label Jul 30, 2024
Copy link

netlify bot commented Jul 30, 2024

Deploy Preview for brilliant-pasca-3e80ec canceled.

Name Link
🔨 Latest commit ce5da86
🔍 Latest deploy log https://app.netlify.com/sites/brilliant-pasca-3e80ec/deploys/66c36890114453000818364d

@njlie njlie force-pushed the nl/2810/initial-load-test-2 branch from a835667 to 89e7e19 Compare August 1, 2024 21:06
@njlie njlie marked this pull request as ready for review August 1, 2024 22:53
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like this is unused... Remove?

Both pnpm --filter performance run-tests and pnpm --filter performance run-tests-docker use run-test.sh

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks. Meant to remove it

headers
}
)
const receiver = JSON.parse(createReceiverResponse.body).data.createReceiver
Copy link
Contributor

Choose a reason for hiding this comment

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

Im seeing some errors like this when spinning up the localenv and running pnpm --filter performance run-tests-docker:

time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createReceiver' of undefined\n\tat file:///scripts/create-outgoing-payments.js:125:64(84)\n" executor=constant-vus scenario=default source=stacktrace
time="2024-08-05T18:40:26Z" level=error msg="TypeError: Cannot read property 'createQuote' of undefined\n\tat file:///scripts/create-outgoing-payments.js:159:58(128)\n" executor=constant-vus scenario=default source=stacktrace

9 TypeErrors for createReceiver and then 1 createQuote. Looks like its indicating data in JSON.parse(createReceiverResponse.body).data is undefined.

Im not sure what to make of it though because then the VUs seem to run fine. I see some quote times in http://localhost:4500/ but not sure there is enough info there to make much sense of the errors.

If I run pnpm --filter performance run-tests-docker again without restarting the localenv I dont see these TypeErrors.

As a side note, I was surprised to see no outgoing payment based metrics but this is actually consistent with the bruno peer-to-peer example (guess it happens outside of the outgoing payment lifecycle where these are recorded).

Copy link
Contributor

Choose a reason for hiding this comment

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

view of dashboard after running:

image

Copy link
Contributor Author

@njlie njlie Aug 5, 2024

Choose a reason for hiding this comment

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

I think these errors are performance issues being exposed by the test. It seems to work more consistently after bringing the number of virtual users down to one, so I suspect that these are symptoms of the service being overwhelmed.

Copy link
Contributor

Choose a reason for hiding this comment

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

makes sense... I actually dont see it anymore

// A number specifying the number of VUs to run concurrently.
vus: 10,
// A string specifying the total duration of the test run.
duration: '30s'
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we bump this up? Im seeing this:

time="2024-08-05T18:51:25Z" level=warning msg="No script iterations fully finished, consider making the test duration longer"

Copy link
Contributor Author

@njlie njlie Aug 5, 2024

Choose a reason for hiding this comment

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

Looks like I need to bump it up to match the issue description anyways:

For now, we can set the scenario to be quite small, a single virtual user (VU) across 10 minutes. We should be able to see the local playground Grafana dashboard properly populate with metrics (and traces).

fi

# Verify that cloud nine wallet address is live
if curl -s --head --request GET "$c9_wallet_address" | grep "HTTP/1.[01]" > /dev/null; then
Copy link
Contributor

@BlairCurrey BlairCurrey Aug 6, 2024

Choose a reason for hiding this comment

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

So this is kinda funny....

The outgoing payment metrics should show after all. I was wrong here and the peer-to-peer bruno tests DO populate the outgoing payment based metrics (I was just impatient - underestimated the delay). So the performance tests should populate them too.

You can confirm this beyond the metrics if you do docker logs rafiki-cloud-nine-mock-ase-1 after running the tests and you should see many of these:

Error: No account found for wallet address
    at handleOutgoingPaymentCreated (/home/rafiki/localenv/mock-account-servicing-entity/build/index.js:2200:11)
    ...

This is showing the mock ase cant find the wallet address in the handle outgoing payment create webhook handler and then it doesnt deposit liquidity and the payment doesnt get funded. I looked into the DB and saw that we had 2 Grace Franklin wallet addresses. https://cloud-nine-wallet-backend/accounts/gfranklin and https://localhost:3000/accounts/gfranklin. Looks like the localhost:3000 one is getting created by the mock ase's wallet address not found handler when we ping here. In other words, you can change gfranklin to anything in c9_wallet_address and it works because it gets created if it doesnt exit. Then when the mock ASE looks up the wallet address, it expects this new one while the one specified in the performance test script is the original so it never gets funded.

Perhaps we can ping something else? Or nothing? http://cloud-nine-wallet-backend:3000/accounts/gfranklin connects but creates a new record as well, and we cant reach by https://cloud-nine-wallet-backend/accounts/gfranklin. Originally I noticed I could change the script to do const CLOUD_NINE_WALLET_ADDRESS = 'https://localhost:3000/accounts/gfranklin' but this is just kinda hacking around the unintended wallet address creation.

Copy link
Contributor

Choose a reason for hiding this comment

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

metrics showing in the dashboard setting constCLOUD_NINE_WALLET_ADDRESS = 'https://localhost:3000/accounts/gfranklin' in the script

image

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 investigated this a little bit and I think it's a separate issue from there being different wallet addresses with the same name. I think when the webhook is generated it is populated with the database id of the wallet address, but the mock ASE passes that id into an instance of account-provider from mock-account-service-lib, which is seeded with different ids from what gets set in the database.

I get this same issue with the webhook handler not finding the wallet address coming up when I perform the Bruno peer-to-peer example, not sure how it got through when you tried it...

BlairCurrey
BlairCurrey previously approved these changes Aug 7, 2024
koekiebox
koekiebox previously approved these changes Aug 7, 2024
Copy link
Collaborator

@koekiebox koekiebox left a comment

Choose a reason for hiding this comment

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

LGtM 🚀


- [Running local playground for Rafiki](../../localenv/README.md)

If the local environment isn't running it may be started
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you meant to finish this sentence. We should also mention how to start it with telemetry enabled

Comment on lines +84 to +87
const c9WalletAddresses = JSON.parse(c9WalletAddressesRes.body).data
.walletAddresses.edges
const c9WalletAddress = c9WalletAddresses.find(
(edge) => edge.node.url === CLOUD_NINE_WALLET_ADDRESS
).node
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we could move this into the setup function of the script, such that we don't need to fetch them every iteration. We should give a good error if the request to find the specific wallet address fails

@njlie njlie force-pushed the nl/2810/initial-load-test-2 branch from f914afd to 14ea6e5 Compare August 13, 2024 14:18
BlairCurrey
BlairCurrey previously approved these changes Aug 13, 2024
mkurapov
mkurapov previously approved these changes Aug 19, 2024
Comment on lines 9 to 47
// The following section contains configuration options for execution of this
// test script in Grafana Cloud.
//
// See https://grafana.com/docs/grafana-cloud/k6/get-started/run-cloud-tests-from-the-cli/
// to learn about authoring and running k6 test scripts in Grafana k6 Cloud.
//
// cloud: {
// // The ID of the project to which the test is assigned in the k6 Cloud UI.
// // By default tests are executed in default project.
// projectID: "",
// // The name of the test in the k6 Cloud UI.
// // Test runs with the same name will be grouped.
// name: "script.js"
// },

// Uncomment this section to enable the use of Browser API in your tests.
//
// See https://grafana.com/docs/k6/latest/using-k6-browser/running-browser-tests/ to learn more
// about using Browser API in your test scripts.
//
// scenarios: {
// // The scenario name appears in the result summary, tags, and so on.
// // You can give the scenario any name, as long as each name in the script is unique.
// ui: {
// // Executor is a mandatory parameter for browser-based tests.
// // Shared iterations in this case tells k6 to reuse VUs to execute iterations.
// //
// // See https://grafana.com/docs/k6/latest/using-k6/scenarios/executors/ for other executor types.
// executor: 'shared-iterations',
// options: {
// browser: {
// // This is a mandatory parameter that instructs k6 to launch and
// // connect to a chromium-based browser, and use it to run UI-based
// // tests.
// type: 'chromium',
// },
// },
// },
// }
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can remove this comment, if more scenarios are needed we can access the docs then

Comment on lines 187 to 190
metadata: {
description: null,
externalRef: null
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
metadata: {
description: null,
externalRef: null
},

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There doesn't seem to be a change here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I was just commenting we can remove metadata if it doesn't contain any info

The test can also be run inside of a Docker container on the same Docker network as the Local Playground:

```
pnpm --filter performance run-tests-docker
Copy link
Contributor

Choose a reason for hiding this comment

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

this script is useful such that we don't need to set the host names?

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 took this from the description of the issue:

Since the local playground is within docker, we will need to run this script in docker as well, e.g.
docker run --rm -i grafana/k6 run - script.js

(Though not setting the host names is a benefit).

Copy link
Contributor

@mkurapov mkurapov left a comment

Choose a reason for hiding this comment

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

🚀

@njlie njlie requested a review from mkurapov August 20, 2024 07:54
@njlie njlie merged commit 5496612 into main Aug 20, 2024
42 checks passed
@njlie njlie deleted the nl/2810/initial-load-test-2 branch August 20, 2024 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: tests Testing related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add K6 script for initial load test
4 participants