question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

having errors with slsart deploy command

See original GitHub issue

Discussed in https://github.com/artilleryio/artillery/discussions/1397

<div type='discussions-op-text'>

Originally posted by sirishaganti April 7, 2022 Hi,

I am trying to use this slsart deploy. I have my script.yml which looks something like below -

config:
  target: "https://d8snwdhbfd.execute-api.us-east-1.amazonaws.com/default"
  phases:
    - duration: 60
      arrivalRate: 5
      name: Warm up
    - duration: 120
      arrivalRate: 5
      rampTo: 50
      name: Ramp up load
    - duration: 60
      arrivalRate: 5
      name: Sustained load
  payload:
    path: "input.csv"
    skipHeader: true
    cast: true
    fields:
      - "EventName"
      - "RequestId"
      - "RequestedBy"
      - "Timestamp"
scenarios:
  - name: "Profile hit"
    flow:
      - post:
          url: "/my_lambda"
          json:
            EventName: '{{ EventName }}'
            RequestId: '{{ RequestId }}'
            RequestedBy: '{{ RequestedBy }}'
            Timestamp: '{{ Timestamp }}'
          capture:
            - json: "$.results[0].id"
              as: "productId"

My input.csv is in the same folder as the script.yml. Below is handler.js -

/* eslint-disable no-underscore-dangle */
const fs = require('fs');
const { safeLoad } = require('js-yaml');
const merge = require('lodash.merge');
const omit = require('lodash.omit'); // eslint-disable-line import/no-unresolved
const task = require('./artillery-task.js');
const platform = require('./platform-settings.js');
const path = require('path');
const promisify = require('util-promisify');// eslint-disable-line import/no-unresolved

const mergeFileField = '>>'

const readFileAsync = promisify(fs.readFile)

const lambdaHandler = {
  handleUnhandledRejection: (ex) => {
    console.log('###############################################################')
    console.log('##             !! Unhandled promise rejection !!             ##')
    console.log('## This probably results from an unforseen circumstance in   ##')
    console.log('## a plugin.  Please report the following stack trace at:    ##')
    console.log('## https://github.com/Nordstrom/serverless-artillery/issues  ##')
    console.log('###############################################################')
    console.log(ex.stack)
    console.log('###############################################################')

    throw ex
  },

  getMergeFilePath: (
    mergeFileInput,
    resolve = path.resolve,
    dirname = __dirname
  ) => {
    const reject = message => Promise.reject(new Error(message))
    if (!mergeFileInput || typeof mergeFileInput !== 'string') {
      return reject(`'${typeof mergeFileInput}' is not a valid path.`)
    }
    const absolutePath = resolve(mergeFileInput)
    if (!absolutePath.startsWith(dirname)) {
      return reject(`Merge file ${absolutePath} is not a local file path.`)
    }
    return Promise.resolve(absolutePath)
  },

  readMergeFile: (
    mergeFilePath,
    readFile = readFileAsync,
    error = console.error,
    getMergeFilePath = lambdaHandler.getMergeFilePath
  ) =>
    getMergeFilePath(mergeFilePath)
      .then(readFile)
      .then(safeLoad)
      .catch((ex) => {
        error('Failed to read merge file.', mergeFilePath, ex.stack)
        throw ex
      }),

  mergeIf: (script, readMergeFile = lambdaHandler.readMergeFile) =>
    (mergeFileField in script
      ? readMergeFile(script[mergeFileField])
        .then(inputData => merge({}, inputData, omit(script, [mergeFileField])))
      : Promise.resolve(script)),

  createHandler: (taskToExecute, platformSettings) =>
    (event, context, callback) => {
      try {
        const script = event
        script._funcAws = {
          functionName: context.functionName,
        }
        const settings = platformSettings.getSettings(script)

        lambdaHandler.mergeIf(script)
          .then(mergedScript => taskToExecute.executeTask(mergedScript, settings))
          .then((result) => {
            if (process.env.SA_DEBUG) console.log(`LambdaResult ${JSON.stringify(result)}`)
            callback(null, result)
          })
          .catch((ex) => {
            console.log(ex.stack)
            if (process.env.SA_DEBUG) console.log(`LambdaResult ${JSON.stringify(ex)}`)
            callback(null, `Error executing task: ${ex.message}`)
          })
      } catch (ex) {
        console.log(ex.stack)
        if (process.env.SA_DEBUG) console.log(`LambdaResult ${JSON.stringify(ex)}`)
        callback(null, `Error validating event: ${ex.message}`)
      }
    },
}

process.on('unhandledRejection', lambdaHandler.handleUnhandledRejection)

module.exports.handler = lambdaHandler.createHandler(task, platform)
module.exports.lambdaHandler = lambdaHandler

and below is serverless.yml -

# We're excited that this project has provided you enough value that you are looking at its code!
#
# This is a standard [Serverless Framework](https://www.serverless.com) project and you should
# feel welcome to customize it to your needs and delight.
#
# If you do something super cool and would like to share the capability, please open a PR against
# https://www.github.com/Nordstrom/serverless-artillery
#
# Thanks!

# If the following value is changed, your service may be duplicated (this value is used to build the CloudFormation
# Template script's name)
service: serverless-artillery-yaAvA4n3DE

provider:
  name: aws
  runtime: nodejs10.x
  iamRoleStatements:
    # This policy allows the function to invoke itself which is important if the script is larger than a single
    # function can produce
    - Effect: 'Allow'
      Action:
        - 'lambda:InvokeFunction'
      Resource:
        'Fn::Join':
          - ':'
          -
            - 'arn:aws:lambda'
            - Ref: 'AWS::Region'
            - Ref: 'AWS::AccountId'
            - 'function'
            - '${self:service}-${opt:stage, self:provider.stage}-loadGenerator*' # must match function name
    # This policy allows the function to publish notifications to the SNS topic defined below with logical ID monitoringAlerts
    - Effect: 'Allow'
      Action:
        - 'sns:Publish'
      Resource:
        Ref: monitoringAlerts # must match the SNS topic's logical ID
functions:
  loadGenerator: # !!Do not edit this name!!
    handler: handler.handler    # the serverlessArtilleryLoadTester handler() method can be found in the handler.js source file
    timeout: 300                # set timeout to be 5 minutes (max for Lambda)
    environment:
      TOPIC_ARN:
        Ref: monitoringAlerts
      TOPIC_NAME:
        'Fn::GetAtt':
          - monitoringAlerts
          - TopicName
    events:
      - schedule:
          name: '${self:service}-${opt:stage, self:provider.stage}-monitoring' # !!Do not edit this name!!
          description: The scheduled event for running the function in monitoring mode
          rate: rate(1 minute)
          ########################################################################################################################
          ### !! BEFORE ENABLING... !!!
          ### 0. Change `'>>': script.yml` below to reference the script you want to use for monitoring if that is not its name.
          ###    The script must be in this directory or a subdirectory.
          ### 1. Modify your `script.yml` to provide the details of invoking every important surface of your service, as per
          ###    https://artillery.io/docs
          ### 2. To receive alerts when errors exceed the budget:
          ###    i.  Add a `match` clause to your requests, specifying your expectations of a successful request.  This relatively
          ###        undocumented feature is implemented at: https://github.com/shoreditch-ops/artillery/blob/82bdcdfc32ce4407bb197deff2cee13b4ecbab3b/core/lib/engine_util.js#L318
          ###        We would welcome the contribution of a plugin replacing this as discussed in https://github.com/Nordstrom/serverless-artillery/issues/116
          ###    ii. Modify the `monitoringAlerts` SNS Topic below, uncommenting `Subscription` and providing subscriptions for any
          ###        alerts that might be raised by the monitoring function.  (To help you out, we've provided commented-out examples)
          ###        (After all, what good is monitoring if noone is listening?)
          ### 3. Deploy your new assets/updated service using `slsart deploy`
          ### 4. [As appropriate] approve the subscription verifications for the SNS topic that will be sent following its creation
          ### 5. Re-deploy whenever you update your monitoring script
          ########################################################################################################################
          enabled: false
          input:
            '>>': script.yml
            mode: monitoring
resources:
  Resources:
    monitoringAlerts: # !!Do not edit this name!!
      Type: 'AWS::SNS::Topic'
      Properties:
        DisplayName: '${self:service} Monitoring Alerts'
#        Subscription: # docs at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-subscription.html
#          - Endpoint: http://<host>/<path> # the endpoint is an URL beginning with "http://"
#            Protocol: http
#          - Endpoint: https://<host>/<path> # the endpoint is a URL beginning with "https://"
#            Protocol: https
#          - Endpoint: <target>@<host> # the endpoint is an email address
#            Protocol: email
#          - Endpoint: <target>@<host> # the endpoint is an email address
#            Protocol: email-json
#          - Endpoint: <phone-number> # the endpoint is a phone number of an SMS-enabled device
#            Protocol: sms
#          - Endpoint: <sqs-queue-arn> # the endpoint is the ARN of an Amazon SQS queue
#            Protocol: sqs
#          - Endpoint: <endpoint-arn> # the endpoint is the EndpointArn of a mobile app and device.
#            Protocol: application
#          - Endpoint: <lambda-arn> # the endpoint is the ARN of an AWS Lambda function.
#            Protocol: lambda

When I run slsart deploy , I get the following error -

/usr/local/lib/node_modules/serverless/node_modules/type/lib/resolve-exception.js:14
        throw error;
        ^

TypeError: undefined is not an array
    at module.exports (/usr/local/lib/node_modules/serverless/node_modules/type/lib/resolve-exception.js:12:14)
    at module.exports (/usr/local/lib/node_modules/serverless/node_modules/type/array/ensure.js:15:25)
    at new Serverless (/usr/local/lib/node_modules/serverless/lib/serverless.js:86:22)
    at Object.serverlessLoader (/usr/local/lib/node_modules/serverless-artillery/lib/index.js:542:24)
    at Object.deploy (/usr/local/lib/node_modules/serverless-artillery/lib/index.js:563:27)
    at Object.<anonymous> (/usr/local/lib/node_modules/serverless-artillery/bin/serverless-artillery:205:16)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

I tried deploying the files handler.js, serverless.yml, script.yml and input.csv to AWS directly by zipping up the 4 files along with serverless and serverless-artillery library files in node_modules and when I ran the lambda function, I got the following error in the output -

Test Event Name
testevent

Response
"Error executing task: Cannot read property 'phases' of undefined"

Function Logs
START RequestId: 93642716-6e9e-4a8d-b705-db4c91a5fdd6 Version: $LATEST
2022-04-07T18:30:52.020Z	93642716-6e9e-4a8d-b705-db4c91a5fdd6	INFO	 SCRIPT OBJECT {"_funcAws":{"functionName":"loadtestlambda"},"_genesis":1649356252020}
2022-04-07T18:30:52.026Z	93642716-6e9e-4a8d-b705-db4c91a5fdd6	INFO	TypeError: Cannot read property 'phases' of undefined
    at Object.scriptDurationInSeconds (/opt/nodejs/node_modules/serverless-artillery/lib/lambda/planning.js:35:35)
    at Object.planPerformance (/opt/nodejs/node_modules/serverless-artillery/lib/lambda/planning.js:554:46)
    at Object.execute (/opt/nodejs/node_modules/serverless-artillery/lib/lambda/artillery-performance.js:6:28)
    at Object.executeTask (/opt/nodejs/node_modules/serverless-artillery/lib/lambda/artillery-task.js:206:29)
    at /var/task/handler.js:75:47
END RequestId: 93642716-6e9e-4a8d-b705-db4c91a5fdd6
REPORT RequestId: 93642716-6e9e-4a8d-b705-db4c91a5fdd6	Duration: 28.86 ms	Billed Duration: 29 ms	Memory Size: 128 MB	Max Memory Used: 97 MB	Init Duration: 1101.10 ms

Request ID
93642716-6e9e-4a8d-b705-db4c91a5fdd6

It seems to me like I am doing something wrong with the configuration because the script.yml is not getting picked by artillery. What am I doing wrong? I was able to run the script.yml from command line but not as a AWS lambda function. I need to generate cloudwatch logs on the script output. I am doing a load test on AWS lambda function which is not accessible to anyone. It has to be load tested using the AWS lambda function created by serverless artillery. That is my requirement.

Thank you</div>

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
ccsirilcommented, Jul 27, 2022

It could be related to Artillery.io’s new pricing model. Pricing Details : https://www.artillery.io/pricing

This problem occurred due the node and serverless version compatibility. I just tried this with both windows and Ubuntu. Both shows the same error. (TypeError: undefined is not an array)
When trying along with older version of serverless and node which shows some another errors binds mutual.

At last found the compactable version of both serverless and node. with small edits in serverless config. 😉 💯

Platform using

Distributor ID : Ubuntu Description : Ubuntu 22.04 LTS Release : 22.04

Recommended versions

$ node -v v15.5.1 $ npm -v 7.3.0 $ serverless --version Framework Core: 1.83.0 Plugin: 3.8.4 SDK: 2.3.2 Components: 2.34.9

$ slsart --version 0.5.2

Steps to follow

npm uninstall -g serverless npm install -g serverless@1.83.0 npm install -g serverless-artillery

Create a custom service for your tests

$ mkdir customTestLambda $ cd customTestLambda $ cp …/script.yml . $ slsart configure $ ls handler.js package.json serverless.yml

$ vi serverless.yml

“Change the runtime like shows below”

provider: name: aws runtime: nodejs12.x ------------------->(important)

slsart deploy --stage dev --region ap-southeast-2 slsart invoke -p script.yml --stage dev --region ap-southeast-2

Enjoy the Fix! cheers

0reactions
hassycommented, Nov 4, 2022

slsart is not an @artilleryio project - as such we are unable to provide support for it. Nothing to do with Artillery Pro’s pricing.

Recent versions of Artillery have built-in AWS Lambda support - https://www.artillery.io/docs/guides/guides/distributed-load-tests-on-aws-lambda

Read more comments on GitHub >

github_iconTop Results From Across the Web

slsart deploy throwing error, how do I troubleshoot?
I am trying to use the command "slsart deploy" but it's not working for me. How do I troubleshoot the error below?
Read more >
Serverless Framework Commands - AWS Lambda - Deploy
The sls deploy command deploys your entire service via CloudFormation. Run this command when you have made infrastructure changes (i.e., ...
Read more >
Top 10 Serverless Deployment Errors (and How to Fix Them)
Select the resource(s) that failed and click Continue update rollback. Once your stack has successfully deleted or rolled back, you can deploy ...
Read more >
Load Testing Serverless Applications With ...
Serverless-artillery makes it easy to test your services for performance and functionality quickly, easily and without having to maintain any servers or testing ......
Read more >
General Mark A. Milley > U.S. Department of ...
General Milley has had multiple command and staff positions in eight divisions ... General Milley deployed as the Commanding General, International Security ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found