{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://catalog.lintel.tools/schemas/schemastore/neoload/latest.json",
  "title": "JSON Schema for NeoLoad as-code files",
  "x-lintel": {
    "source": "https://raw.githubusercontent.com/Neotys-Labs/neoload-cli/master/resources/as-code.latest.schema.json",
    "sourceSha256": "1c30e9661d3d159a91b6184c5368d6b6d0732744be753dc6d5fa3d42c62ca4cb",
    "fileMatch": [
      ".nl.yaml",
      ".nl.yml",
      ".nl.json",
      ".neoload.yaml",
      ".neoload.yml",
      ".neoload.json"
    ],
    "parsers": [
      "json",
      "yaml"
    ]
  },
  "type": "object",
  "properties": {
    "$schema": {
      "$ref": "#/$defs/full_url"
    },
    "name": {
      "$ref": "#/$defs/name"
    },
    "includes": {
      "items": {
        "$ref": "#/$defs/text"
      },
      "title": "Includes",
      "type": "array",
      "minItems": 1,
      "additionalProperties": false
    },
    "variables": {
      "items": {
        "anyOf": [
          {
            "$ref": "#/$defs/constant"
          },
          {
            "$ref": "#/$defs/file"
          },
          {
            "$ref": "#/$defs/counter"
          },
          {
            "$ref": "#/$defs/random_number"
          },
          {
            "$ref": "#/$defs/javascript"
          }
        ]
      },
      "title": "Variables",
      "type": "array",
      "additionalItems": false,
      "minItems": 1,
      "additionalProperties": false
    },
    "servers": {
      "items": {
        "$ref": "#/$defs/server"
      },
      "title": "Servers",
      "type": "array",
      "minItems": 1
    },
    "sla_profiles": {
      "items": {
        "$ref": "#/$defs/sla"
      },
      "title": "SLA Profiles",
      "type": "array",
      "minItems": 1
    },
    "populations": {
      "items": {
        "$ref": "#/$defs/population"
      },
      "title": "Populations",
      "type": "array",
      "minItems": 1
    },
    "scenarios": {
      "items": {
        "$ref": "#/$defs/scenario"
      },
      "title": "Scenarios",
      "type": "array",
      "minItems": 1
    },
    "user_paths": {
      "items": {
        "$ref": "#/$defs/user_path"
      },
      "title": "User_paths",
      "type": "array",
      "minItems": 1
    }
  },
  "xrequired": [
    "name",
    "because neoload files can be partial"
  ],
  "additionalProperties": false,
  "$defs": {
    "sla": {
      "threshold": {
        "$id": "#/definitions/sla/threshold",
        "title": "Threshold",
        "type": "string",
        "pattern": "^(.*?)\\s(warn\\s(>=|==|<=|>|<))(?=\\s)(.*?)per\\s(test|interval)$"
      },
      "title": "SLA Profile",
      "type": "object",
      "xrequired": [
        "name",
        "thresholds"
      ],
      "properties": {
        "name": {
          "$ref": "#/$defs/text"
        },
        "description": {
          "$ref": "#/$defs/text"
        },
        "thresholds": {
          "items": {
            "$ref": "#/$defs/sla/threshold"
          },
          "title": "Thresholds",
          "type": "array",
          "minItems": 1,
          "additionalProperties": false
        }
      }
    },
    "scenario": {
      "properties": {
        "name": {
          "$ref": "#/$defs/text"
        },
        "description": {
          "$ref": "#/$defs/text"
        },
        "populations": {
          "items": {
            "properties": {
              "name": {
                "$ref": "#/$defs/text"
              },
              "constant_load": {
                "$ref": "#/$defs/constant_load"
              },
              "rampup_load": {
                "$ref": "#/$defs/rampup_load"
              },
              "peaks_load": {
                "$ref": "#/$defs/peaks_load"
              }
            },
            "type": "object",
            "required": [
              "name"
            ]
          },
          "title": "Scenario Populations",
          "type": "array",
          "minItems": 1,
          "additionalItems": false,
          "additionalProperties": false
        }
      },
      "title": "Scenario",
      "type": "object"
    },
    "server": {
      "properties": {
        "name": {
          "$ref": "#/$defs/text"
        },
        "host": {
          "$ref": "#/$defs/text"
        },
        "scheme": {
          "enum": [
            "http",
            "https"
          ],
          "type": "string"
        },
        "port": {
          "type": "integer"
        },
        "basic_authentication": {
          "$ref": "#/$defs/basic"
        },
        "ntlm_authentication": {
          "$ref": "#/$defs/ntlm"
        },
        "negotiate_authentication": {
          "$ref": "#/$defs/basic"
        }
      },
      "title": "Server",
      "type": "object",
      "xrequired": [
        "name",
        "host"
      ],
      "additionalProperties": false
    },
    "text": {
      "pattern": ".*",
      "title": "Text",
      "type": "string"
    },
    "positive_number": {
      "minimum": 0,
      "title": "Positive Number",
      "type": "integer"
    },
    "duration": {
      "anyOf": [
        {
          "$ref": "#/$defs/common/time"
        },
        {
          "$ref": "#/$defs/common/iterations"
        }
      ],
      "title": "Duration"
    },
    "stop_after_options": {
      "anyOf": [
        {
          "$ref": "#/$defs/common/time"
        },
        {
          "type": "string",
          "enum": [
            "current_iteration"
          ]
        }
      ],
      "title": "variation_policy.stop_after values"
    },
    "start_after_options": {
      "anyOf": [
        {
          "$ref": "#/$defs/common/time"
        },
        {
          "$ref": "#/$defs/common/text"
        }
      ],
      "title": "Start after"
    },
    "time": {
      "pattern": "^((\\d{1,2}[hms]{1}){1,3})+$",
      "title": "Time",
      "type": "string"
    },
    "iterations": {
      "pattern": "^(\\d+ iterations)$",
      "title": "Iterations",
      "type": "string"
    },
    "name": {
      "title": "Name",
      "type": "string",
      "pattern": "^.*$"
    },
    "full_url": {
      "title": "Url",
      "type": "string",
      "pattern": "https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)"
    },
    "var_change_policy": {
      "type": "string",
      "default": "each_iteration",
      "enum": [
        "each_use",
        "each_request",
        "each_page",
        "each_iteration",
        "each_user"
      ]
    },
    "var_scope": {
      "type": "string",
      "default": "global",
      "enum": [
        "local",
        "global",
        "unique"
      ]
    },
    "var_order": {
      "type": "string",
      "default": "global",
      "enum": [
        "sequential",
        "random",
        "any"
      ]
    },
    "var_out_of_value": {
      "type": "string",
      "default": "global",
      "enum": [
        "cycle",
        "stop_test",
        "no_value_code"
      ]
    },
    "generic": {
      "properties": {
        "name": {
          "$ref": "#/$defs/common/name"
        },
        "descrption": {
          "$ref": "#/$defs/common/text"
        },
        "change_policy": {
          "$ref": "#/$defs/common/var_change_policy"
        }
      },
      "type": "object",
      "xrequired": [
        "name"
      ]
    },
    "constant": {
      "x-d7nosupport-additionalProperties": false,
      "title": "Constant",
      "type": "object",
      "xrequired": [
        "value"
      ],
      "allOf": [
        {
          "$ref": "#/$defs/variables/generic"
        },
        {
          "properties": {
            "value": {
              "$ref": "#/$defs/common/text"
            }
          }
        }
      ]
    },
    "file": {
      "x-d7nosupport-additionalProperties": false,
      "title": "File",
      "type": "object",
      "xrequired": [
        "path"
      ],
      "allOf": [
        {
          "$ref": "#/$defs/variables/generic"
        },
        {
          "properties": {
            "column_names": {
              "type": "array",
              "prefixItems": [
                {
                  "type": "string"
                }
              ]
            },
            "is_first_line_column_names": {
              "type": "boolean",
              "default": false
            },
            "start_from_line": {
              "type": "integer",
              "default": 1
            },
            "delimiter": {
              "$ref": "#/$defs/common/text",
              "default": ","
            },
            "path": {
              "$ref": "#/$defs/common/text"
            },
            "scope": {
              "$ref": "#/$defs/common/var_scope"
            },
            "order": {
              "$ref": "#/$defs/common/var_order"
            },
            "out_of_value": {
              "$ref": "#/$defs/common/var_out_of_value"
            }
          }
        }
      ]
    },
    "counter": {
      "x-d7nosupport-additionalProperties": false,
      "title": "Counter",
      "type": "object",
      "xrequired": [
        "start",
        "end",
        "increment"
      ],
      "allOf": [
        {
          "$ref": "#/$defs/variables/generic"
        },
        {
          "properties": {
            "start": {
              "type": "number"
            },
            "end": {
              "type": "number"
            },
            "increment": {
              "type": "number"
            },
            "scope": {
              "$ref": "#/$defs/common/var_scope"
            },
            "out_of_value": {
              "$ref": "#/$defs/common/var_out_of_value"
            }
          }
        }
      ]
    },
    "random_number": {
      "x-d7nosupport-additionalProperties": false,
      "title": "Random Number",
      "type": "object",
      "xrequired": [
        "min",
        "max"
      ],
      "allOf": [
        {
          "$ref": "#/$defs/variables/generic"
        },
        {
          "properties": {
            "min": {
              "type": "number"
            },
            "max": {
              "type": "number"
            },
            "predictable": {
              "type": "boolean"
            }
          }
        }
      ]
    },
    "javascript": {
      "x-d7nosupport-additionalProperties": false,
      "title": "Javascript",
      "type": "object",
      "xrequired": [
        "script"
      ],
      "allOf": [
        {
          "$ref": "#/$defs/variables/generic"
        },
        {
          "properties": {
            "script": {
              "$ref": "#/$defs/common/text"
            }
          }
        }
      ]
    },
    "auth-generic": {
      "properties": {
        "login": {
          "$ref": "#/$defs/common/text"
        },
        "password": {
          "$ref": "#/$defs/common/text"
        }
      },
      "type": "object",
      "xrequired": [
        "login",
        "password"
      ]
    },
    "auth-generic-domain": {
      "allOf": [
        {
          "$ref": "#/$defs/authentication/auth-generic"
        },
        {
          "properties": {
            "domain": {
              "$ref": "#/$defs/common/text"
            }
          }
        }
      ],
      "type": "object"
    },
    "basic": {
      "allOf": [
        {
          "$ref": "#/$defs/authentication/auth-generic"
        },
        {
          "properties": {
            "realm": {
              "$ref": "#/$defs/common/text"
            }
          }
        }
      ],
      "title": "Basic Authentication",
      "type": "object"
    },
    "ntlm": {
      "allOf": [
        {
          "$ref": "#/$defs/authentication/auth-generic-domain"
        }
      ],
      "title": "NTLM Authentication",
      "type": "object"
    },
    "negotiate": {
      "allOf": [
        {
          "$ref": "#/$defs/authentication/auth-generic-domain"
        }
      ],
      "title": "Negotiate Authentication",
      "type": "object"
    },
    "population": {
      "properties": {
        "name": {
          "$ref": "#/$defs/common/text"
        },
        "description": {
          "$ref": "#/$defs/common/text"
        },
        "xcomments": {
          "value": "why do we need the substructure 'name' to denote a string list?"
        },
        "user_paths": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "$ref": "#/$defs/common/text"
              }
            }
          },
          "additionalItems": false,
          "additionalProperties": false
        }
      },
      "title": "Population",
      "type": "object"
    },
    "constant_load": {
      "properties": {
        "duration": {
          "$ref": "#/$defs/common/duration"
        },
        "start_after": {
          "$ref": "#/$defs/common/start_after_options"
        },
        "stop_after": {
          "$ref": "#/$defs/common/stop_after_options"
        },
        "users": {
          "type": "integer",
          "default": 1
        },
        "rampup": {
          "$ref": "#/$defs/common/time"
        }
      },
      "title": "Constant Load",
      "type": "object",
      "required": [
        "users"
      ]
    },
    "rampup_load": {
      "properties": {
        "duration": {
          "$ref": "#/$defs/common/duration"
        },
        "start_after": {
          "$ref": "#/$defs/common/start_after_options"
        },
        "stop_after": {
          "$ref": "#/$defs/common/stop_after_options"
        },
        "min_users": {
          "$ref": "#/$defs/common/positive_number"
        },
        "max_users": {
          "$ref": "#/$defs/common/positive_number"
        },
        "increment_users": {
          "type": "integer",
          "default": 1
        },
        "increment_every": {
          "$ref": "#/$defs/common/duration"
        },
        "increment_rampup": {
          "$ref": "#/$defs/common/time"
        }
      },
      "title": "Ramp-up Load",
      "type": "object",
      "required": [
        "min_users",
        "increment_users",
        "increment_every"
      ],
      "additionalProperties": false
    },
    "peaks_load": {
      "properties": {
        "minimum": {
          "$ref": "#/$defs/populations/peaks_phase"
        },
        "maximum": {
          "$ref": "#/$defs/populations/peaks_phase"
        },
        "start": {
          "type": "string",
          "enum": [
            "minimum",
            "maximum"
          ]
        },
        "duration": {
          "$ref": "#/$defs/common/duration"
        },
        "start_after": {
          "$ref": "#/$defs/common/start_after_options"
        },
        "step_rampup": {
          "$ref": "#/$defs/common/text"
        },
        "stop_after": {
          "$ref": "#/$defs/common/stop_after_options"
        }
      },
      "title": "Peaks Load",
      "type": "object",
      "required": [
        "minimum",
        "maximum",
        "start"
      ],
      "additionalProperties": false
    },
    "peaks_phase": {
      "properties": {
        "users": {
          "$ref": "#/$defs/common/positive_number"
        },
        "duration": {
          "$ref": "#/$defs/common/duration"
        }
      },
      "title": "Peak Phase",
      "type": "object",
      "required": [
        "users",
        "duration"
      ]
    },
    "user_path": {
      "properties": {
        "name": {
          "$ref": "#/$defs/common/text"
        },
        "description": {
          "$ref": "#/$defs/common/text"
        },
        "user_session": {
          "type": "string",
          "enum": [
            "reset_on",
            "reset_off",
            "reset_auto"
          ]
        },
        "init": {
          "$ref": "#/$defs/user_paths/container"
        },
        "actions": {
          "$ref": "#/$defs/user_paths/container"
        },
        "end": {
          "$ref": "#/$defs/user_paths/container"
        }
      },
      "title": "User Path",
      "type": "object",
      "required": [
        "name",
        "actions"
      ]
    },
    "container": {
      "properties": {
        "sla_profile": {
          "type": "string"
        },
        "steps": {
          "title": "Steps",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "properties": {
              "transaction": {
                "$ref": "#/$defs/user_paths/actions/transaction"
              },
              "request": {
                "$ref": "#/$defs/user_paths/actions/request"
              },
              "delay": {
                "$ref": "#/$defs/user_paths/actions/delay"
              },
              "think_time": {
                "$ref": "#/$defs/user_paths/actions/think_time"
              },
              "javascript": {
                "$ref": "#/$defs/user_paths/actions/javascript"
              },
              "if": {
                "$ref": "#/$defs/user_paths/actions/if"
              }
            },
            "additionalProperties": false
          }
        }
      },
      "title": "Containers",
      "type": "object",
      "required": [
        "steps"
      ]
    },
    "actions": {
      "transaction": {
        "$id": "#/definitions/user_paths/actions/transaction",
        "name": "transaction",
        "title": "Action: Transaction",
        "type": "object",
        "required": [
          "name",
          "steps"
        ],
        "properties": {
          "name": {
            "$ref": "#/definitions/common/text"
          },
          "description": {
            "$ref": "#/definitions/common/text"
          },
          "steps": {
            "title": "Steps",
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "properties": {
                "transaction": {
                  "$ref": "#/definitions/user_paths/actions/transaction"
                },
                "request": {
                  "$ref": "#/definitions/user_paths/actions/request"
                },
                "delay": {
                  "$ref": "#/definitions/user_paths/actions/delay"
                },
                "think_time": {
                  "$ref": "#/definitions/user_paths/actions/think_time"
                },
                "javascript": {
                  "$ref": "#/definitions/user_paths/actions/javascript"
                },
                "if": {
                  "$ref": "#/definitions/user_paths/actions/if"
                }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "request": {
        "$id": "#/definitions/user_paths/actions/request",
        "title": "Action: HTTP/s Request",
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "$ref": "#/definitions/common/text"
          },
          "server": {
            "$ref": "#/definitions/common/text"
          },
          "method": {
            "type": "string",
            "enum": [
              "GET",
              "POST",
              "HEAD",
              "PUT",
              "DELETE",
              "OPTIONS",
              "TRACE"
            ]
          },
          "headers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              }
            }
          },
          "sla_profile": {
            "$ref": "#/definitions/common/text"
          },
          "body": {
            "$ref": "#/definitions/common/text"
          },
          "extractors": {
            "type": "array",
            "items": {
              "$ref": "#/definitions/user_paths/extractor"
            }
          }
        }
      },
      "delay": {
        "$id": "#/definitions/user_paths/actions/delay",
        "title": "Action: Delay",
        "type": "string",
        "allOf": [
          {
            "$ref": "#/definitions/common/text"
          }
        ]
      },
      "think_time": {
        "$id": "#/definitions/user_paths/actions/think_time",
        "title": "Action: Think Time",
        "type": "string",
        "allOf": [
          {
            "$ref": "#/definitions/common/text"
          }
        ]
      },
      "javascript": {
        "$id": "#/definitions/user_paths/actions/javascript",
        "title": "Action: Javascript",
        "type": "object",
        "xrequired": [
          "name",
          "script"
        ],
        "properties": {
          "name": {
            "$ref": "#/definitions/common/text"
          },
          "description": {
            "$ref": "#/definitions/common/text"
          },
          "script": {
            "$ref": "#/definitions/common/text"
          }
        }
      },
      "if": {
        "properties": {
          "name": {
            "$ref": "#/$defs/common/text"
          },
          "description": {
            "$ref": "#/$defs/common/text"
          },
          "conditions": {
            "type": "array",
            "xcomments": "like GWBSR said: 'aint gonna do it', at least not this commit",
            "items": {
              "$ref": "#/$defs/common/text"
            }
          },
          "match": {
            "type": "string",
            "enum": [
              "any",
              "all"
            ],
            "default": "any"
          },
          "then": {
            "$ref": "#/$defs/user_paths/container"
          },
          "else": {
            "$ref": "#/$defs/user_paths/container"
          }
        },
        "title": "Action: If",
        "type": "object",
        "xrequired": [
          "conditions",
          "then"
        ]
      }
    },
    "extractor": {
      "type": "object",
      "xrequired": [
        "name"
      ],
      "properties": {
        "name": {
          "$ref": "#/$defs/common/text"
        },
        "from": {
          "type": "string",
          "default": "body",
          "enum": [
            "header",
            "body",
            "both"
          ]
        },
        "xpath": {
          "$ref": "#/$defs/common/text"
        },
        "jsonpath": {
          "$ref": "#/$defs/common/text"
        },
        "regexp": {
          "$ref": "#/$defs/common/text"
        },
        "match_number": {
          "type": "integer",
          "default": 1
        },
        "template": {
          "$ref": "#/$defs/common/text"
        },
        "decode": {
          "type": "string",
          "enum": [
            "html",
            "url"
          ]
        },
        "extract_once": {
          "type": "boolean",
          "default": false
        },
        "default": {
          "type": "string",
          "default": ""
        },
        "throw_assertion_error": {
          "type": "boolean",
          "default": true
        }
      }
    }
  },
  "fileMatch": [
    "*.nl.yaml",
    "*.neoload.yaml",
    "neoload*.yaml",
    "*.nl.yml",
    "*.neoload.yml",
    "neoload*.yml",
    "*.nl.json",
    "*.neoload.json",
    "neoload*.json"
  ],
  "minProperties": 1
}
