Skip to content

Conversation

@BobdenOs
Copy link
Contributor

This PR adds a new perf property to the cds.test API. Which is a wrapper around the commonly used autocannon node module. Which allows developers to measure the performance of their endpoints. To make the API as simple to use as possible the APIs have axios integration. Which means that by default the same base url is used by perf as it currently used by axios.

Additionally perf introduces the fn API. Which accepts a callback function which will be measured in a similar way as all the autocannon APIs are. Providing flexibility for not just measuring http request performance, but also for measuring the performance of any javascript function. For the use cases where multiple requests have to be chained together the fn callback can be async and the promise will be awaited and the connections configuration of autocannon will apply so that if there async function detaches from the event loop. It will trigger multiple parallel calls to the callback function.

const { POST, DELETE, perf: {GET, report, fn} } = cds.test()

it('GET', async () => {
  report(await GET`/browse/Books`)
})

it('complex', async () => report(await fn(async () => {
  const book = await POST('/admin/Books', {})
  await DELETE`/admin/Books(${book.ID})`
}))

it('compute', async () => report(await fn(() => {
  cds.db.cqn2sql(cds.ql`SELECT * FROM Books`)
})))

const ret = fn()
if (ret?.then) await ret;

const d = process.hrtime.bigint() - s
Copy link
Member

Choose a reason for hiding this comment

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

just out of curiosity, whats the advantage of this over:

const time = process.hrtime() // nano precision

const diff = process.hrtime(time)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is more precise then performance.now and I got this from the node repository benchmark code.

Copy link
Member

Choose a reason for hiding this comment

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

I know hrtime is more precise, I was just wondering why we need the bigint() API here. Also the diff calculation can be done by the function itself (but it yields a [seconds, nanoseconds] tuple).

Smt like this:

- const d = process.hrtime.bigint() - s
+ const d = process.hrtime(s)

patricebender added a commit to cap-js/cds-dbs that referenced this pull request Aug 27, 2025
based on cap-js/cds-test#20 (and some local tweaks)

preferred over #1329
@BobdenOs BobdenOs marked this pull request as ready for review August 28, 2025 10:49
@patricebender
Copy link
Member

Hi @chgeo / @danjoa I tried this out in a small benchmarking suite for cqn4sql. Does anything speak against merging this?

@mauriciolauffer
Copy link
Contributor

mauriciolauffer commented Oct 2, 2025

What's the value in embedding autocannon or any other benchmark/performance tool into cds-test? What about customers using other tools like k6, vegeta, artillery, jmeter, etc? Using any of these tools is easy, the effort is minimum...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants