HTTP File Uploads

Background

The http-file-uploads plugin in Artillery Pro adds support for multipart/form-data form uploads in your test scripts, i.e. the mechanism that web browsers use to allow users to upload files to a server. It can also be used to transfer arbitrary binary data with chunked transfer encoding.

Configuration

Basic Configuration

The file upload plugin must be enabled in the config section of your script.

config:
  target: "http://example.com"
  #
  # Enable the file upload plugin:
  #
  plugins:
    http-file-uploads: {}

Form Uploads (multipart/form-data)

To submit forms containing one or more file fields use the formData attribute on the request andfromFile to specify the file to be uploaded.

scenarios:
  - flow:
      #
      # Upload a file through a form with two fields:
      # 1. name (text)
      # 2. avatar (file data from ./files/avatar.jpg, relative to the location
      #    of the test script)
      #
      post:
        url: "/upload"
        formData:
          name: "Bart Simpson"
          avatar:
            fromFile: "./files/avatar.jpg"

Uploading Multiple Files

To upload more than one file, use multiple fromFile attributes:

- post:
    url: "/upload"
    formData:
      name: "Homer Simpson"
      resume:
        fromFile: "./files/resume.pdf"
      cover_letter:
        fromFile: "./files/cover_letter.pdf"

Customizing File Metadata

File metadata may be customized:

- post:
    url: "/upload"
    formData:
      name: "Homer Simpson"
      resume:
        value:
          fromFile: "./files/resume.pdf"
        options:
          # original filename seen by the server
          filename: "homer_simpson_resume.pdf"
          conentType: "application/pdf"

Binary Uploads (Chunked Transfer Encoding)

To stream an arbitrary file content as the body of a request use fromFile in the body attribute of your request:

scenarios:
  - flow:
     - put:
         url: "/files/myfile.png"
         body:
           fromFile: "./myfile.png"

If the headers don't specify the content-type, Artillery will check the file extension against a mapping of file extensions to content-types and use the proper content-type for the request.

S3/CloudFront Uploads With Pre-Signed URLs

If you are using Artillery to make PUT requests to pre-signed S3/CloudFront URLs, note that S3 requires that the Content-Length header is set, even when using chunked transfer encoding.

You can use the setContentLengthHeader option to tell Artillery to include the header. The value of the header will be set to the size of the file in bytes:

scenarios:
  - flow:
     - put:
         url: "https://presigned-url.cloudfront.net/file.png"
         body:
           fromFile: "./myfile.png"
           setContentLengthHeader: true # include the content-length header

Note: This option should not be used with multipart/form-data or multipart/related uploads, or with servers other than S3/CloudFront unless you are sure that you need it.

Usage With Tests Run From AWS ECS

For file upload tests that run from the cloud (i.e. an AWS ECS cluster with artillery run-cluster), the filePaths property should be set to a list of all files and/or directories which are used by the scenarios.

config:
  target: "http://example.com"
  plugins:
    http-file-uploads:
      #
      # The files used by scenarios for uploading to the server all reside
      # in ../data/files:
      #
      filePaths:
        - ../data/files

Large amounts of file data will have an effect on the startup time of your tests. Consider using the smallest amount of data possible and using named tests (created with artillery create-test) to improve the startup time of your tests.

Using Variables

Variables may be used with fromFile to randomize the files being uploaded. For example:

config:
  target: "http://example.com"
  #
  # Enable the file upload plugin:
  #
  plugins:
    http-file-uploads: {}
  variables:
    filename:
      - "avatar1.jpg"
      - "avatar2.jpg"
      - "avatar3.jpg"
      - "avatar4.jpg"
scenarios:
  - flow:
      #
      # Upload a file through a form with two fields:
      # 1. name (text)
      # 2. avatar (file data from ./files/avatar.jpg, relative to the location
      #    of the test script)
      #
      post:
        url: "/upload"
        formData:
          name: "Bart Simpson"
          avatar:
            fromFile: "./files/{{ filename }}"

Errors

If a file cannot be read, an ENOENT error will be reported in Artillery's output.