Can I use a separate function to perform a check?

Hoping you could help me with what I sure is a glaring oversight on my part:

Since the beginning, I have been using a separate function to perform a check on the response objest and do some logging for every step in my script. However, I have been refactoring the error handling, and now I’m having some trouble getting my function call to complete.

For example, I force a check to fail:

export default function ssoLogin() {

  var tenant = `${__ENV.TENANT}`;
  var stepNum;
  var vuserID = `${__VU}`;
  var iterNum = `${__ITER}`;

  var response = http.get(`http://` + tenant, {
    tags: { name: stepNum + ' - http://' + tenant },
  });
  checkStatus(response, vuserID, iterNum, 303);

and then pass the response object over to this function:

function checkStatus(response, vuserID, iterNum, httpCode) {
  passed = check(response, {
    "Status: OK": (response) => response.status === httpCode,
  })

 if (!passed) {
fail(" - - - Checks failed: " + response.url + " - - - Expected: " + httpCode + " - - - Received: " + response.status + ` (VUSER ` + vuserID + `, ITER: ` + iterNum + `) ` + response.body);
errorCount.add(1, { url: response.request.name });

}

But the script fails with a very goofy error right on the line where I set passed.

INFO[0001] VU: 003  ITER: 001  * * * * * START * * * * *   source=console
E
<
<
<
<
<
<

        at github.com/loadimpact/k6/js/common.Bind.func1 (native)
        at checkStatus (file:///C:/Users/james/Github/performance-k6/SSO/sso-new-flow-k6.js:100:211(47))
        at ssoLogin (file:///C:/Users/james/Github/performance-k6/SSO/sso-new-flow-k6.js:144:14(180))  executor=ramping-vus scenario=default source=stacktrace

FWIW: I used to fail the step a different way - using an example from your original documentation, which led to this ticket: Fail function does not pass validation in web scripting interface

check(res, {
    "status code MUST be 200": (res) => res.status == 200,
  }) || fail("status code was *not* 200");

Hello,

I can’t explain the weird output if it is happening during check (can’t see anything wrong with it though - are you sure the line numbers match up?).

I’d be more inclined to suspect the culprit being the fail statement, specifically the use of response.body in the message being logged. That could potentially be a very long string with lots of newlines in it, which could explain why you’d get weird output when printing it.

Incidentally, I was just investigating what a generic checkStatus function might look like, and this is where I got to with that:

import http from 'k6/http';
import { check, fail } from 'k6';

export default function () {
  let res = http.get("https://httpbin.test.k6.io/html");
  checkStatus(res, 200, true, true);

  // this will fail:
  res = http.get("https://httpbin.test.k6.io/status/500");
  checkStatus(res, 200, true, true);
}

function checkStatus(res, expectedStatus, failOnError, printOnError) {
  const obj = {};
  obj[`HTTP status ${expectedStatus}`] = (r) => r.status === expectedStatus;

  const checkResult = check(res, obj);
  if (!checkResult) {
    if (printOnError) {
      console.log("Response: " + res.body);
    }
    if (failOnError) {
      fail(`Received unexpected status code ${res.status} for URL: ${res.url}, expected ${expectedStatus}`)
    }
  }
}

The only downside is that the response is logged before the associated fail call (it needs to be logged before the call to fail as the latter restarts the iteration).

Oh, you’re right. I was using a really bad request to test throwing the body. I think it is working fine. Thanks again!

This is a relevant issue

1 Like