artilleryio / artillery-core

artillery-core - deprecated
Mozilla Public License 2.0
29 stars 104 forks source link

Add ability to run requests in parallel #210

Closed Wol closed 7 years ago

Wol commented 7 years ago

For some apps, it has to handle multiple requests from a single user at once (e.g. API requests which are fired at the same time).

This adds in a nested step with a similar syntax to the loop configuration which allows requests to be grouped together and run in parallel. Once all requests have completed, the load test then continues.

hassy commented 7 years ago

Thanks @Wol!

Related issue: https://github.com/shoreditch-ops/artillery/issues/376

Wol commented 7 years ago

Also just to jot down a bit more on usage:

To make sure that enough sockets are allocated for the parallel processing, make sure that the configuration block specifies the config.http.maxSockets variable. Running 20 tasks in parallel over 1 socket will end up with no parallel requests.

config:
  target: "http://target.dev"
  phases:
    - duration: 10
      arrivalRate: 5
  http:
    maxSockets: 4

scenarios:
  - flow:
      - log: "New virtual user running"
      - get:
          url: "/first_url"
          capture:
            selector: "[data-capture-value]"
            as: capturedvalue
            attr: data-capture-value
      - log: "Captured value was: {{ capturedvalue }}"
      - parallel:
        - get:
            url: /test_url_1.php?{{capturedvalue}}
        - get:
            url: /test_url_2.php?{{capturedvalue}}
        - get:
            url: /test_url_3.php?{{capturedvalue}}
      - log: "Done"

Captured values can also be handled in parallel (not fully tested, but seems to work)

slow.php just runs sleep(1); and returns a JSON string with the request time delta as: {'time': 1.0000}

config:
  target: "http://target.dev"
  phases:
    - duration: 10
      arrivalRate: 5
  http:
    maxSockets: 3

scenarios:
  - flow:
      - parallel:
        - get:
            url: "/slow.php"
            capture:
              json: "$.time"
              as: "time1"
        - get:
            url: "/slow.php"
            capture:
              json: "$.time"
              as: "time2"
      - log: "Time was {{ time1 }} and {{ time2 }}"

This will print out: Time was 1.0000958442688 and 1.000107049942

eledhwen commented 6 years ago

Hi @hassy

I'm wondering if this feature is supposed to be available in the 1.6.0-12 version of Artillery, it looks like it should be, but I seemingly can't make it work.

The logs aren't very helpful (I get "an URL must be specified" errors when using "parallel" blocks), so I'm wondering if I'm simply doing it wrong, or if it's just not there yet (and just fails somewhat silently).

And if it's not available, do you know when it will be?

Thanks in advance.

hassy commented 6 years ago

@eledhwen Yes that functionality should be available in 1.6.0-12 - mind filing an issue with an example on the main repo? Cheers

eledhwen commented 6 years ago

@hassy Okay, I'll start by having a closer look at my configuration, and if I can't find anything I'll do that. Thank you for the help!