artilleryio / artillery

The complete load testing platform. Everything you need for production-grade load tests. Serverless & distributed. Load test with Playwright. Load test HTTP APIs, GraphQL, WebSocket, and more. Use any Node.js module.
https://www.artillery.io
Mozilla Public License 2.0
7.75k stars 494 forks source link

CSV-Payload with multiple fields is empty when accessed by $loopElement.field #2633

Open siom79 opened 3 months ago

siom79 commented 3 months ago

Version info:

Artillery: 2.0.9
Node.js:   v21.7.2
OS:        linux

Running this command:

artillery run ./artillery_load-test.yam

I expected to see this happen:

The CSV file contains comma separated values that should be used as JSON payload for the POST requests. I expect that for each request data from the CSV file is used.

Instead, this happened:

The JSON elements are just "empty", captured with a simple http-Node Server:

==== POST /leistungen
> Headers
{
  'user-agent': 'Artillery (https://artillery.io)',
  authorization: 'Bearer eyJ...',
  'content-type': 'application/json',
  'content-length': '43',
  'accept-encoding': 'gzip, deflate, br',
  host: 'localhost:8080',
  connection: 'keep-alive'
}
> Body
{"behandlungsjahr":{"von":2000,"bis":2024}}

We only see the fields behandlungsjahr, but not vnr, vznr, etc.

Files being used:

config:
  target: http://localhost:8080
  phases:
    - duration: 30
      arrivalRate: 1
      rampTo: 5
      name: "Warm up phase"
    - duration: 30
      arrivalRate: 5
      rampTo: 30
      name: "Ramp up phase"
    - duration: 30
      arrivalRate: 30
      rampTo: 30
      name: "Spike phase"
  payload:
    - path: "test.csv"
      fields:
        - "vnr"
        - "vznr"
        - "rinr"
        - "sgnr"
        - "pnr"
      loadAll: true
      name: vp
      order: random
    - path: "basic_auth.csv"
      fields:
        - "basicAuth"

before:
  flow:
    - post:
        url: "https://example.com/auth/token"
        headers:
          authorization: "Basic {{basicAuth}}"
          content-type: "application/x-www-form-urlencoded"
        form:
          grant_type: client_credentials
        capture:
          json: "$.access_token"
          as: "bearer"

scenarios:
  - flow:
      - loop:
          - post:
              url: "/leistungen"
              headers:
                authorization: "Bearer {{bearer}}"
                content-type: "application/json"
              json:
                vnr: "{{ $loopElement.vnr }}"
                vznr: "{{ $loopElement.vznr }}"
                rinr: "{{ $loopElement.rinr }}"
                sgnr: "{{ $loopElement.sgnr }}"
                pnr: "{{ $loopElement.pnr }}"
                behandlungsjahr:
                  von: 2000
                  bis: 2024
        over: vp

The CSV file test.csv:

100001,2,1,1,1
100001,2,1,1,2
100007,2,1,1,1
100007,2,1,1,2
100007,2,1,1,4
100007,2,3,1,1
100008,2,1,1,1
100010,2,1,7,1
100010,2,1,7,5
100012,2,1,1,1
100059,2,1,1,1
100059,2,1,1,2
100065,2,1,1,1
[...]

The CSV file basic_auth.csv contains only one line with the base64 encoded data for the basic auth login.

hassy commented 3 months ago

Thank you for the detailed bug report! Looks like a bug, we'll take a look

bernardobridge commented 2 months ago

Hi @siom79 👋 ,

Can you try removing order: random from your config? I believe this is happening because when you select order, then a specific row is passed (randomly) to the VU, rather than the entire thing.

siom79 commented 2 months ago

Hi @bernardobridge ,

when removing order: random the loop variable works and the variables are set to random rows from the file. I wasn't expecting that.

Is is possible to fix it such that it also works when setting order: random although it might be redundant? Or at least output an error message?

But: When running the exactly same config against my "real" application and I look into the logs, I see that the variables are not filled with random values from the file but they are all the same (from the first 10 lines). That was the reason why I have set order: random. So why does it work with a simpel node-server, but not with a real application? What might be the difference there?