Questions around http request

Hi mstoykov,
I try to do load testing with k6, but I meet below issues I want to confirm with you, I am not sure it is whether is bug or design, could you help me to answer it? thanks.
I write two request, one is get request and another one is post request, as below code,
Script output displays “http_req_failed” is 25 % failed rate,

My question1 : I just has one VUS and two api request, and why it is actually has 4 http_reqs, and has 25% failed rate. Note: script run successfully.

question 2: Will the K6 code default to multiple attempts until the request succeeds when the request fails?

question 3: Why is it that there are actually four requests when two requests are written in the code? My virtual user is 1.

import http from "k6/http";
import { check, sleep, fail } from "k6";
import { Rate, Trend, Counter } from "k6/metrics";

let username = "username";
username = encodeURIComponent(username);
let password = "password";
password = encodeURIComponent(password);
const credentials = `${username}:${password}`;
let response;

export default function () {
  response = http.get(
    `hide here`,
    {
      auth: "ntlm",
    }
  );

  check(response, {
    "0. check the get site api was 200": (res) => res.status == 200,
  });

  if (response.status != 200) {
    console.log("error: message: sites get response not 200" + response.status);
  }

  response = http.post(
    `url-> because of security, so I hide here',
    {
      headers: {
        accept: "application/json, text/plain, */*",
        "content-type": "application/json",
        "sec-ch-ua":
          '" Not A;Brand";v="99", "Chromium";v="102", "Microsoft Edge";v="102"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
        auth: "ntlm",
      },
    }
  );
  //  sleep(2.9);
  check(response, {
    "1. check the post issues api was 200": (res) => res.status == 200,
  });
  //console.log(response.body + response.status);

  if (response.status != 200) {
    console.log("post issues api not 200" + response.status);
  }
}

console output:

PS C:\k6-code> k6 run --out influxdb=http://localhost:8086/myk6db "C:\k6-code\k6\dashboard_issues.js"

          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: C:\k6-code\k6\dashboard_issues.js
     output: InfluxDBv1 (http://localhost:8086)

  scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
           * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)


running (00m00.3s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m00.3s/10m0s  1/1 iters, 1 per VU



     **✓ 0. check the get site api was 200**
**     ✓ 1. check the post issues api was 200**

     checks.........................: 100.00% ✓ 2         ✗ 0
     data_received..................: 6.6 kB  23 kB/s
     data_sent......................: 2.0 kB  6.9 kB/s
     http_req_blocked...............: avg=24.62ms  min=0s       med=0s       max=98.51ms  p(90)=68.96ms  p(95)=83.73ms
     http_req_connecting............: avg=249.67µs min=0s       med=0s       max=998.7µs  p(90)=699.09µs p(95)=848.89µs
     http_req_duration..............: avg=46.76ms  min=999.9µs  med=20.5ms   max=145.03ms p(90)=113.52ms p(95)=129.28ms
       { expected_response:true }...: avg=62.01ms  min=1ms      med=40ms     max=145.03ms p(90)=124.03ms p(95)=134.53ms
     http_req_failed................: 25.00%  ✓ 1         ✗ 3
     http_req_receiving.............: avg=250.12µs min=0s       med=0s       max=1ms      p(90)=700.35µs p(95)=850.42µs
     http_req_sending...............: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s
     http_req_tls_handshaking.......: avg=23.87ms  min=0s       med=0s       max=95.51ms  p(90)=66.86ms  p(95)=81.18ms
     http_req_waiting...............: avg=46.51ms  min=999.9µs  med=20ms     max=145.03ms p(90)=113.22ms p(95)=129.13ms
     http_reqs......................: 4       13.958965/s
     iteration_duration.............: avg=285.55ms min=285.55ms med=285.55ms max=285.55ms p(90)=285.55ms p(95)=285.55ms
     iterations.....................: 1       3.489741/s

Regards
Lambda

Hi @lambda999, I move this to it’s own topic.

http_req_failed is a rate there are 1 true and 3 false, so actually there is 1 failed request and the others are none failed - see this issue for more info.

answer 1: ntlm is special - k6 will first just try to make the requests. We in practice have no way to know whether it was authenticated or not as this is on the tcp connection level(AFAIK). This on first requests will return a 401. Then k6 needs to actually make a request to start the negotiation, which again gets a 401. It then makes a third request with the correct header in order to finish the challenge and get the original response we wanted. This for the record isn’t really our choice - this is what the library under the azure organization does - so likely written by Microsoft employees. So I don’t really see a way for this to be fixed unless we develop this ourselves, and unfortunately NTLM is really hard to test in a CI because it is IME completely non existent unless on microsoft products.

answer 2: no, but it will follow redirects and in the case of ntlm try to do the thing explained above.

answer 3: From the looks of it when I tried to make it so that 401 in ntlm requests to not add to http_req_failed, I failed to take into account that there are two 401 in a row before it actually succeeds. There also appears to be a case where only 1 will accurate which is likely what confused me, and again we can’t test this. I apparently have even opened an issue about this a year ago and completely forgot about this until I just tried to open a new one.

I kind of doubt we will prioritize this higher again, but if you want you can try to make a PR for it.

Hope this helps you!

1 Like

Hi mstoykov,
Very thanks for your reply, your explain very useful for me.

Queation 1: For the code I provided above, I have another question. Why do I have to successfully send a get request before I can successfully send a post request? Is there any method in K6 to send only one post request and without get API request in a JS script?
Question 2: Based on your above explain, I want to confirm that K6 is there any parameter or method that can be configured to exclude one API requests from the statistics of “http_req_failed” and others.

Regards
Lambda

Queation 1: For the code I provided above, I have another question. Why do I have to successfully send a get request before I can successfully send a post request? Is there any method in K6 to send only one post request and without get API request in a JS script?

You don’t need to send a get request before you can send a post request. Sorry If I made it sound like that.

I think that in your case the problem is that your http.post send the headers and the auth as the body as http.post has the body as the second argument.

Because NTLM is connection based and k6 will reuse the connection it will work after the original request authenticate, even if the second one doesn’t.

Question 2: Based on your above explain, I want to confirm that K6 is there any parameter or method that can be configured to exclude one API requests from the statistics of “http_req_failed” and others.

Not at the moment you can see this issue about potential future way to do it.

I would like to reiterate that in this case in the future this 1 failed should be marked as not failed.

1 Like

Thanks mstoykov,

I have another question want to confirm with you.
k6 script run result, below screenshot: the p(90) and p(95) means that 90% or 95% of the request time is 406ms or 518ms?


the grafana display p95 request duration time not equal to 518 ms, so i want to confirm with you, how to calculate and get the p95 duration time?

Regards
Lambda

Hi @lambda999,

It is the 90th and 95th percentile (which is different from a percent).

I would guess that given tthat there are 6 values they are either for different names or for 6 distinct time periods while the k6 values are for the whole duration of the test.

1 Like

Thanks mstoykov,

Thanks for your reply, I understand the 90th and 95th present percentile. :grinning: