UNPKG

111 kBMarkdownView Raw
1# Serverless-artillery [![Build Status](https://travis-ci.org/Nordstrom/serverless-artillery.svg?branch=master)](https://travis-ci.org/Nordstrom/serverless-artillery) [![Coverage Status](https://coveralls.io/repos/github/Nordstrom/serverless-artillery/badge.svg?branch=master)](https://coveralls.io/github/Nordstrom/serverless-artillery?branch=master)
2
3[//]: # (Thanks to https://www.divio.com/en/blog/documentation/)
4
5# Introduction
6Combine [`serverless`](https://serverless.com) with [`artillery`](https://artillery.io) and you get `serverless-artillery` (a.k.a. `slsart`).
7
8Serverless-artillery makes it easy to test your services for performance and functionality quickly, easily and without having to maintain any servers or testing infrastructure.
9
10### Use serverless-artillery if
111. You want to know if your services (either internal or public) can handle different amount of traffic load (i.e. performance or load testing).
121. You want to test if your services behave as you expect after you deploy new changes (i.e. acceptance testing).
131. You want to constantly monitor your services over time to make sure the latency of your services is under control (i.e. monitoring mode).
14
15# Table of Contents
16- [Installation](#installation)
17 - [Installing on local machine](#installing-on-local-machine)
18 - [Prerequisite](#prerequisite)
19 - [1. Node JS](#1-node-js)
20 - [2. Serverless Framework CLI](#2-serverless-framework-cli)
21 - [Installing serverless-artillery](#installing-serverless-artillery)
22 - [Installing in Docker](#installing-in-docker)
23- [Uninstallation](#uninstallation)
24- [How it works?](#how-it-works)
25 - [Load generator Lambda function on AWS](#load-generator-lambda-function-on-aws)
26- [Before running serverless-artillery](#before-running-serverless-artillery)
27 - [Setup for Nordstrom Technology](#setup-for-nordstrom-technology)
28 - [Setup for everyone else](#setup-for-everyone-else)
29- [Tutorial 1: Run a quick performance test](#tutorial-1-run-a-quick-performance-test)
30 - [1. Setup AWS account credentials](#1-setup-aws-account-credentials)
31 - [2. Command line](#2-command-line)
32 - [3. Deploy](#3-deploy)
33 - [4. Invoke](#4-invoke)
34 - [5. Remove](#5-remove)
35- [Tutorial 2: Performance test with custom script](#tutorial-2-performance-test-with-custom-script)
36 - [1. Create new directory](#1-create-new-directory)
37 - [2. Create `script.yml`](#2-create-scriptyml)
38 - [3. Understanding `script.yml`](#3-understanding-scriptyml)
39 - [4. Customizing `script.yml`](#4-customizing-scriptyml)
40 - [5. Setup AWS account credentials](#5-setup-aws-account-credentials)
41 - [6. Deploy assets to AWS](#6-deploy-assets-to-aws)
42 - [7. Invoke performance test](#7-invoke-performance-test)
43 - [8. Remove assets from AWS](#8-remove-assets-from-aws)
44- [Tutorial 3: Performance test with custom deployment assets](#tutorial-3-performance-test-with-custom-deployment-assets)
45 - [1. Create new directory](#1-create-new-directory-1)
46 - [2. Create `script.yml`](#2-create-scriptyml)
47 - [3. Understanding `script.yml`](#3-understanding-scriptyml)
48 - [4. Customizing `script.yml`](#4-customizing-scriptyml)
49 - [5. Create custom deployment assets](#5-create-custom-deployment-assets)
50 - [6. Understanding `serverless.yml`](#6-understanding-serverlessyml)
51 - [a. Service name](#a-service-name)
52 - [b. Load generator Lambda function name](#b-load-generator-lambda-function-name)
53 - [c. Load generator Lambda function permissions](#c-load-generator-lambda-function-permissions)
54 - [7. Customizing `serverless.yml`](#7-customizing-serverlessyml)
55 - [a. Customization for Nordstrom Engineers](#a-customization-for-nordstrom-engineers)
56 - [b. Service name](#b-service-name)
57 - [c. Plugins](#c-plugins)
58 - [i. CloudWatch plugin](#i-cloudwatch-plugin)
59 - [ii. Datadog plugin](#ii-datadog-plugin)
60 - [8. Setup AWS account credentials](#8-setup-aws-account-credentials)
61 - [9. Deploy assets to AWS](#9-deploy-assets-to-aws)
62 - [10. Invoke performance test](#10-invoke-performance-test)
63 - [11. Remove assets from AWS](#11-remove-assets-from-aws)
64- [Tutorial 4: Killing in-progress performance test](#tutorial-4-killing-in-progress-performance-test)
65 - [1. Increase `duration`](#1-increase-duration)
66 - [2. Setup AWS account credentials](#2-setup-aws-account-credentials)
67 - [3. Deploy assets to AWS](#3-deploy-assets-to-aws)
68 - [4. Invoke performance test](#4-invoke-performance-test)
69 - [5. Kill the in-progress performance test](#5-kill-the-in-progress-performance-test)
70 - [6. Wait before re-deploying](#6-wait-before-re-deploying)
71- [Performance test workshop](#performance-test-workshop)
72- [Other commands and use cases](#other-commands-and-use-cases)
73 - [Killing in-progress performance test](#killing-in-progress-performance-test)
74 - [Create customized `script.yml`](#create-customized-scriptyml)
75 - [Performance test using script file with different name/path](#performance-test-using-script-file-with-different-namepath)
76 - [Reserved and unsupported flags](#reserved-and-unsupported-flags)
77 - [Reserved flags](#reserved-flags)
78 - [Unsupported flags](#unsupported-flags)
79 - [Providing a data store to view the results of your performance test](#providing-a-data-store-to-view-the-results-of-your-performance-test)
80 - [Related tools and plugins](#related-tools-and-plugins)
81 - [Performance testing VPC hosted services](#performance-testing-vpc-hosted-services)
82 - [Using Payload/CSV files to inject data in scenarios of your `script.yml`](#using-payloadcsv-files-to-inject-data-in-scenarios-of-your-scriptyml)
83 - [Advanced customization use cases](#advanced-customization-use-cases)
84 - [Deployment assets and settings customization](#deployment-assets-and-settings-customization)
85 - [Test script and execution customization using Artillery.io](#test-script-and-execution-customization-using-artilleryio)
86 - [Script splitting customization](#script-splitting-customization)
87 - [Debugging and Tracing Behavior Customization](#debugging-and-tracing-behavior-customization)
88 - [`_trace`](#_trace)
89 - [`_simulation`](#_simulation)
90 - [Splitting and Distribution Logic Customization](#splitting-and-distribution-logic-customization)
91 - [Scripts](#scripts)
92 - [Splitting](#splitting)
93- [Acceptance mode](#acceptance-mode)
94 - [`match` clause](#match-clause)
95 - [Acceptance test command](#acceptance-test-command)
96 - [Tutorial 5: Acceptance mode](#tutorial-5-acceptance-mode)
97 - [1. Customize `script.yml`](#1-customize-scriptyml)
98 - [2. Setup AWS account credentials](#2-setup-aws-account-credentials-1)
99 - [3. Deploy assets to AWS](#3-deploy-assets-to-aws-1)
100 - [4. Invoke acceptance test](#4-invoke-acceptance-test)
101 - [5. Observe the results](#5-observe-the-results)
102 - [6. Test failure scenario](#6-test-failure-scenario)
103 - [6.1. Edit `script.yml` to fail `match`](#61-edit-scriptyml-to-fail-match)
104 - [6.2. Invoke acceptance test](#62-invoke-acceptance-test)
105 - [6.3. Observe the results](#63-observe-the-results)
106 - [7. Remove assets from AWS](#7-remove-assets-from-aws)
107 - [More about acceptance mode](#more-about-acceptance-mode)
108 - [Acceptance testing in CI/CD](#acceptance-testing-in-cicd)
109 - [Run `script.yml` exclusively in acceptance mode](#run-scriptyml-exclusively-in-acceptance-mode)
110 - [Use same `script.yml` for performance and acceptance testing and monitoring](#use-same-scriptyml-for-performance-and-acceptance-testing-and-monitoring)
111 - [To configure acceptance behavior](#to-configure-acceptance-behavior)
112- [Monitoring mode](#monitoring-mode)
113 - [Tutorial 6: Monitoring mode without serverless-artillery alert](#tutorial-6-monitoring-mode-without-serverless-artillery-alert)
114 - [1. Create custom deployment assets](#1-create-custom-deployment-assets)
115 - [2. Setup AWS account credentials](#2-setup-aws-account-credentials-2)
116 - [3. Tryout monitoring mode](#3-tryout-monitoring-mode)
117 - [3.1. Deploy assets to AWS](#31-deploy-assets-to-aws)
118 - [3.2. Invoke monitoring once](#32-invoke-monitoring-once)
119 - [4. Customize deployment assets to turn on monitoring](#4-customize-deployment-assets-to-turn-on-monitoring)
120 - [5. Deploy assets to AWS to start monitoring](#5-deploy-assets-to-aws-to-start-monitoring)
121 - [6. Pause monitoring](#6-pause-monitoring)
122 - [6.1. Method 1: Using CloudWatch Rules](#61-method-1-using-cloudwatch-rules)
123 - [6.2. Method 2: Turn monitoring off in `serverless.yml`](#62-method-2-turn-monitoring-off-in-serverlessyml)
124 - [7. Remove assets from AWS](#7-remove-assets-from-aws-1)
125 - [Tutorial 7: Monitoring mode with serverless-artillery alert](#tutorial-7-monitoring-mode-with-serverless-artillery-alert)
126 - [1. Create custom deployment assets](#1-create-custom-deployment-assets-1)
127 - [2. Setup AWS account credentials](#2-setup-aws-account-credentials-3)
128 - [3. Customize script to have `match` clause](#3-customize-script-to-have-match-clause)
129 - [4. Customize deployment assets to add at least one subscription](#4-customize-deployment-assets-to-add-at-least-one-subscription)
130 - [5. Tryout monitoring mode](#5-tryout-monitoring-mode)
131 - [5.1. Deploy assets to AWS](#51-deploy-assets-to-aws)
132 - [5.2. Invoke monitoring once](#52-invoke-monitoring-once)
133 - [6. Test failure scenario](#6-test-failure-scenario-1)
134 - [6.1. Edit `script.yml` to fail `match`](#61-edit-scriptyml-to-fail-match-1)
135 - [6.2. Invoke monitoring once](#62-invoke-monitoring-once)
136 - [7. Customize deployment assets to turn on monitoring](#7-customize-deployment-assets-to-turn-on-monitoring)
137 - [8. Deploy assets to AWS to start monitoring](#8-deploy-assets-to-aws-to-start-monitoring)
138 - [9. Pause monitoring](#9-pause-monitoring)
139 - [10. Remove assets from AWS](#10-remove-assets-from-aws)
140 - [More about monitoring mode](#more-about-monitoring-mode)
141 - [Run `script.yml` exclusively in monitoring mode](#run-scriptyml-exclusively-in-monitoring-mode)
142 - [Use same `script.yml` for performance and acceptance testing and monitoring](#use-same-scriptyml-for-performance-and-acceptance-testing-and-monitoring-1)
143 - [To configure monitoring behavior](#to-configure-monitoring-behavior)
144- [Upgrading customized projects built with older versions of serverless-artillery](#upgrading-customized-projects-built-with-older-versions-of-serverless-artillery)
145 - [Known Upgrade Issues](#known-upgrade-issues)
146- [Detailed Usage](#detailed-usage)
147 - [Commands](#commands)
148 - [`deploy`](#deploy)
149 - [`invoke`](#invoke)
150 - [`kill`](#kill)
151 - [`remove`](#remove)
152 - [`script`](#script)
153 - [`configure`](#configure)
154 - [`upgrade`](#upgrade)
155- [Troubleshooting](#troubleshooting)
156 - [Problems installing?](#problems-installing)
157- [External References](#external-references)
158- [If you've read this far](#if-youve-read-this-far)
159
160# Installation
161
162## Installing on local machine
163You can install serverless-artillery on your local machine as follows.
164### Prerequisite
165#### 1. Node JS
166Before installing serverless-artillery, install Node JS from https://nodejs.org/en/download/ or with your operating system’s package manager. You can install the latest LTS version. We support any version higher than maintenance LTS (v8+).
167#### 2. Serverless Framework CLI
168Before installing serverless-artillery, install Serverless Framework CLI (a.k.a. Serverless) (v1.38+). It should be either installed globally or available in the local node_modules. To install globally use the following command.
169```
170npm install -g serverless
171```
172
173### Installing serverless-artillery
174Now you can install serverless-artillery on your local machine using the following command.
175```
176npm install -g serverless-artillery
177```
178To check that the installation succeeded, run:
179```
180slsart --version
181```
182You should see serverless-artillery print its version if the installation has been successful.
183
184## Installing in Docker
185If you prefer using Docker, refer to [example Dockerfile](Dockerfile) for installation. Please note that, post installation causes permission issues when installing in a Docker image. To successfully install in Docker make sure to add the following to your Dockerfile before the Serverless Framework CLI (a.k.a. Serverless) and serverless-artillery install.
186```
187ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
188ENV PATH=$PATH:/home/node/.npm-global/bin
189```
190
191# Uninstallation
192When needed, you can uninstall serverless-artillery from you local machine using the following command.
193```
194npm uninstall -g serverless-artillery
195```
196
197# How it works?
198<img src="docs/HowItWorks.jpg" width="442">
199
200* Serverless-artillery would be installed and run on your local machine. From command line run `slsart --help` to see various serverless-artillery commands.
201* It takes your JSON or YAML load script (`script.yml`) that specifies
202 * test target/URL/endpoint/service
203 * load progression
204 * and the scenarios that are important for your service to test.
205* When you run `slsart deploy` command, serverless-artillery deploys a **load generator Lambda function**, on your AWS account along with other assets.
206* Running the tests
207 * **Performance test:** When you run `slsart invoke` command, serverless-artillery would invoke the load generator Lambda function.
208 * It would generate the number of requests as specified in `script.yml` to specified test target in order to run the specified scenarios.
209 * **Acceptance test:** When you run `slsart invoke -a` command, serverless-artillery would invoke the load generator Lambda function in acceptance test mode where it runs each scenario in your script exactly once and reports the results.
210 * **Monitoring:** When you customize the deployment assets to turn on monitoring and deploy those assets using `slsart deploy` command, the load generator Lambda function is invoked in monitoring mode once a minute 24x7 where it runs each scenario in your script 5 times and sends an alert if it detects a problem.
211* When you run `slsart remove` command, serverless-artillery would remove these assets from your AWS account.
212* When you run `slsart kill` command, serverless-artillery would kill the in-progress test and remove these assets from your AWS account.
213
214## Technologies powering serverless-artillery
215<details><summary>Click to expand/collapse</summary>
216<p>
217
218### Serverless Framework
219- The [Serverless Framework](https://serverless.com) makes managing (deploying/updating/removing) cloud assets easy.
220- It translates a `yaml` file to deployable assets of the target cloud provider (like AWS).
221- Serverless-artillery uses it to manage required assets to your cloud account.
222
223### Artillery.io
224- [Artillery.io](https://artillery.io/) (built by Hassy Veldstra of shoreditch-ops) is an existing open-source node package, built for easy load testing and functional testing of a target/service/endpoint/URL. It provides a simple but powerful means of specifying how much load to create and what requests that load should comprise.
225- It takes in a developer-friendly JSON or YAML load script that specifies
226 - target/URL/endpoint
227 - load progression
228 - and the scenarios that are important for your service to test.
229- It generates specified load, and measures and reports the resulting latency and return codes.
230- It generates the load by running on your local machine or servers.
231- However, if you specify more load in your script than what can be produced on your machine, artillery will throttle down the load specified in your script. While it is simple to distribute artillery across a fleet of servers, you must then manage, coordinate, and retire them. It is not a serverless solution. This is the task that serverless-artillery steps in to remove from your plate.
232
233### Serverless-artillery
234- Serverless-artillery allows your script to specify an amount of load far exceeding the capacity of a single server to execute.
235- It breaks that script into smaller chunks (sized for a single instance of load generator Lambda function) and distribute the chunks for execution across multiple instances of load generator Lambda function.
236- Since this is done using a FaaS provider, the ephemeral infrastructure used to execute your load disappears as soon as your load tests are complete.
237
238</p>
239</details>
240
241## Load generator Lambda function on AWS
242<details><summary>Click to expand/collapse</summary>
243<p>
244
245<img src="docs/Architecture.gif">
246
247- Serverless-artillery generates the requests to run the specified tests using load generator Lambda function, which is deployed and invoked on AWS along with other assets.
248 - Naming format is `<customized-service-name default:serverless-artillery>-<optional-unique-string-><stage default:dev>-loadGenerator`. For example, `serverless-artillery-dev-loadGenerator` or `serverless-artillery-XnBa473psJ-dev-loadGenerator`.
249- It has an ephimeral architecture. It only exists as long as you need it.
250- It runs Artillery.io node package in AWS Lambda function.
251 - Each lambda function can only generate a certain amount of load, and can only run for up to five minutes (five minutes was a built-in limitation of AWS Lambda. Now it has been raised to 15 minutes).
252 - Given these limitations, it is often necessary to invoke more lambdas - both to scale horizontally (to generate higher load) as well as handing off the work to a new generation of lambdas before their run-time has expired.
253- Above diagram shows how Serverless Artillery solves this problem.
254 - It first runs the Lamdba function in a **controller** mode. It examines the submitted load config JSON/YAML script (this is identical to the original “servered” [Artillery.io](https://artillery.io/) script). This script is also referred to as original script. If the load in the original script exceeds what a single lambda is configured to handle, then the load config is chopped up into workloads achievable by a single lambda.
255 - Controller lambda then invokes as many **worker** lambdas as necessary to generate the load. Controller lambda passes a script to worker lambda that is created by chopping up the original script.
256 - Towards the end of the Lambda runtime the controller lambda invokes a new controller lambda to produce load for the remaining duration.
257- The result of the load test can be reported to CloudWatch, InfluxDB or Datadog through plugins and then visualized with CloudWatch, Grafana or Datadog dashboard.
258
259</p>
260</details>
261
262# Before running serverless-artillery
263Serverless-artillery needs to _deploy_ assets like [load generator Lambda function](#load-generator-lambda-function-on-aws) to AWS, _invoke_ the function to run the tests and _remove_ these assets from AWS when not needed. Hence you need an AWS account and setup credentials with which to deploy, invoke and remove the assets from AWS.
264
265## Setup for Nordstrom Technology
266If you are a **_Nordstrom_** engineer, please see the page titled **_`Serverless Artillery - Nordstrom Technology Setup`_** in **Confluence** and follow the instructions there.
267## Setup for everyone else
268In order to use serverless-artillery, depending on the AWS account environment you're working in, you may need to define `AWS_PROFILE` to declare the AWS credentials to use and possibly `HTTP_PROXY` in order to escape your corporate proxy. See the [Serverless Framework docs](https://serverless.com/framework/docs/) or serverless-artillery workshop's [Lesson 0](https://github.com/Nordstrom/serverless-artillery-workshop/tree/master/Lesson0%20-%20Before%20the%20workshop) followed by [**Step 1** of Lesson 1](https://github.com/Nordstrom/serverless-artillery-workshop/tree/master/Lesson1%20-%20Hello%2C%20artillery#step-1-serverless-artillery-requires-aws-credentials) for details of how to set your local machine for successful deployment, invocation, and removal of assets from your AWS accounts.
269
270# Performance mode (performance/load testing)
271You can use serverless-artillery to performance test or load test your service/target/endpoint/URL. Performance testing framework forms the basis of the other two modes of serverless-artillery, i.e. acceptance mode and monitoring mode.
272
273## Tutorial 1: Run a quick performance test
274If you want to quickly test your setup or see serverless-artillery in action, do the following to quickly run a **small load/performance test**.
275
276### 1. Setup AWS account credentials
277Make sure you have [setup your AWS account credentials](#before-running-serverless-artillery) before proceeding.
278
279### 2. Command line
280Go to command line for all the following steps in this tutorial. You can run the steps of this tutorial from anywhere in command line since the commands you run in this tutorial will not create any files on your local machine.
281
282### 3. Deploy
283The `slsart deploy` command deploys required assets (like [load generator Lambda function](#load-generator-lambda-function-on-aws)) to the AWS account you selected in the previous step.
284
285By _default_ it uses `service` name `serverless-artillery` and `stage` name `dev`. And hence the _default_ AWS CloudFormation Stack name becomes `serverless-artillery-dev` (format: `<service-name default:serverless-artillery>-<stage-name default:dev>`). You will see that if you go to your AWS account console > CloudFormation after running the command.
286
287Since multiple developers could share an AWS account, we recommend creating a unique stack for your use. For that we recommend either using custom deployment assets as shown in [Tutorial 3](#tutorial-3-performance-test-with-custom-deployment-assets) or use the _optional_ `stage` argument as shown in the following command.
288```
289slsart deploy --stage <your-unique-stage-name>
290```
291The AWS CloudFormation Stack name would be `serverless-artillery-<your-unique-stage-name>`.
292
293For example,
294```
295slsart deploy --stage test1
296```
297The AWS CloudFormation Stack name in this case would be `serverless-artillery-test1`.
298
299### 4. Invoke
300The following command will invoke [load generator Lambda function](#load-generator-lambda-function-on-aws) using the default load script (`script.yml`), creating small traffic against the sample endpoint specified in the default script. Note that this default load script is part of the global install of serverless-artillery and not in the local folder from where you are running the command.
301```
302slsart invoke --stage <your-unique-stage-name>
303```
304At the end of the test serverless-artillery will generate a report of the test. **Please note that this report is generated only for small load.** See [here](#providing-a-data-store-to-view-the-results-of-your-performance-test) for details.
305
306If you go to AWS Lambda console > find the `loadGenerator` Lambda corresponding to your stack > `Monitoring` tab > `Invocations` graph, you will see that the Lambda function was invoked to generate the load. You can also see the logs produced by the Lambda in CloudWatch Logs.
307
308### 5. Remove
309The following command will remove the AWS CloudFormation Stack deployed in step 3. If you are a **_Nordstrom_** engineer, please see the page titled **_`Serverless Artillery - Remove Instructions`_** in **Confluence** and follow the instructions there.
310```
311slsart remove --stage <your-unique-stage-name>
312```
313
314## Tutorial 2: Performance test with custom script
315Throughout this tutorial we will walk you towards performance testing the AWS website, https://aws.amazon.com/.
316
317We would test with our _custom_ script but would use _default_ deployment assets.
318
319### 1. Create new directory
320Start by creating a new directory for this tutorial and go to that directory in command line.
321
322### 2. Create `script.yml`
323Serverless-artillery needs to know information about the performance test that user wants to run. It needs information like, the target URL of the service that user wants to test, load progression, user's interaction with the service (scenarios) etc. All these are described in a `yml` file. It is the same `yml` that Artillery.io uses.
324- **Please see [here for basic concepts for Artillery.io usage](https://artillery.io/docs/basic-concepts/#basic-concepts).**
325- **Please see [here for Artillery.io's test script reference](https://artillery.io/docs/script-reference/).**
326
327Run the following command to create the initial `script.yml` file.
328```
329slsart script
330```
331
332### 3. Understanding `script.yml`
333Open `script.yml` with your favorite editor to see what it contains.
334<details><summary>Click to expand/collapse</summary>
335<p>
336
337```
338# Thank you for trying serverless-artillery!
339# This default script is intended to get you started quickly.
340# There is a lot more that Artillery can do.
341# You can find great documentation of the possibilities at:
342# https://artillery.io/docs/
343config:
344 # this hostname will be used as a prefix for each URI in the flow unless a complete URI is specified
345 target: "http://aws.amazon.com"
346 phases:
347 -
348 duration: 5
349 arrivalRate: 2
350scenarios:
351 -
352 flow:
353 -
354 get:
355 url: "/"
356
357```
358
359</p>
360</details>
361
362- The script has [`config` block](https://artillery.io/docs/script-reference/#the-config-section)
363 - under which it specifies http://aws.amazon.com as the `target` for the test
364 - and that requests should be made using [HTTP protocol](https://artillery.io/docs/http-reference/)
365 - There is one [load `phase`](https://artillery.io/docs/script-reference/#load-phases) of `duration` of 5 sec and `arrivalRate` of 2 new virtual users arriving every second.
366- The script has [`scenarios` block](https://artillery.io/docs/script-reference/#scenarios)
367 - which contains one scenario
368 - which contains one flow
369 - which has one [flow action](https://artillery.io/docs/http-reference/#flow-actions) to send [GET request](https://artillery.io/docs/http-reference/#get-post-put-patch-delete-requests) for the specified `target`.
370
371### 4. Customizing `script.yml`
372This step is optional in the tutorial. If you like you can customize `script.yml` as follows.
373- If you have a public endpoint/service/URL that you would like to load test then you can change `target` to point to that.
374- You can also change the [load `phase`](https://artillery.io/docs/script-reference/#load-phases) and [`scenarios` block](https://artillery.io/docs/script-reference/#scenarios) as per your need. We recommend using a low load to try the tool first.
375
376### 5. Setup AWS account credentials
377Make sure you have [setup your AWS account credentials](#before-running-serverless-artillery) before proceeding.
378
379### 6. Deploy assets to AWS
380This section is same as before. See [here](#3-deploy) for details.
381
382### 7. Invoke performance test
383Now you are all set to invoke performance test using following command.
384```
385slsart invoke --stage <your-unique-stage-name>
386```
387
388At the end of the test serverless-artillery will generate a report of the test. **Please note that this report is generated only for small load.** See [here](#providing-a-data-store-to-view-the-results-of-your-performance-test) for details.
389
390If you go to AWS Lambda console > find the `loadGenerator` Lambda corresponding to your stack > `Monitoring` tab > `Invocations` graph, you will see that the Lambda function was invoked to generate the load. You can also see the logs produced by the Lambda in CloudWatch Logs.
391
392**NOTE** that for performance testing, the command will take the `script.yml` from your local machine (and not the one deployed in AWS account) to run the performance test. Hence if you edit it on your local machine after deploying assets to AWS, you don't need to deploy again in order to run the performance test again. Also note that this is true only for performance test and acceptance test and not monitoring.
393
394### 8. Remove assets from AWS
395After the test is done, you can remove the assets from AWS using following command. If you are a **_Nordstrom_** engineer, please see the page titled **_`Serverless Artillery - Remove Instructions`_** in **Confluence** and follow the instructions there.
396```
397slsart remove --stage <your-unique-stage-name>
398```
399
400## Tutorial 3: Performance test with custom deployment assets
401
402Throughout this tutorial we will walk you towards performance testing the AWS website, https://aws.amazon.com/.
403
404We would test with our _custom_ script and _custom_ deployment assets.
405
406### 1. Create new directory
407Start by creating a new directory for this tutorial and go to that directory in command line.
408
409### 2. Create `script.yml`
410This section is same as before. See [here](#2-create-scriptyml) for details.
411
412### 3. Understanding `script.yml`
413This section is same as before. See [here](#3-understanding-scriptyml) for details.
414
415### 4. Customizing `script.yml`
416This section is same as before. See [here](#4-customizing-scriptyml) for details.
417
418### 5. Create custom deployment assets
419Create a _local copy_ of the deployment assets for your customization and then deployment to AWS, using following command. The command generates a local copy of the load generator lambda function code (along with other assets) that can be edited and deployed with your changed settings if needed. It also runs `npm install` after creating local copy of the deployment assets.
420```
421slsart configure
422```
423The important files among other files created by this command are as follows.
424
425|File|Description|
426|:----|:----------|
427|`package.json`|Node.js dependencies for the load generator Lambda. Add Artillery.io plugins you want to use here.|
428|`serverless.yml`|Serverless-artillery's service definition/configuration using Serverless Framework. Change AWS-specific settings here.|
429|`handler.js`|Load generator Lambda code. **EDIT AT YOUR OWN RISK.**|
430
431**Note** that everytime you make changes to these local copy of deployment assets or `serverless.yml` file, you need to redeploy using `slsart deploy` command.
432
433**Note** that if you change `package.json` then you need to run `npm install` and then redeploy using `slsart deploy` command.
434
435### 6. Understanding `serverless.yml`
436`serverless.yml` contains serverless-artillery's service definition/configuration using Serverless Framework.
437
438Open `serverless.yml` with your favorite editor to see what it contains.
439<details><summary>Click to expand/collapse</summary>
440<p>
441
442```
443# We're excited that this project has provided you enough value that you are looking at its code!
444#
445# This is a standard [Serverless Framework](https://www.serverless.com) project and you should
446# feel welcome to customize it to your needs and delight.
447#
448# If you do something super cool and would like to share the capability, please open a PR against
449# https://www.github.com/Nordstrom/serverless-artillery
450#
451# Thanks!
452
453# If the following value is changed, your service may be duplicated (this value is used to build the CloudFormation
454# Template script's name)
455service: serverless-artillery-XnBa473psJ
456
457provider:
458 name: aws
459 runtime: nodejs8.10
460 iamRoleStatements:
461 # This policy allows the function to invoke itself which is important if the script is larger than a single
462 # function can produce
463 - Effect: 'Allow'
464 Action:
465 - 'lambda:InvokeFunction'
466 Resource:
467 'Fn::Join':
468 - ':'
469 -
470 - 'arn:aws:lambda'
471 - Ref: 'AWS::Region'
472 - Ref: 'AWS::AccountId'
473 - 'function'
474 - '${self:service}-${opt:stage, self:provider.stage}-loadGenerator*' # must match function name
475 # This policy allows the function to publish notifications to the SNS topic defined below with logical ID monitoringAlerts
476 - Effect: 'Allow'
477 Action:
478 - 'sns:Publish'
479 Resource:
480 Ref: monitoringAlerts # must match the SNS topic's logical ID
481functions:
482 loadGenerator: # !!Do not edit this name!!
483 handler: handler.handler # the serverlessArtilleryLoadTester handler() method can be found in the handler.js source file
484 timeout: 300 # set timeout to be 5 minutes (max for Lambda)
485 environment:
486 TOPIC_ARN:
487 Ref: monitoringAlerts
488 TOPIC_NAME:
489 'Fn::GetAtt':
490 - monitoringAlerts
491 - TopicName
492 events:
493 - schedule:
494 name: '${self:service}-${opt:stage, self:provider.stage}-monitoring' # !!Do not edit this name!!
495 description: The scheduled event for running the function in monitoring mode
496 rate: rate(1 minute)
497 ########################################################################################################################
498 ### !! BEFORE ENABLING... !!!
499 ### 0. Change `'>>': script.yml` below to reference the script you want to use for monitoring if that is not its name.
500 ### The script must be in this directory or a subdirectory.
501 ### 1. Modify your `script.yml` to provide the details of invoking every important surface of your service, as per
502 ### https://artillery.io/docs
503 ### 2. Add a `match` clause to your requests, specifying your expectations of a successful request. This relatively
504 ### undocumented feature is implemented at: https://github.com/shoreditch-ops/artillery/blob/82bdcdfc32ce4407bb197deff2cee13b4ecbab3b/core/lib/engine_util.js#L318
505 ### We would welcome the contribution of a plugin replacing this as discussed in https://github.com/Nordstrom/serverless-artillery/issues/116
506 ### 3. Modify the `monitoringAlerts` SNS Topic below, uncommenting `Subscription` and providing subscriptions for any
507 ### alerts that might be raised by the monitoring function. (To help you out, we've provided commented-out examples)
508 ### (After all, what good is monitoring if noone is listening?)
509 ### 4. Deploy your new assets/updated service using `slsart deploy`
510 ### 5. [As appropriate] approve the subscription verifications for the SNS topic that will be sent following its creation
511 ########################################################################################################################
512 enabled: false
513 input:
514 '>>': script.yml
515 mode: monitoring
516resources:
517 Resources:
518 monitoringAlerts: # !!Do not edit this name!!
519 Type: 'AWS::SNS::Topic'
520 Properties:
521 DisplayName: '${self:service} Monitoring Alerts'
522# Subscription: # docs at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-subscription.html
523# - Endpoint: http://<host>/<path> # the endpoint is an URL beginning with "http://"
524# Protocol: http
525# - Endpoint: https://<host>/<path> # the endpoint is a URL beginning with "https://"
526# Protocol: https
527# - Endpoint: <target>@<host> # the endpoint is an email address
528# Protocol: email
529# - Endpoint: <target>@<host> # the endpoint is an email address
530# Protocol: email-json
531# - Endpoint: <phone-number> # the endpoint is a phone number of an SMS-enabled device
532# Protocol: sms
533# - Endpoint: <sqs-queue-arn> # the endpoint is the ARN of an Amazon SQS queue
534# Protocol: sqs
535# - Endpoint: <endpoint-arn> # the endpoint is the EndpointArn of a mobile app and device.
536# Protocol: application
537# - Endpoint: <lambda-arn> # the endpoint is the ARN of an AWS Lambda function.
538# Protocol: lambda
539```
540
541</p>
542</details>
543
544Please refer to [`serverless.yml` documentation](https://serverless.com/framework/docs/providers/aws/guide/serverless.yml/) for details. It defines assets needed for monitoring (turned off by default) as well which we will discuss later.
545#### a. Service name
546- In above `serverless.yml` the `service` name is set to `serverless-artillery-XnBa473psJ`. In your `serverless.yml` the string at the end (`XnBa473psJ`) would be different.
547- This will be the AWS CloudFormation stack name when you run `slsart deploy`. Format of the AWS CloudFormation stack name would be `<service-name default:serverless-artillery>-<stage-name default:dev>`.
548 - If you specify the optional stage name with the deploy command, i.e. `slsart deploy --stage <your-unique-stage-name>`, then the AWS CloudFormation stack name would be `<service-name default:serverless-artillery>-<your-unique-stage-name>`
549- The `slsart configure` command adds a random string at the end of the `service` name so you get a unique stack name that does not conflict with anyone else also deploying to the same AWS account, in case you were to not specify the optional stage name with the deploy command.
550- You can change `service` name to some other unique string as per your need. For example, `serverless-artillery-myperftestservice` or `myloadtestservice`.
551- The rest of the `serverless.yml` refers to the service name by using `${self:service}`.
552
553#### b. [Load generator Lambda function](#load-generator-lambda-function-on-aws) name
554The Serverless Framework automatically names the Lambda function based on the service, stage and function name as follows.
555- The function `loadGenerator` when deployed is named as `${self:service}-${opt:stage, self:provider.stage}-loadGenerator`.
556 - `${self:service}` is name of the service. In this `serverless.yml` it is `serverless-artillery-XnBa473psJ`.
557 - `${opt:stage, self:provider.stage}` will either use `${opt:stage}` or `${self:provider.stage}`.
558 - `${opt:stage}` refers to the (optional) stage name passed in `slsart deploy [--stage <stage-name>]` command. For example, if you run `slsart deploy --stage prod` then `prod` would be used for `${opt:stage}`.
559 - If no stage name is passed in the deploy command then `${self:provider.stage}` would be used. It is the `stage` name set under `provider` block in the `serverless.yml`. If one is not provided (like in above example) it is set to `dev`. See [here](https://serverless.com/framework/docs/providers/aws/guide/serverless.yml/).
560- In this example function name will be set to `serverless-artillery-XnBa473psJ-dev-loadGenerator` while running `slsart deploy` command (note no stage name specified).
561#### c. [Load generator Lambda function](#load-generator-lambda-function-on-aws) permissions
562- In order to generate load the load generator Lambda needs to invoke itself.
563- The `iamRoleStatements` block in the `serverless.yml` gives the load generator Lambda function to invoke itself (`lambda:InvokeFunction`).
564
565### 7. Customizing `serverless.yml`
566**NOTE:** Except for [one step for **_Nordstrom_** Engineers](#a-customization-for-nordstrom-engineers), all customizations are **optional** in the tutorial.
567
568If you like you can customize `serverless.yml` as follows.
569
570#### a. Customization for Nordstrom Engineers
571If you are a **_Nordstrom_** engineer, please see the page titled **_`Serverless Artillery - Nordstrom Technology Policies`_** in **Confluence** and follow the instructions there.
572
573#### b. Service name
574- You can change `service` name to some other unique string as per your need.
575- For example, `serverless-artillery-myperftestservice` or `myloadtestservice`.
576- Format of the AWS CloudFormation stack name would be `<service-name default:serverless-artillery>-<stage-name default:dev>` after you deploy.
577
578#### c. Plugins
579You can customize the `serverless.yml` to use required tools/plugins mentioned [below](#related-tools-and-plugins).
580
581##### i. CloudWatch plugin
582In this tutorial you can add [artillery-plugin-cloudwatch](https://github.com/Nordstrom/artillery-plugin-cloudwatch) to record test results to [AWS CloudWatch](https://aws.amazon.com/cloudwatch).
5831. To allow the Lambda code to write to CloudWatch, the correct NPM package dependency must be added. This modifies the package.json file to include the necessary dependency.
584```
585npm install --save artillery-plugin-cloudwatch
586```
587
5882. In `script.yml`, at the end of the `config` block (which already exists)
589```
590config:
591```
592add CloudWatch plugin as follows:
593```
594 plugins:
595 cloudwatch:
596 namespace: "<cloud-watch-namespace>"
597```
598For example, you can use
599```
600 namespace: "serverless-artillery-myperftestservice-loadtest"
601```
602
6033. In `serverless.yml`, at the end of the following block (which already exists)
604```
605provider:
606 iamRoleStatements:
607```
608add the following:
609```
610 - Effect: 'Allow'
611 Action:
612 - 'cloudwatch:PutMetricData'
613 Resource:
614 - '*'
615```
616##### ii. Datadog plugin
617In this tutorial you can add [artillery-plugin-datadog](https://www.npmjs.com/package/artillery-plugin-datadog) to record test results to [Datadog](https://www.datadoghq.com/).
618
6191. To allow the Lambda code to write to Datadog, the correct NPM package dependency must be added. This modifies the package.json file to include the necessary dependency.
620```
621npm install --save artillery-plugin-datadog
622```
623
6242. Update the `config` portion of `script.yml` to add Datadog plugin as follows and customize the `host`, `prefix` and `tags` as per your requirement.
625```
626config:
627 plugins:
628 datadog:
629 # Custom hostname (leave blank if not desired)
630 host: ''
631 # Custom metric prefix (example, to 'serverless-artillery')
632 prefix: 'serverless-artillery'
633 # Additional tags for all metrics
634 tags:
635 - 'mode:test'
636```
637
6383. In `serverless.yml`, under `provider` section specify Datadog API key as an environment variable as follows. **NOTE** that you should not save sensitive information like Datadog API Key in plain text in a source control. Below is just for the tutorial.
639```
640provider:
641 environment:
642 DATADOG_API_KEY: "<your-datadog-api-key>"
643```
644
645### 8. Setup AWS account credentials
646This section is same as before. See [here](#before-running-serverless-artillery) for details.
647
648### 9. Deploy assets to AWS
649This section is same as before. See [here](#3-deploy) for details.
650
651You can go to your AWS account console > CloudFormation, and see AWS stack `<service-name default:serverless-artillery>-<stage-name default:dev>` created there depending on the customizations explained in the steps above.
652
653### 10. Invoke performance test
654This section is same as before. See [here](#7-invoke-performance-test) for details.
655
656If you used CloudWatch/Datadog plugins you will be able to view the metrics on the CloudWatch/Datadog dashboard. You can learn more about using CloudWatch dashboard [here](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html). **Note that it can take few minutes for the data to propogate to CloudWatch/Datadog.**
657
658### 11. Remove assets from AWS
659This section is same as before. See [here](#8-remove-assets-from-aws) for details.
660
661## Tutorial 4: Killing in-progress performance test
662While running performance/load test it is sometimes necessary to kill the test before it is complete. Read more about the [kill command](#killing-in-progress-performance-test).
663
664### 1. Increase `duration`
665If you are a **_Nordstrom_** engineer, please follow [Tutorial 3](#tutorial-3-performance-test-with-custom-deployment-assets) to create custom script and custom deployment assets. Make sure you do [customization for Nordstrom Engineers](#a-customization-for-nordstrom-engineers). Other optional customizations are not necessary for this tutorial.
666
667Others can follow [Tutorial 2](#tutorial-2-performance-test-with-custom-script) to create custom `script.yml`.
668
669Edit `script.yml` in your favorite editor and increase the `duration` to `60` seconds.
670
671### 2. Setup AWS account credentials
672This section is same as before. See [here](#before-running-serverless-artillery) for details.
673
674### 3. Deploy assets to AWS
675This section is same as before. See [here](#3-deploy) for details.
676
677### 4. Invoke performance test
678This section is same as before. See [here](#7-invoke-performance-test) for details.
679
680### 5. Kill the in-progress performance test
681Run the following command to kill the performance test. Read more about the kill command [here](#killing-in-progress-performance-test). **Note** that _kill_ command will also _remove_ the deployed assets. Hence running `slsart remove` after this is not needed.
682```
683slsart kill --stage <your-unique-stage-name> --region=<region-used-for-deploy>
684```
685
686You must specify a `region` when running this command:
687- Use `--region` option, e.g. `--region=us-east-1`
688- or set AWS_REGION in environment, e.g. `AWS_REGION=us-east-1`
689- or configure a default region using the guide below.
690Serverless will use the `us-east-1` region by default.
691
692### 6. Wait before re-deploying
693Wait for ~5 minutes before re-deploying to let the Lambda invocation queue drain.
694
695## Performance test workshop
696We've created a workshop detailing end-to-end usage of serverless-artillery for performance testing. Check out our conference-style [workshop](https://github.com/Nordstrom/serverless-artillery-workshop) for step by step lessons on how to set your system up for successful deployment, invocation, and removal.
697
698## Other commands and use cases
699### Killing in-progress performance test
700While running performance/load test it is sometimes necessary to kill the test before it is complete. For example, it might be done when the test target is not able to handle the current load and you want to stop the test before the service goes down.
701
702You can run the following command to kill the performance test.
703```
704slsart kill --stage <your-unique-stage-name> --region=<region-used-for-deploy>
705```
706You must specify a `region` when running this command:
707- Use `--region` option, e.g. `--region=us-east-1`
708- or set AWS_REGION in environment, e.g. `AWS_REGION=us-east-1`
709- or configure a default region using the guide below.
710Serverless will use the `us-east-1` region by default.
711
712The command will do the followings:
713- It will set the load generator Lambda function's [concurrency level](https://docs.aws.amazon.com/lambda/latest/dg/concurrent-executions.html#per-function-concurrency) to 0.
714- and then _remove_ the deployed assets. It will remove load generator Lambda function, CloudWatch logs, and IAM role. CloudWatch metrics will remain.
715
716Result:
717- Any further invocations of load generator Lambda will be supressed.
718- The already executing instances of load generator Lambda will continue and complete the assigned load generation workload.
719- The load generator Lambda function by default runs for up to 2 minutes. So that would be the default maximum time before the load generation stops.
720
721**You will want to wait approximately 5 minutes before redeploying to avoid the killed performance test from resuming.** Behind the scenes, AWS creates a queue for Lambda invocations. While processing the invocation requests from the queue, if a function is not available then that message will be placed back onto the queue for further attempts. As a result, redeploying your function can allow those re-queued messages to be used to invoke your re-deployed function. In our observation based on a limited set of tests, messages will be permanently failed out of the queues after 5 minutes. That is the basis of our recommendation.
722
723The default maximum duration of a [script chunk](#splitting) is 2 minutes (`maxChunkDurationInSeconds`). As a result of this, on average, load will not be produced after 1 minute but it could continue for up to the full 2 minutes. To lower the wait times after killing, this value can be overridden in your `script.yml` within the \_split attribute, as shown [here](#script-splitting-customization). This value can be as low as 15 seconds and using this value causes each script chunk to run for a maximum duration of 15 seconds. Theoretically, this means that you’d only have to wait 7.5 seconds on average for tests to stop running after killing your test (in practice we have observed roughly 20 seconds lag between killing a function and termination of invocations).
724
725### Create customized `script.yml`
726Above you used how to use `slsart script` to create the default `script.yml` (see [here](#2-create-scriptyml)) and how to customize it by manually editing it (see [here](#4-customizing-scriptyml)).
727
728`slsart script` command has options to quickly do the above in one command. Run the following command to create custom `script.yml` with **one** load `phase`.
729```
730slsart script -e <your-target-endpoint> -d <duration-in-sec> -r <arrival-rate-in-virtual-users-arriving-per-second> -t <ramp-to-in-virtual-users-arriving-per-second>
731```
732
733For example, following command will create a `script.yml` with test target https://example.com, performance test starting with 10 requests per second, and scaling up to 25 requests per second, over a duration of 60 seconds.
734```
735slsart script -e https://example.com -d 60 -r 10 -t 25
736```
737
738For more details see
739```
740slsart script --help
741```
742
743### Performance test using script file with different name/path
744The `slsart script` command by default gives the file name `script.yml`. If you want to give a different name to your `yml` file then you can use the `-o` option of the `slsart script` command. See`slsart script --help` for more details.
745```
746slsart script -o <preferred-filename.yml>
747```
748Example,
749```
750slsart script -o myservicetests.yml
751```
752
753By default `slsart invoke` command will look for `script.yml` under the local folder to run performance test. You can use `-p` option to specify script file with different name/path as follows.
754```
755slsart invoke -p <path-to-your-script-file>
756```
757For example, following command will *invoke* performance test using the specified file.
758```
759slsart invoke -p /my/path/to/myotherscript.yml
760```
761
762For more options see,
763```
764slsart invoke --help
765```
766
767### Reserved and unsupported flags
768`slsart` commands support most commandline flags of the corresponding `sls` (Serverless Framework) commands.
769#### Reserved flags
770Following flags are reserved in `slsart invoke` command.
771- The flags `-t`, `--type`, `-f`, and `--function` are reserved for `serverless-artillery` use. They cannot be supplied on the command line.
772- The `-t` and `--type` flags are reserved because the tool uses the script you provide it to cacluate whether an `Event` or `RequestResponse` invocation type is more appropriate. If that argument was supplied, a user might have an expectation-behavior mismatch.
773- The `-f` and `--function` flags are reserved because a part of the value that `serverless-artillery` provides is the automated definition of the function providing load testing and thereby a necessarily strong opinion of the name that function was given.
774#### Unsupported flags
775The flag `--raw` is unsupported in `slsart invoke` command because, while arbitrary functions can accept strings, a string does not comprise a valid artillery script.
776
777### Providing a data store to view the results of your performance test
778- If your script specifies a small load that can be generated by single invocation of [load generator Lambda function](#load-generator-lambda-function-on-aws) then the results are reported back at the end of `slsart invoke` command.
779- Otherwise, the volume of load results can be such that it cannot pass back to the original requestor.
780- You are responsible for sending the results (usually via a plugin) to a data store for later review and/or analysis. See the [available plugins](#related-tools-and-plugins) that can be used.
781
782### Related tools and plugins
783You would need to [create custom deployment assets](#tutorial-3-performance-test-with-custom-deployment-assets) and customize `serverless.yml` to use a plugin as shown in the examples [here](#c-plugins).
784
785|Plugin|Description|
786|:----|:----------|
787|[artillery-plugin-aws-sigv4](https://github.com/Nordstrom/artillery-plugin-aws-sigv4)|for testing against an authenticated AWS API Gateway endpoint.|
788|[artillery-plugin-influxdb](https://github.com/Nordstrom/artillery-plugin-influxdb)|to record test results to InfluxDB.|
789|[artillery-plugin-cloudwatch](https://github.com/Nordstrom/artillery-plugin-cloudwatch)|to record test results to AWS CloudWatch.|
790|[artillery-plugin-datadog](https://www.npmjs.com/package/artillery-plugin-datadog)|to record test results to DataDog.|
791|[serverless-attach-managed-policy](https://www.npmjs.com/package/serverless-attach-managed-policy)|if you have automatic IAM role modification in your corporate/shared AWS account.|
792
793### Performance testing VPC hosted services
794The default deployment assets (used in [Tutorial 1](#tutorial-1-run-a-quick-performance-test) and [Tutorial 2](#tutorial-2-performance-test-with-custom-script)) of serverless-artillery are not deployed in a VPC and hence it can only successfully send requests to public endpoints. If your service is hosted in VPC (i.e. service is internal and does not have public endpoint), you would need to use [custom deployment assets](#tutorial-3-performance-test-with-custom-deployment-assets).
795
796Please refer to Serverless Frameworks's [doc](https://serverless.com/framework/docs/providers/aws/guide/functions/#vpc-configuration) to understand how to customize `serverless.yml` to deploy the customized assets to VPC.
797
798You need to add following section to your `serverless.yml` and add appropriate `securityGroupIds` and `subnetIds`.
799```
800provider:
801 name: aws
802 vpc:
803 securityGroupIds:
804 - securityGroupId1
805 - securityGroupId2
806 subnetIds:
807 - subnetId1
808 - subnetId2
809```
810
811### Using Payload/CSV files to inject data in scenarios of your `script.yml`
812- For some scenarios it can be useful to pass different information (example, user ID and password, search term) in the requests sent. Artillery.io allows you to use payload file to accomplish that. Please refer to Artillery.io's [doc](https://artillery.io/docs/script-reference/#payload-files) to understand how to customize `script.yml` to use payload/CSV files.
813- You would need to use [custom deployment assets](#tutorial-3-performance-test-with-custom-deployment-assets) to use payload files in serverless-artillery.
814- The payload/CSV files should be under the same directory as `serverless.yml`.
815- Payload files are deployed with the load generator Lambda. You would need to redeploy everytime it is changed (unlike `script.yml`).
816- **Payload file size limitation**
817 - As mentioned above, payload files are deployed with load generator Lambda.
818 - AWS Lambda poses a limitation on how large of a payload file can be deployed with it. See [here](https://docs.aws.amazon.com/lambda/latest/dg/limits.html)
819 - Artillery.io allows the script to read from payload files in `random` or `sequence` `order`. For that it loads the entire payload file in memory. Hence Lambda memory size limitation would also determine how large of a payload file can be used.
820 - If your payload file is too large, you may need to write some custom code (i.e. write a custom processor or modify the serverless-artillery codebase) that will retrieve the data from S3 for you prior to the execution of any load.
821
822### Advanced customization use cases
823#### Deployment assets and settings customization
824- Above we discussed how you need to use [custom deployment assets](#tutorial-3-performance-test-with-custom-deployment-assets) and [`slsart configure` command] (#5-create-custom-deployment-assets) when your testing needs are not met by the default deployment assets that are used in [Tutorial 1](#tutorial-1-run-a-quick-performance-test) and [Tutorial 2](#tutorial-2-performance-test-with-custom-script).
825- For example,
826 - when the endpoints you need to test are in the VPC. See [here](#performance-testing-vpc-hosted-services) for details.
827 - when you need to view the results in your data store. See [here](#providing-a-data-store-to-view-the-results-of-your-performance-test) for details.
828 - when you need to automatically attach an AWS Managed IAM Policy (or Policies) to all IAM Roles created by serverless-artillery due to company policy. See `serverless-attach-managed-policy` plugin [here](#related-tools-and-plugins) for details.
829 - when you need to separate out various versions of the load testing function in order to maintain least privilege.
830 - when you want to use payload/CSV files to feed data into the request being sent to the target. See [here](#using-payloadcsv-files-to-inject-data-in-scenarios-of-your-scriptyml) for details.
831 - when you want to add custom IAM rights (see Serverless Framework [docs](https://serverless.com/framework/docs/providers/aws/guide/iam/)) to the load generator Lambda to validate least privilege.
832- For such cases you need to create a local copy of the deployment assets using [`slsart configure` command](#5-create-custom-deployment-assets), customize them for your use case and deploy them using `slsart deploy` command as shown in [Tutorial 3](#tutorial-3-performance-test-with-custom-deployment-assets).
833- Full documentation of what is in the `serverless.yml` and the options you have available can be found at https://serverless.com/framework/docs/.
834- You would need to use custom deployment assets when you want to make even more customizations to how serverless-artillery works. [`slsart configure` command](#5-create-custom-deployment-assets) generates a local copy of the serverless function code that can be edited and redeployed with your changed settings. For example, if you need to make any code change to load generator Lambda (example, alter hard-coded limits).
835- Please see [Serverless Framework docs](https://serverless.com/framework/docs/providers/aws/) for load generation Lambda function's configuration related documentation.
836- Please see [Artillery.io docs](https://artillery.io/docs/script-reference/) for script configuration related documentation.
837- **Note** that everytime you make changes to the local copy of deployment assets, you need to redeploy using `slsart deploy` command.
838
839#### Test script and execution customization using Artillery.io
840- The test script, `script.yml`, allows you to add plugins for various capabilities. For example,
841 - when you need to test against an authenticated AWS API Gateway endpoint. See `artillery-plugin-aws-sigv4` plugin [here](#related-tools-and-plugins) for details.
842 - when you need to view the results in your data store. See [here](#providing-a-data-store-to-view-the-results-of-your-performance-test) for details.
843- Also see [Artillery.io's plugin docs](https://github.com/artilleryio/artillery/blob/master/docs/plugins.md) about how to write your plugin.
844- You can also use payload/CSV files to feed data into the request being sent to the target. See [here](#using-payloadcsv-files-to-inject-data-in-scenarios-of-your-scriptyml) for details.
845- The HTTP engine has support for "hooks", which allow for custom JS functions to be called at certain points during the execution of a scenario. See [here](https://artillery.io/docs/http-reference/#advanced-writing-custom-logic-in-javascript) for details.
846
847#### Script splitting customization
848As mentioned [here](#load-generator-lambda-function-on-aws), the controller mode load generator Lambda function splits the work to generate the required load between multiple worker mode load generator Lambdas. The following controls are available to control how splitting is done. That said, the defaults are good and you generally won't need them until you have gotten deeper into implementation.
849To use these, define a `_split` attribute within your `script.yml`. The values of that object will be used to alter the splitting of your script.
850```
851{
852 _split: {
853 maxScriptDurationInSeconds: 86400, # Default listed. Hard-coded max is 518400
854 maxChunkDurationInSeconds: 120, # Default listed. Hard-coded max is 285, min is 15
855 maxScriptRequestsPerSecond: 5000, # Default listed. Hard-coded max is 50000
856 maxChunkRequestsPerSecond: 25, # Default listed. Hard-coded max is 500
857 timeBufferInMilliseconds: 15000, # Default listed. Hard-coded max is 30000
858 }
859 ...
860}
861```
862See the [Splitting and Distribution Logic Customization](#splitting-and-distribution-logic-customization) section for an in depth discussion of how splitting is implemented and what you control with these parameters as well as the concerns involved in making decisions about them. See the comments in [`~/lambda/handler.js`](lib/lambda/handler.js) for detailed documentation of the semantics the code has with regard to them (search for '`const constants`'). By the way, you now have the source code to change those hard-coded limits and can change them at will if you so desire - we wanted to provide a margin of safety and guardrails but not restrictions.
863
864#### Debugging and Tracing Behavior Customization
865There are two primary tools for debugging and tracing the load generator Lambda function and how it splits and executes the task it has been given. Define the following in your `script.yml`:
866```
867{
868 _trace: true,
869 _simulation: true,
870 ...
871}
872```
873
874##### `_trace`
875`_trace` causes the load generator Lambda function to report the actions it is taking with your script and the chunks that it breaks your script into. Expect statements such as this:
876```
877scheduling self invocation for 1234567890123 in 2345678901234 with a 3456789012345 ms delay
878```
879
880This would be produced by the following line in the source code:
881```
882console.log(`scheduling self invocation for ${event._genesis} in ${event._start} with a ${timeDelay} ms delay`);
883```
884
885Here are definitions that will help you understand these statements. In the code you will see `_genesis`, `_start`, `now`, and `timeDelay`:
886- `_genesis`: the datetime stamp immediately taken by the first instance of load generator Lambda function that received the original script. `_genesis` is added to the original script so that all child function executions of the original handler have a datetime stamp of when the original "load execution request" was received. If you are not running many load tests simultaneously then this can serve as a unique ID for the current load execution. This can be useful for correlation. An improvement could include adding a unique factor to avoid collisions in such usage.
887- `_start`: the datetime stamp immediately taken by the current function that is executing on either the original script or a chunk of that original script. This allows relative time reporting and evaluation with a function execution.
888- `now`: the datetime stamp taken when the log entry was produced.
889- `timeDelay`: a time delta (in milliseconds) between the current time of the current function and when it has scheduled to take the action reported in the current log entry.
890
891`_trace` is very useful in identifying what the system is doing or where something is going wrong. #bugs-happen
892
893##### `_simulation`
894Setting the `_simulation` attribute to a truthy value will cause the load generator Lambda function to split the script without taking action on the script. Functionally, this comprises splitting the given script into pieces without invoking functions to handle the split chunks and/or execute the load described by those chunks. Concretely, when it comes time to invoke new function instances for distributing the load, it simply invokes (or schedules an invokation of) itself. Likewise, when it comes time to invoke the `artillery` entry point for generator load from the chunk, it instead invokes the simulation shim that reports what would have been executed and immediately completes.
895
896This mode, in combination with `_trace` related behavior is very helpful in debugging script splitting behavior and identifying what the logic declares should occur.
897
898#### Splitting and Distribution Logic Customization
899You've got the code. Have at! Have fun and consider contributing improvements back into the tool. Thank you!
900
901Some helpful notions used in the code and discussion of them follows.
902##### Scripts
903An artillery script is composed of a number of phases which occur one after the other. Each of these phases has its own duration and maximum load. The duration is straightforwardly how long the phase lasts. The maximum load of the phase is the maximum Requests Per Second (RPS) that are declared for the entirety of that phase (e.g. a phase declaring a ramp up from 0 to 500 RPS has a maximum load of 500 RPS). Phases are declared in serial in order to provide warming or not as appropriate for the load testing scenario that interests you.
904
905The duration of the script is the sum of the durations of its phases. The maximum load of the script is the maximum RPS that any of its phases declares.
906
907##### Splitting
908The splitting of a script comprises taking "chunks" off of the script.
909
910First, we take chunks from the script by duration. This is driven by the maximum duration of the underlying function as a service (FaaS) provider that we are using. For AWS Lambda, this at the time of original implementation was 5 minutes (now 15 minutes). However, we need to allow for cold starts and as such must provide a buffer of time before we begin the execution of any specific load job. Following the execution of a load job, the artillery framework calculates a summary and invokes custom analyzers (via the plugin capabilities it offers). As a result, a tailing buffer is also needed to ensure execution can properly complete.
911
912The result is a script chunk that can be executed within the duration limited period the FaaS provider allows (no guarantees yet exist on whether a single function can execute the demanded load). This chunk will be called the script for referential simplicity. We also may have a remainder script that must be executed by a new function instance as the current splitting function nears its timeout.
913
914Next, we take chunks from the script by maximum load. This is driven by the maximum requests per second that a single execution of the underlying function as a service (FaaS) provider is capable of pushing with high fidelity. For AWS Lambda (with the default 1024 MB configuration), we found 25 RPS to be a good level. This is lower than the absolute ceiling that Lambda is capable of pushing for a reason. First, each connection will be a separate opened and closed socket. Second, if we are producing too many connections, we can be in the middle of making a request when we receive the response of a separate request. Given that this is implemented in NodeJS, we have one thread and that means the timestamping of the receipt of that response is artificially and incorrectly delayed. We found that at RPS above 25 we observed an increase in the volatility of observed latencies. That written, if you do not intend to record your latencies, then you could bump this up to the limit of the FaaS service (i.e. `_split.maxChunkRequestsPerSecond = 300` or so).
915
916The result is a script chunk that is less than the limited period and also executable by a single function instance. Therefore, we invoke a single function with the chunk to execute it.
917
918# Acceptance mode
919Find defects before performance testing! Acceptance mode runs each scenario/flow in your script exactly once and reports the results. For example, you can run your script in acceptance mode in your CI/CD to ensure that merges don't break the scenarios in your script.
920
921Performance testing framework forms the basis of acceptance mode of serverless-artillery. Hence please go through [performance mode](#performance-mode-performanceload-testing) section before proceeding.
922
923## `match` clause
924Ensure that you have `match` clauses defined for each request in your script's flows to validate the responses. You can read about how to use `match` in [Artillery.io docs](https://artillery.io/docs/http-reference/?#extracting-and-reusing-parts-of-a-response-request-chaining) and ["official" docs](https://github.com/shoreditch-ops/artillery/blob/master/core/lib/engine_util.js#L318). Also see, [serverless-artillery issue #116](https://github.com/Nordstrom/serverless-artillery/issues/116).
925
926## Acceptance test command
927When `-a` option is used in `slsart invoke` command, serverless-artillery invokes the load generator Lambda in acceptance mode.
928```
929slsart invoke -a
930```
931Expect a non-zero exit code if a match clause fails.
932
933## Tutorial 5: Acceptance mode
934### 1. Customize `script.yml`
935Follow [Tutorial 2 to create custom `script.yml`](#tutorial-2-performance-test-with-custom-script) and customize your `script.yml` by copy pasting the following content in it. Note the `match` clauses.
936
937```
938# Thank you for trying serverless-artillery!
939# This default script is intended to get you started quickly.
940# There is a lot more that Artillery can do.
941# You can find great documentation of the possibilities at:
942# https://artillery.io/docs/
943config:
944 # this hostname will be used as a prefix for each URI in the flow unless a complete URI is specified
945 target: "https://postman-echo.com/headers"
946 phases:
947 -
948 duration: 1
949 arrivalRate: 1
950 defaults:
951 headers:
952 my-sample-header: "my-sample-header-value"
953scenarios:
954 -
955 flow:
956 -
957 get:
958 url: "/"
959 match:
960 - json: "$.headers.my-sample-header"
961 value: "my-sample-header-value"
962 #value: "failvalue"
963 - json: "$.headers.host"
964 value: "postman-echo.com"
965 #value: "failvalue"
966 - json: "$.headers.x-forwarded-proto"
967 value: "https"
968 #value: "failvalue"
969```
970
971The script is using target `https://postman-echo.com/headers` which at the time of writing this document is designed to return JSON response with headers that are passed in the request.
972
973Run the following to try that out.
974```
975curl --location --request GET "https://postman-echo.com/headers" --header "my-sample-header: my-sample-header-value"
976```
977
978The JSON response will be as follows.
979```
980{
981 "headers": {
982 "x-forwarded-proto": "https",
983 "host": "postman-echo.com",
984 "accept": "*/*",
985 "my-sample-header": "my-sample-header-value",
986 "user-agent": "curl/7.54.0",
987 "x-forwarded-port": "443"
988 }
989}
990```
991
992The `match` clauses check if the return value is same as what is expected.
993
994### 2. Setup AWS account credentials
995This section is same as before. See [here](#before-running-serverless-artillery) for details.
996
997### 3. Deploy assets to AWS
998This section is same as before. See [here](#3-deploy) for details.
999
1000**Note** that you don't need to _deploy_ the assets everytime `script.yml` changes.
1001
1002### 4. Invoke acceptance test
1003Run following command to run acceptance test.
1004```
1005slsart invoke -a --stage <your-unique-stage-name>
1006```
1007
1008### 5. Observe the results
1009You will see an output similar to the following.
1010<details><summary>Click to expand/collapse</summary>
1011<p>
1012
1013```
1014
1015 Invoking test Lambda
1016
1017{
1018 "errors": 0,
1019 "reports": [
1020 {
1021 "timestamp": "2019-04-17T21:40:59.127Z",
1022 "scenariosCreated": 1,
1023 "scenariosCompleted": 1,
1024 "requestsCompleted": 1,
1025 "latency": {
1026 "min": 26.6,
1027 "max": 26.6,
1028 "median": 26.6,
1029 "p95": 26.6,
1030 "p99": 26.6
1031 },
1032 "rps": {
1033 "count": 1,
1034 "mean": 2.7
1035 },
1036 "scenarioDuration": {
1037 "min": 177.8,
1038 "max": 177.8,
1039 "median": 177.8,
1040 "p95": 177.8,
1041 "p99": 177.8
1042 },
1043 "scenarioCounts": {
1044 "0": 1
1045 },
1046 "errors": {},
1047 "codes": {
1048 "200": 1
1049 },
1050 "matches": 3,
1051 "customStats": {},
1052 "phases": [
1053 {
1054 "pause": 0.2430741319294641
1055 },
1056 {
1057 "duration": 1,
1058 "arrivalRate": 1
1059 }
1060 ]
1061 }
1062 ],
1063 "totals": {
1064 "scenariosCreated": 1,
1065 "scenariosCompleted": 1,
1066 "requestsCompleted": 1,
1067 "codes": {
1068 "200": 1
1069 },
1070 "errors": {}
1071 }
1072}
1073
1074 Your function invocation has completed.
1075
1076{
1077 "errors": 0,
1078 "reports": [
1079 {
1080 "timestamp": "2019-04-17T21:40:59.127Z",
1081 "scenariosCreated": 1,
1082 "scenariosCompleted": 1,
1083 "requestsCompleted": 1,
1084 "latency": {
1085 "min": 26.6,
1086 "max": 26.6,
1087 "median": 26.6,
1088 "p95": 26.6,
1089 "p99": 26.6
1090 },
1091 "rps": {
1092 "count": 1,
1093 "mean": 2.7
1094 },
1095 "scenarioDuration": {
1096 "min": 177.8,
1097 "max": 177.8,
1098 "median": 177.8,
1099 "p95": 177.8,
1100 "p99": 177.8
1101 },
1102 "scenarioCounts": {
1103 "0": 1
1104 },
1105 "errors": {},
1106 "codes": {
1107 "200": 1
1108 },
1109 "matches": 3,
1110 "customStats": {},
1111 "phases": [
1112 {
1113 "pause": 0.2430741319294641
1114 },
1115 {
1116 "duration": 1,
1117 "arrivalRate": 1
1118 }
1119 ]
1120 }
1121 ],
1122 "totals": {
1123 "scenariosCreated": 1,
1124 "scenariosCompleted": 1,
1125 "requestsCompleted": 1,
1126 "codes": {
1127 "200": 1
1128 },
1129 "errors": {}
1130 }
1131}
1132Results:
1133PASSED
1134```
1135
1136</p>
1137</details>
1138
1139You can observe the following in the result:
1140- Observe the following section where we list the number of scenarios created, scenarios completed, requests completed and list of errors which in this case is 0.
1141```
1142 "totals": {
1143 "scenariosCreated": 1,
1144 "scenariosCompleted": 1,
1145 "requestsCompleted": 1,
1146 "codes": {
1147 "200": 1
1148 },
1149 "errors": {}
1150```
1151
1152Also, as this test passed, you will also observe that the process exit code is 0. On _Mac_ you can run command `echo $?` immediately after that to see the process exit code 0 in this case.
1153
1154### 6. Test failure scenario
1155#### 6.1. Edit `script.yml` to fail `match`
1156Edit `match` section in `script.yml` to look for wrong return value to simulate failure scenario. Note that we are causing failure for two matches out of three.
1157```
1158 match:
1159 - json: "$.headers.my-sample-header"
1160 value: "my-sample-header-value"
1161 #value: "failvalue"
1162 - json: "$.headers.host"
1163 #value: "postman-echo.com"
1164 value: "failvalue"
1165 - json: "$.headers.x-forwarded-proto"
1166 #value: "https"
1167 value: "failvalue"
1168```
1169#### 6.2. Invoke acceptance test
1170Invoke acceptance test as mentioned [above](#4-invoke-acceptance-test).
1171
1172#### 6.3. Observe the results
1173You will see an output similar to the following.
1174<details><summary>Click to expand/collapse</summary>
1175<p>
1176
1177```
1178
1179 Invoking test Lambda
1180
1181{
1182 "errors": 2,
1183 "reports": [
1184 {
1185 "timestamp": "2019-04-17T21:56:59.527Z",
1186 "scenariosCreated": 1,
1187 "scenariosCompleted": 0,
1188 "requestsCompleted": 1,
1189 "latency": {
1190 "min": 24.7,
1191 "max": 24.7,
1192 "median": 24.7,
1193 "p95": 24.7,
1194 "p99": 24.7
1195 },
1196 "rps": {
1197 "count": 1,
1198 "mean": 2
1199 },
1200 "scenarioDuration": {
1201 "min": null,
1202 "max": null,
1203 "median": null,
1204 "p95": null,
1205 "p99": null
1206 },
1207 "scenarioCounts": {
1208 "0": 1
1209 },
1210 "errors": {
1211 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 1,
1212 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 1
1213 },
1214 "codes": {
1215 "200": 1
1216 },
1217 "matches": 0,
1218 "customStats": {},
1219 "phases": [
1220 {
1221 "pause": 0.29122591362828076
1222 },
1223 {
1224 "duration": 1,
1225 "arrivalRate": 1
1226 }
1227 ]
1228 }
1229 ],
1230 "totals": {
1231 "scenariosCreated": 1,
1232 "scenariosCompleted": 0,
1233 "requestsCompleted": 1,
1234 "codes": {
1235 "200": 1
1236 },
1237 "errors": {
1238 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 1,
1239 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 1
1240 }
1241 },
1242 "errorMessage": "acceptance failure: scenarios run: 1, total errors: 2, error budget: 0"
1243}
1244
1245 Your function invocation has completed.
1246
1247{
1248 "errors": 2,
1249 "reports": [
1250 {
1251 "timestamp": "2019-04-17T21:56:59.527Z",
1252 "scenariosCreated": 1,
1253 "scenariosCompleted": 0,
1254 "requestsCompleted": 1,
1255 "latency": {
1256 "min": 24.7,
1257 "max": 24.7,
1258 "median": 24.7,
1259 "p95": 24.7,
1260 "p99": 24.7
1261 },
1262 "rps": {
1263 "count": 1,
1264 "mean": 2
1265 },
1266 "scenarioDuration": {
1267 "min": null,
1268 "max": null,
1269 "median": null,
1270 "p95": null,
1271 "p99": null
1272 },
1273 "scenarioCounts": {
1274 "0": 1
1275 },
1276 "errors": {
1277 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 1,
1278 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 1
1279 },
1280 "codes": {
1281 "200": 1
1282 },
1283 "matches": 0,
1284 "customStats": {},
1285 "phases": [
1286 {
1287 "pause": 0.29122591362828076
1288 },
1289 {
1290 "duration": 1,
1291 "arrivalRate": 1
1292 }
1293 ]
1294 }
1295 ],
1296 "totals": {
1297 "scenariosCreated": 1,
1298 "scenariosCompleted": 0,
1299 "requestsCompleted": 1,
1300 "codes": {
1301 "200": 1
1302 },
1303 "errors": {
1304 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 1,
1305 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 1
1306 }
1307 },
1308 "errorMessage": "acceptance failure: scenarios run: 1, total errors: 2, error budget: 0"
1309}
1310Results:
1311FAILED acceptance failure: scenarios run: 1, total errors: 2, error budget: 0
1312
1313```
1314
1315</p>
1316</details>
1317
1318You can observe the following in the result.
1319- Observe `"matches": 0,`. When any of the `match` statements fail it sets this to 0 (this could be confusing with scripts that don't have any `match` statements.
1320- Observe the following section where we list the number of scenarios created, scenarios completed, requests completed and list of errors. You can see it has information about the `match` statements that failed so you can use this information to find where in script failure occured.
1321```
1322 "totals": {
1323 "scenariosCreated": 1,
1324 "scenariosCompleted": 0,
1325 "requestsCompleted": 1,
1326 "codes": {
1327 "200": 1
1328 },
1329 "errors": {
1330 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 1,
1331 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 1
1332 }
1333```
1334- Observe the following error message regarding acceptance testing. Notice that error budget (default 0) can be modified as per your need. Read [here](#to-configure-acceptance-behavior) for more info.
1335```
1336"errorMessage": "acceptance failure: scenarios run: 1, total errors: 2, error budget: 0"
1337```
1338
1339Also, as this test failed, you will also observe that the process exit code is non-zero (number of `match` failures). On _Mac_ you can run command `echo $?` immediately after that to see the process exit code 2 in this case.
1340
1341### 7. Remove assets from AWS
1342This section is same as before. See [here](#8-remove-assets-from-aws) for details.
1343
1344## More about acceptance mode
1345### Acceptance testing in CI/CD
1346For the purposes of facilitating the use of this tool in a CI/CD pipeline, if any of the acceptance tests fail to successfully complete, the process will exit with a non-zero exit code.
1347
1348### Run `script.yml` exclusively in acceptance mode
1349To hard code acceptance mode into your script add the following in your `script.yml`:
1350```
1351mode: acceptance
1352...
1353```
1354*note: 'acceptance' may be abbreviated to 'acc' in the script*
1355
1356### Use same `script.yml` for performance and acceptance testing and monitoring
1357You can use the same `script.yml` for performance, acceptance testing and monitoring so you don't have to maintain multiple files. The scenarios that are important for performance test would be used for acceptance testing and monitoring as well.
1358
1359Since acceptance mode will run all scenarios only once (by default), the scripts that only are run in acceptance mode are not required to have a `phases` array in the `config` section of the script.
1360
1361### To configure acceptance behavior
1362You may configure [sampling](glossary.md#sampling) behavior. To control the number of samples taken, the time before taking a sample, or the number of errors constituting a failure, you may supply the following (default values listed):
1363
1364```
1365sampling:
1366 size: 1 # The size of sample set
1367 averagePause: 0.2 # The average number of seconds to pause between samples
1368 pauseVariance: 0.1 # The maximum difference of the actual pause from the average pause (in either direction)
1369 errorBudget: 0 # The number of observed errors to accept before alerting
1370```
1371
1372# Monitoring mode
1373Detect outages quickly. Use serverless-artillery to generate synthetic customer activity to continously validate the expected system behavior and optionally alert you immediately if your users will be impacted.
1374
1375Performance testing framework forms the basis of monitoring mode of serverless-artillery. Hence please go through [performance mode](#performance-mode-performanceload-testing) section before proceeding.
1376
1377## Tutorial 6: Monitoring mode without serverless-artillery alert
1378If you don't need serverless-artillery to send an alert when monitoring detects a problem then follow the tutorial here. You can [forward the test result to your data store](#providing-a-data-store-to-view-the-results-of-your-performance-test) and use alerting service there to noify you.
1379
1380### 1. Create custom deployment assets
1381Follow [Tutorial 3 to create custom deployment assets](#tutorial-3-performance-test-with-custom-deployment-assets).
1382
1383### 2. Setup AWS account credentials
1384This section is same as before. See [here](#before-running-serverless-artillery) for details.
1385
1386### 3. Tryout monitoring mode
1387#### 3.1. Deploy assets to AWS
1388This section is same as before. See [here](#3-deploy) for details. **Note** that monitoring is turned off by default in `serverless.yml` and hence the assets deployed in this step would not start monitoring.
1389
1390#### 3.2. Invoke monitoring once
1391When `-m` option is used in `slsart invoke` command, serverless-artillery invokes the load generator Lambda in monitoring mode. This is useful also during script development to avoid having to redeploy everytime you edit `script.yml` as mentioned [below](#5-deploy-assets-to-aws-to-start-monitoring).
1392```
1393slsart invoke -m --stage <your-unique-stage-name>
1394```
1395Given default [monitoring behavior configuration](#to-configure-monitoring-behavior), each scenario/flow in your script will be executed five times **only once**.
1396
1397### 4. Customize deployment assets to turn on monitoring
1398Open `serverless.yml` in your favorite editor. Under `functions` > `loadGenerator` > `events` > `schedule` > find `enabled: false`. Set it to `true`.
1399
1400Notice instruction 0 and 1 under `BEFORE ENABLING` section if they are applicable for your use case.
1401
1402### 5. Deploy assets to AWS to start monitoring
1403This section is same as before. See [here](#3-deploy) for details. **Note** that in the previous step monitoring was turned on and hence just _deploying_ the assets would turn on monitoring. Separate _invoke_ is not needed.
1404
1405**NOTE:** In performance test and acceptance test, the `script.yml` is passed with `invoke` command and hence redeployment is not needed when you edit `script.yml`. But monitoring mode uses the `script.yml` that is deployed in `slsart deploy` command. Also `invoke` command is not used in monitoring mode. Hence you need to redeploy everytime you edit `script.yml`. During script development you can take advantage of `slsart invoke -m` to [try monitoring](#3-tryout-monitoring-mode) with your script and avoid having to redeploy each time it is changed.
1406
1407Given default [moitoring behavior configuration](#to-configure-monitoring-behavior), each scenario/flow in your script will be executed five times **every minute**.
1408
1409### 6. Pause monitoring
1410Monitoring mode will run 24x7 until turned off or paused. If you need to pause monitoring you can do the following.
1411#### 6.1. Method 1: Using CloudWatch Rules
1412- Go to `AWS CloudWatch console` and find `Rules` (under `Events`) and search for the rule `${self:service}-${opt:stage, self:provider.stage}-monitoring` based on your `serverless.yml`.
1413- Do required [steps](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/Delete-or-Disable-Rule.html) to `Disable` this rule. This will prevent further invocation of the load generator Lambda function for monitoring.
1414 - To enable monitoring again `Enable` this rule.
1415- This will turn off monitoring and preserve the load generator Lambda logs.
1416#### 6.2. Method 2: Turn monitoring off in `serverless.yml`
1417- Open `serverless.yml` in your favorite editor.
1418- Under `functions` > `loadGenerator` > `events` > `schedule` > find `enabled: true`. Set it to `false`.
1419- Redeploy assets using same instructions as before. See [here](#3-deploy) for details.
1420
1421### 7. Remove assets from AWS
1422If you want to keep the 24x7 monitoring then you don't need to do this step.
1423
1424When you want to turn off monitoring then remove the assets from AWS. See [here](#8-remove-assets-from-aws) for details.
1425
1426## Tutorial 7: Monitoring mode with serverless-artillery alert
1427Here we will look into how to setup monitoring such that serverless-artillery sends alert when it detects a problem.
1428
1429### 1. Create custom deployment assets
1430Follow [Tutorial 3 to create custom deployment assets](#tutorial-3-performance-test-with-custom-deployment-assets).
1431
1432### 2. Setup AWS account credentials
1433This section is same as before. See [here](#before-running-serverless-artillery) for details.
1434
1435### 3. Customize script to have `match` clause
1436Ensure that you have `match` clauses defined for each request in your script's flows to validate the responses. See [here](#match-clause) to learn more about `match`.
1437
1438For the purpose of this tutorial you can copy paste the script from [here](#1-customize-scriptyml).
1439
1440### 4. Customize deployment assets to add at least one subscription
1441Open `serverless.yml` in your favorite editor.
1442- _Uncomment_ the line of `Subscription` section.
1443```
1444# Subscription: # docs at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-subscription.html
1445```
1446- Add at least one subscription. In this tutorial we will use email subscription.
1447 - _Uncomment_ following two lines.
1448```
1449# - Endpoint: <target>@<host> # the endpoint is an email address
1450# Protocol: email
1451```
1452 - Replace `<target>@<host>` with your email address. Example, `mymail@myhost.com`.
1453
1454### 5. Tryout monitoring mode
1455#### 5.1. Deploy assets to AWS
1456This section is same as before. See [here](#31-deploy-assets-to-aws) for details.
1457
1458#### 5.2. Invoke monitoring once
1459This section is same as before. See [here](#32-invoke-monitoring-once) for details.
1460
1461### 6. Test failure scenario
1462We will inject failure scenario so that the `match` fails and monitoring mode sends us an alert.
1463
1464#### 6.1. Edit `script.yml` to fail `match`
1465Edit `script.yml` as mentioned [here](#61-edit-scriptyml-to-fail-match) to cause `match` to fail.
1466
1467#### 6.2. Invoke monitoring once
1468Follow instruction [here](#32-invoke-monitoring-once) to use `-m` option of `slsart invoke` command to invoke monitoring once to try our modified `script.yml` without having to redeploy assets.
1469
1470Given default [moitoring behavior configuration](#to-configure-monitoring-behavior), each scenario/flow in your script will be executed five times **only once**. If all five of them fail (we try to avoid notifying you about blips) then you should receive a notification via the configured mechanism (email in the case of this tutorial).
1471
1472Below is sample email.
1473<details><summary>Click to expand/collapse</summary>
1474<p>
1475
1476```
1477Alert:
1478 monitoring failure: scenarios run: 5, total errors: 10, error budget: 4
1479
1480Logs:
1481Full analysis:
1482{
1483 "errors": 10,
1484 "reports": [
1485 {
1486 "timestamp": "2019-04-17T23:16:17.050Z",
1487 "scenariosCreated": 5,
1488 "scenariosCompleted": 0,
1489 "requestsCompleted": 5,
1490 "latency": {
1491 "min": 12.4,
1492 "max": 25.2,
1493 "median": 24,
1494 "p95": 25.2,
1495 "p99": 25.2
1496 },
1497 "rps": {
1498 "count": 5,
1499 "mean": 0.93
1500 },
1501 "scenarioDuration": {
1502 "min": null,
1503 "max": null,
1504 "median": null,
1505 "p95": null,
1506 "p99": null
1507 },
1508 "scenarioCounts": {
1509 "0": 5
1510 },
1511 "errors": {
1512 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 5,
1513 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 5
1514 },
1515 "codes": {
1516 "200": 5
1517 },
1518 "matches": 0,
1519 "customStats": {},
1520 "phases": [
1521 {
1522 "pause": 0.2255259122021872
1523 },
1524 {
1525 "duration": 1,
1526 "arrivalRate": 1
1527 },
1528 {
1529 "pause": 0.2968933399583734
1530 },
1531 {
1532 "duration": 1,
1533 "arrivalRate": 1
1534 },
1535 {
1536 "pause": 0.16654656047499483
1537 },
1538 {
1539 "duration": 1,
1540 "arrivalRate": 1
1541 },
1542 {
1543 "pause": 0.19488041671127268
1544 },
1545 {
1546 "duration": 1,
1547 "arrivalRate": 1
1548 },
1549 {
1550 "pause": 0.19656039636288947
1551 },
1552 {
1553 "duration": 1,
1554 "arrivalRate": 1
1555 }
1556 ]
1557 }
1558 ],
1559 "totals": {
1560 "scenariosCreated": 5,
1561 "scenariosCompleted": 0,
1562 "requestsCompleted": 5,
1563 "codes": {
1564 "200": 5
1565 },
1566 "errors": {
1567 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 5,
1568 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 5
1569 }
1570 },
1571 "errorMessage": "monitoring failure: scenarios run: 5, total errors: 10, error budget: 4"
1572}
1573
1574
1575--
1576If you wish to stop receiving notifications from this topic, please click or visit the link below to unsubscribe:
1577https://sns.us-east-1.amazonaws.com/unsubscribe.html?SubscriptionArn=arn:aws:sns:us-east-1:515126931066:serverless-artillery-hPDAiDvuzL-ash-monitoringAlerts-3PPB71S63RM2:e11606d1-e70d-482c-82f9-eff26a760e68&Endpoint=ashmi.s.bhanushali@nordstrom.com
1578
1579Please do not reply directly to this email. If you have any questions or comments regarding this email, please contact us at https://aws.amazon.com/support
1580```
1581
1582</p>
1583</details>
1584
1585You will also see the following output at the command line.
1586<details><summary>Click to expand/collapse</summary>
1587<p>
1588
1589```
1590
1591 Invoking test Lambda
1592
1593{
1594 "errors": 10,
1595 "reports": [
1596 {
1597 "timestamp": "2019-04-17T23:06:29.570Z",
1598 "scenariosCreated": 5,
1599 "scenariosCompleted": 0,
1600 "requestsCompleted": 5,
1601 "latency": {
1602 "min": 21.4,
1603 "max": 52.1,
1604 "median": 25.8,
1605 "p95": 52.1,
1606 "p99": 52.1
1607 },
1608 "rps": {
1609 "count": 5,
1610 "mean": 0.94
1611 },
1612 "scenarioDuration": {
1613 "min": null,
1614 "max": null,
1615 "median": null,
1616 "p95": null,
1617 "p99": null
1618 },
1619 "scenarioCounts": {
1620 "0": 5
1621 },
1622 "errors": {
1623 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 5,
1624 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 5
1625 },
1626 "codes": {
1627 "200": 5
1628 },
1629 "matches": 0,
1630 "customStats": {},
1631 "phases": [
1632 {
1633 "pause": 0.19110438826323195
1634 },
1635 {
1636 "duration": 1,
1637 "arrivalRate": 1
1638 },
1639 {
1640 "pause": 0.2695130316914205
1641 },
1642 {
1643 "duration": 1,
1644 "arrivalRate": 1
1645 },
1646 {
1647 "pause": 0.10236624757585773
1648 },
1649 {
1650 "duration": 1,
1651 "arrivalRate": 1
1652 },
1653 {
1654 "pause": 0.13588464289194607
1655 },
1656 {
1657 "duration": 1,
1658 "arrivalRate": 1
1659 },
1660 {
1661 "pause": 0.2951659631896233
1662 },
1663 {
1664 "duration": 1,
1665 "arrivalRate": 1
1666 }
1667 ]
1668 }
1669 ],
1670 "totals": {
1671 "scenariosCreated": 5,
1672 "scenariosCompleted": 0,
1673 "requestsCompleted": 5,
1674 "codes": {
1675 "200": 5
1676 },
1677 "errors": {
1678 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 5,
1679 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 5
1680 }
1681 },
1682 "errorMessage": "monitoring failure: scenarios run: 5, total errors: 10, error budget: 4"
1683}
1684
1685 Your function invocation has completed.
1686
1687{
1688 "errors": 10,
1689 "reports": [
1690 {
1691 "timestamp": "2019-04-17T23:06:29.570Z",
1692 "scenariosCreated": 5,
1693 "scenariosCompleted": 0,
1694 "requestsCompleted": 5,
1695 "latency": {
1696 "min": 21.4,
1697 "max": 52.1,
1698 "median": 25.8,
1699 "p95": 52.1,
1700 "p99": 52.1
1701 },
1702 "rps": {
1703 "count": 5,
1704 "mean": 0.94
1705 },
1706 "scenarioDuration": {
1707 "min": null,
1708 "max": null,
1709 "median": null,
1710 "p95": null,
1711 "p99": null
1712 },
1713 "scenarioCounts": {
1714 "0": 5
1715 },
1716 "errors": {
1717 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 5,
1718 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 5
1719 },
1720 "codes": {
1721 "200": 5
1722 },
1723 "matches": 0,
1724 "customStats": {},
1725 "phases": [
1726 {
1727 "pause": 0.19110438826323195
1728 },
1729 {
1730 "duration": 1,
1731 "arrivalRate": 1
1732 },
1733 {
1734 "pause": 0.2695130316914205
1735 },
1736 {
1737 "duration": 1,
1738 "arrivalRate": 1
1739 },
1740 {
1741 "pause": 0.10236624757585773
1742 },
1743 {
1744 "duration": 1,
1745 "arrivalRate": 1
1746 },
1747 {
1748 "pause": 0.13588464289194607
1749 },
1750 {
1751 "duration": 1,
1752 "arrivalRate": 1
1753 },
1754 {
1755 "pause": 0.2951659631896233
1756 },
1757 {
1758 "duration": 1,
1759 "arrivalRate": 1
1760 }
1761 ]
1762 }
1763 ],
1764 "totals": {
1765 "scenariosCreated": 5,
1766 "scenariosCompleted": 0,
1767 "requestsCompleted": 5,
1768 "codes": {
1769 "200": 5
1770 },
1771 "errors": {
1772 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 5,
1773 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 5
1774 }
1775 },
1776 "errorMessage": "monitoring failure: scenarios run: 5, total errors: 10, error budget: 4"
1777}
1778Results:
1779FAILED monitoring failure: scenarios run: 5, total errors: 10, error budget: 4
1780
1781```
1782
1783</p>
1784</details>
1785
1786You can observe the following in the result.
1787- Observe `"matches": 0,`. When any of the `match` statements fail it sets this to 0 (this could be confusing with scripts that don't have any `match` statements).
1788- Observe the following section where we list the number of scenarios created, scenarios completed, requests completed and list of errors. You can see it has information about the `match` statements that failed so you can use this information to find where in script failure occured.
1789```
1790 "totals": {
1791 "scenariosCreated": 5,
1792 "scenariosCompleted": 0,
1793 "requestsCompleted": 5,
1794 "codes": {
1795 "200": 5
1796 },
1797 "errors": {
1798 "Failed match: expected=failvalue got=postman-echo.com expression=$.headers.host": 5,
1799 "Failed match: expected=failvalue got=https expression=$.headers.x-forwarded-proto": 5
1800 }
1801 },
1802```
1803- Observe the following error message regarding acceptance testing. Notice that error budget (default 4) can be modified as per your need. Read [here](#to-configure-monitoring-behavior) for more info.
1804```
1805"errorMessage": "monitoring failure: scenarios run: 5, total errors: 10, error budget: 4"
1806```
1807
1808Also, as this test failed, you will also observe that the process exit code is non-zero (number of `match` failures). On _Mac_ you can run command `echo $?` immediately after that to see the process exit code 10 in this case.
1809
1810### 7. Customize deployment assets to turn on monitoring
1811This section is same as before. See [here](#4-customize-deployment-assets-to-turn-on-monitoring) for details.
1812
1813### 8. Deploy assets to AWS to start monitoring
1814This section is same as before. See [here](#5-deploy-assets-to-aws-to-start-monitoring) for details.
1815
1816In this step, along with deployment asset we are also deploying the modified `script.yml` where `match` will fail. Hence once the assets are deployed, monitoring mode will turn on and send you an email to alert about these failures.
1817
1818Given default [monitoring behavior configuration](#to-configure-monitoring-behavior), each scenario/flow in your script will be executed five times **every minute**. All five of the executions will cause the `match` statements to fail exceeding `errorBudget` (default 4) and hence would send the email alerting about the problem (once every minute).
1819
1820### 9. Pause monitoring
1821This section is same as before. See [here](#6-pause-monitoring) for details.
1822
1823### 10. Remove assets from AWS
1824This section is same as before. See [here](#8-remove-assets-from-aws) for details.
1825
1826## More about monitoring mode
1827### Run `script.yml` exclusively in monitoring mode
1828To hard code monitoring mode into your script add the following in your `script.yml`:
1829```
1830mode: monitoring
1831...
1832```
1833*note: 'monitoring' may be abbreviated to 'mon' in the script*
1834
1835### Use same `script.yml` for performance and acceptance testing and monitoring
1836You can use the same `script.yml` for performance, acceptance testing and monitoring so you don't have to maintain multiple files. The scenarios that are important for performance test would be used for acceptance testing and monitoring as well.
1837
1838Since monitoring mode will run all scenarios five times (by default), the scripts that only are run in monitoring mode are not required to have a `phases` array in the `config` section of the script.
1839
1840### To configure monitoring behavior
1841You may configure [sampling](glossary.md#sampling) behavior. To control the number of samples taken, the time before taking a sample, or the number of errors constituting a failure, you may supply the following (default values listed):
1842
1843```
1844sampling:
1845 size: 5 # The size of sample set
1846 averagePause: 0.2 # The average number of seconds to pause between samples
1847 pauseVariance: 0.1 # The maximum difference of the actual pause from the average pause (in either direction)
1848 errorBudget: 4 # The number of observed errors to accept before alerting
1849```
1850
1851# Upgrading customized projects built with older versions of serverless-artillery
1852If you had built a custom test project (in order to customize the deployment assets) with an older version of serverless-artillery, then you might need to upgrade the project in order to use features of newer version of serverless-artillery. For example, serverless-artillery's monitoring mode requires certain deployment assets (configured in `serverless.yml`), that are not part of the configuration defined in `serverless.yml` created by `slsart configure` command of the older versions of serverless-artillery. Hence if you were to try monitoring on such test project then it would not work.
1853
1854We have added `slsart upgrade` command in order to make it easier for you to upgrade such custom test projects. Please note that you might have to manually add your customizations in the upgraded test project.
1855
1856```
1857slsart upgrade
1858
1859Upgrading project...
1860Cleaning project by deleting node_modules and package-lock.json ...done.
1861
1862Backing up existing project files to `backup` directory ...
1863handler.js -> backup/handler.js ✔
1864package.json -> backup/package.json ✔
1865serverless.yml -> backup/serverless.yml ✔
1866Backup complete.
1867
1868upgrading to version 0.0.1 ...done.
1869Executing `npm install` to provide dependencies to the upgraded project ...
1870[ NPM install output here ]
1871
1872Upgrade complete.
1873
1874Existing project files were copied to `backup`.
1875
1876It's possible that the upgraded project contained additional customizations:
1877Diff `backup` with `original-assets-0.0.0` to understand how the project was originally customized.
1878Diff `serverless.yml` with `backup/serverless.yml` to compare the previous cloud resources with the upgraded service.
1879Diff `project.json` with `backup/project.json` to compare the changes in project dependencies.
1880
1881Please merge any missing customizations into the project to complete the upgrade.
1882
1883```
1884
1885## Known Upgrade Issues
1886
1887It's possible that the upgrade fails with this error:
1888```
1889UpdatePreconditionError: Invalid package.json dependency package version found:
1890 csv-parse expected ^1.1.7 found ^1.3.3
1891```
1892
1893Do the following to work-around this error:
1894
18951) Delete the backup directory which we created by the failed upgrade.
18962) Modify the existing `package.json` dependency for `csv-parse` to version `^1.1.7`:
1897```
1898"csv-parse": "^1.1.7"
1899```
19003) Run the upgrade again:
1901```
1902slsart upgrade
1903```
1904
1905# Detailed Usage
1906```
1907$ slsart --help
1908
1909slsart <command>
1910
1911Commands:
1912 slsart deploy Deploy a default version of the function that will execute
1913 your Artillery scripts. See
1914 https://serverless.com/framework/docs/providers/aws/cli-refe
1915 rence/deploy/ for reference.
1916 slsart invoke Invoke your function with your Artillery script. Will
1917 prefer a script given by `-d`, `--data`, `-p`, or `--path`
1918 over a `script.[yml|json]` file in the current directory
1919 over the default script. Invocation mode will default to
1920 "performance" but adding the `-a` flag will run the script
1921 in "acceptance" mode. See
1922 https://serverless.com/framework/docs/providers/aws/cli-refe
1923 rence/invoke/ for reference.
1924 slsart kill Stop a currently running load test and remove the function.
1925 slsart remove Remove the function and the associated resources created for
1926 or by it. See
1927 https://serverless.com/framework/docs/providers/aws/cli-refe
1928 rence/remove/ for reference.
1929 slsart script Create a local Artillery script so that you can customize it
1930 for your specific load requirements. See
1931 https://artillery.io for documentation.
1932 slsart configure Create a local copy of the deployment assets for
1933 modification and deployment. See
1934 https://serverless.com/framework/docs/ for documentation.
1935 slsart upgrade Upgrade local assets to latest version.
1936
1937Options:
1938 --help Show help [boolean]
1939 --version Show version number [boolean]
1940 -D, --debug Execute the command in debug mode. It will be chatty about
1941 what it is happening in the code.
1942 -V, --verbose Execute the command in verbose mode. It will be chatty about
1943 what it is attempting to accomplish.
1944```
1945
1946## Commands
1947### `deploy`
1948```
1949slsart deploy --help
1950```
1951```
1952slsart deploy
1953
1954Deploy a default version of the function that will execute your Artillery
1955scripts. See
1956https://serverless.com/framework/docs/providers/aws/cli-reference/deploy/ for
1957reference.
1958
1959Options:
1960 --help Show help [boolean]
1961 --version Show version number [boolean]
1962 -D, --debug Execute the command in debug mode. It will be chatty about
1963 what it is happening in the code.
1964 -V, --verbose Execute the command in verbose mode. It will be chatty about
1965 what it is attempting to accomplish.
1966```
1967
1968### `invoke`
1969```
1970slsart invoke --help
1971```
1972```
1973slsart invoke
1974
1975Invoke your function with your Artillery script. Will prefer a script given by
1976`-d`, `--data`, `-p`, or `--path` over a `script.[yml|json]` file in the current
1977directory over the default script. Invocation mode will default to
1978"performance" but adding the `-a` flag will run the script in "acceptance" mode.
1979See https://serverless.com/framework/docs/providers/aws/cli-reference/invoke/
1980for reference.
1981
1982Options:
1983 --help Show help [boolean]
1984 --version Show version number [boolean]
1985 -D, --debug Execute the command in debug mode. It will be chatty about
1986 what it is happening in the code.
1987 -V, --verbose Execute the command in verbose mode. It will be chatty
1988 about what it is attempting to accomplish.
1989 -a, --acceptance Execute the script in acceptance mode. It will execute each
1990 flow once, reporting failures.
1991 -m, --monitoring Execute the script in monitoring mode. It will execute each
1992 flow a multiple of times, alerting if the number of errors
1993 exceeds the configured threshold.
1994 -d, --data A stringified script to execute
1995 -p, --path A path to the file containing the script to execute
1996 --si, --stdIn Have serverless read the event to invoke the remote function
1997 with from the "standard in" stream
1998 --jo, --jsonOnly Only write JSON to console.log to facilitate piping the
1999 invocation result into a tool such as jq
2000```
2001
2002### `kill`
2003```
2004slsart kill --help
2005```
2006```
2007slsart kill
2008
2009Stop a currently running load test and remove the function.
2010
2011Options:
2012 --help Show help [boolean]
2013 --version Show version number [boolean]
2014 -D, --debug Execute the command in debug mode. It will be chatty about
2015 what it is happening in the code.
2016 -V, --verbose Execute the command in verbose mode. It will be chatty about
2017 what it is attempting to accomplish.
2018```
2019
2020### `remove`
2021```
2022slsart remove --help
2023```
2024```
2025slsart remove
2026
2027Remove the function and the associated resources created for or by it. See
2028https://serverless.com/framework/docs/providers/aws/cli-reference/remove/ for
2029reference.
2030
2031Options:
2032 --help Show help [boolean]
2033 --version Show version number [boolean]
2034 -D, --debug Execute the command in debug mode. It will be chatty about
2035 what it is happening in the code.
2036 -V, --verbose Execute the command in verbose mode. It will be chatty about
2037 what it is attempting to accomplish.
2038```
2039
2040### `script`
2041```
2042slsart script --help
2043```
2044```
2045slsart script
2046
2047Create a local Artillery script so that you can customize it for your specific
2048load requirements. See https://artillery.io for documentation.
2049
2050Options:
2051 --help Show help [boolean]
2052 --version Show version number [boolean]
2053 -D, --debug Execute the command in debug mode. It will be chatty about
2054 what it is happening in the code.
2055 -V, --verbose Execute the command in verbose mode. It will be chatty about
2056 what it is attempting to accomplish.
2057 -e, --endpoint The endpoint to load with traffic. [string]
2058 -d, --duration The duration, in seconds, to load the given endpoint. [number]
2059 -r, --rate The rate, in requests per second, at which to load the given
2060 endpoint. [number]
2061 -t, --rampTo The rate to ramp up to from the given (starting) rate, in
2062 requests per second at which to load the given endpoint.
2063 [number]
2064 -o, --out The file to output the generated script in to. [string]
2065```
2066
2067### `configure`
2068```
2069slsart configure --help
2070```
2071```
2072slsart configure
2073
2074Create a local copy of the deployment assets for modification and deployment.
2075See https://docs.serverless.com for documentation.
2076
2077Options:
2078 --help Show help [boolean]
2079 --version Show version number [boolean]
2080 -D, --debug Execute the command in debug mode. It will be chatty about
2081 what it is happening in the code.
2082 -V, --verbose Execute the command in verbose mode. It will be chatty about
2083 what it is attempting to accomplish.
2084```
2085
2086### `upgrade`
2087```
2088slsart upgrade --help
2089```
2090```
2091slsart upgrade
2092
2093Upgrade local assets to latest version.
2094
2095Options:
2096 --help Show help [boolean]
2097 --version Show version number [boolean]
2098 -D, --debug Execute the command in debug mode. It will be chatty about
2099 what it is happening in the code.
2100 -V, --verbose Execute the command in verbose mode. It will be chatty about
2101 what it is attempting to accomplish.
2102```
2103
2104# Troubleshooting
2105### Problems installing?
2106#### Error: npm ERR! code EACCES
2107If you are installing into a node_modules owned by root and getting error `npm ERR! code EACCES`, [read this](root-owns-node-modules.md).
2108
2109# External References
21101. [artillery.io](https://artillery.io) for documentation about how to define your load shape, volume, targets, inputs, et cetera
21112. [serverless.com](https://serverless.com/framework/docs/) for documentation about how to create a custom function configuration
21123. [serverless-artillery](https://github.com/Nordstrom/serverless-artillery) README for documentation on the use of this tool
21134. [serverless-star](https://github.com/Nordstrom/serverless-star) Next generation implementation and generalization of the arbitrarily wide work distribution capability
2114
2115# If you've read this far
2116Please let us know any feedback on this tool. We would love to hear from you. Thank you!
2117