Skip to content

Conversation

@Fernando-hub527
Copy link
Contributor

What?

This PR ensures that once thresholds are defined, they are still evaluated correctly even if check(...) is never called.

Why?

Guarantee that if an error occurs before any checks are executed, the threshold evaluation will correctly register a failure.

Checklist

  • I have performed a self-review of my code.
  • I have commented on my code, particularly in hard-to-understand areas.
  • I have added tests for my changes.
  • I have run linter and tests locally (make check) and all pass.

Checklist: Documentation (only for k6 maintainers and if relevant)

Please do not merge this PR until the following items are filled out.

  • I have added the correct milestone and labels to the PR.
  • I have updated the release notes: link
  • I have updated or added an issue to the k6-documentation: grafana/k6-docs#NUMBER if applicable
  • I have updated or added an issue to the TypeScript definitions: grafana/k6-DefinitelyTyped#NUMBER if applicable

Related PR(s)/Issue(s)

Closes #4283

Signed-off-by: Fernando-hub527 <fernandocoelhosaraivanando@gmail.com>
Signed-off-by: Fernando-hub527 <fernandocoelhosaraivanando@gmail.com>
@Fernando-hub527 Fernando-hub527 requested a review from a team as a code owner May 15, 2025 02:37
@Fernando-hub527 Fernando-hub527 requested review from ankur22 and codebien and removed request for a team May 15, 2025 02:37
@Fernando-hub527
Copy link
Contributor Author

As far as I could determine, the issue was happening because, to avoid a division by zero, the rate metric wasn’t populated when the total number of checks was zero (see code here). That means if an error occurred before any checks were executed, the threshold failure was never triggered.

Here’s an example of the threshold evaluation after the fix:

code:
Captura de tela de 2025-05-14 22-57-57

result:
Captura de tela de 2025-05-14 22-58-48

Copy link
Contributor

@ankur22 ankur22 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR @Fernando-hub527!

I took a look at the change and used the following script to test before and after the fix:

import { check } from "k6";
import http from "k6/http";

export const options = {
 stages: [
  { duration: "2s", target: 1 },
 ],
 thresholds: {
  "checks": [{threshold: "rate>0.9", abortOnFail: true}],
 },
};

export default function () {
  const res = http.get("https://test-api.k6.io/public/crocodiles");
  throw new Error('This is an error');

  check(res, {
    "status was 200": (res) => res.status === 200,
  });
}

Before the fix:

  █ THRESHOLDS 

    checks
    ✓ 'rate>0.9' rate=0.00%


  █ TOTAL RESULTS 

    checks_total.......................: 0     0/s
    checks_succeeded...................: 0.00% 0 out of 0
    checks_failed......................: NaN%  0 out of 0

After the fix:

  █ THRESHOLDS 

    checks
    ✗ 'rate>0.9' rate=0.00%


  █ TOTAL RESULTS 

    checks_total.......................: 0     0/s
    checks_succeeded...................: 0.00% 0 out of 0
    checks_failed......................: 0.00% 0 out of 0

NOTE: The results are focusing on the areas that differ between the two test runs. Other metrics are presented such as HTTP, but they look correct in both test runs.

I think with the fix is a better outcome than before, so i'm approving it.

@mstoykov mstoykov requested review from joanlopez and removed request for codebien June 11, 2025 13:22
@joanlopez
Copy link
Contributor

joanlopez commented Jun 17, 2025

Hi @Fernando-hub527,

We're discussing internally if really want to merge this new behavior for thresholds as-is, or perhaps offer another workaround to sort it out.

So, could you please split it into two different PRs, one for changing the threshold evaluation behavior and the other one to fix the NaN%? You can leave this one as-is, just extract the small bits into another one.

This way we can merge this part of your contribution and close #4842.
And later continue with the ongoing discussion around thresholds.
cc/ @mstoykov for visibility.

Thanks! 🙇🏻 🙌🏻

@Fernando-hub527
Copy link
Contributor Author

Hi @joanlopez, sorry for the delay.
Here's the PR containing only the fix for the NaN issue: #4878.
If you think it would be useful to share the discussion, I'd be happy to help.

@joanlopez joanlopez mentioned this pull request Jul 10, 2025
8 tasks
@joanlopez
Copy link
Contributor

Hey @Fernando-hub527,

I'm going to close this pull request because after some internal discussions, I even stronger believe we won't want to change this behavior on thresholds, as it would introduce a breaking change, and it's unlikely that's always going to be the desired behavior by users, while it won't be configurable.

So, we'll likely agree on another workaround, like "exposing" the "total" value for Rate metrics, letting users to define another threshold that ensures "total > 0"; or adding a new option, like abortOnFail, but specifically for the case where there's no data at all, like failWhenNoData.

Anyway, thanks for the other half of the PR that you split and that has already been merged, as that was really a small bug to be fixed. Really appreciated! 🙌🏻

@joanlopez joanlopez closed this Jul 31, 2025
@joanlopez joanlopez added the breaking change for PRs that need to be mentioned in the breaking changes section of the release notes label Jul 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change for PRs that need to be mentioned in the breaking changes section of the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Thresholds evaluated incorrectly

3 participants