Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local testing for functions using hs functions test command #389

Merged
merged 89 commits into from
Jan 20, 2021

Conversation

miketalley
Copy link
Contributor

@miketalley miketalley commented Nov 17, 2020

Description and Context

Allows local testing of serverless functions using hs functions test <localDotFunctionsFolderPath> command. This runs an express server on port 5432 (or can be specified with --port=<port>) that will host the endpoints configured within serverless.json of the specified .functions folder. By default the specified .functions folder is watched for changes, which will restart the server.

The endpoints can be hit(localhost:5432/_hcms/api/myEndpoint) to execute the function and the context passed into the function will mimic the data shape/properties that are used in production. The output from the function will be logged to the console. CORS has been disabled on the local server, which allows pointing to the local endpoint from a DesignManger module to test the functionality.

This library can also be used for an external project. For example...

const { start } = require('@hubspot/serverless-dev-runtime');

start({
  accountId: 123456,
  port: 5678,
  path: './tmp/localTesting.functions'
});

The limits and contact property values are using mocked data, which can be modified using .env file variables.

Notes

  • A .env file can be included in the local .functions folder to mimic secrets
  • environment config object can be added at both the root level and at the function level in serverless.json(function level overwrites root)
  • headers, params, body(from POSTs), secrets, accountId, limits(mocked), and contact(mocked) get passed into the serverless execution context
  • console.logs within the function will be caught and added to output
  • Mocked data can be customized by setting the values of the following environment variables within a .env file
    • HUBSPOT_LIMITS_TIME_REMAINING
    • HUBSPOT_LIMITS_EXECUTIONS_REMAINING
    • HUBSPOT_CONTACT_VID
    • HUBSPOT_CONTACT_IS_LOGGED_IN
    • HUBSPOT_CONTACT_LIST_MEMBERSHIPS
  • Mocking no contact data can be done using the --contact=false option when running the command
  • Watch can be turned off(it's on by default) by using the --watch=false option
  • Warnings will be displayed when hitting limits
    • secrets > 50
    • runTime > 3s

image

image

TODO

  • Think about creating a BE endpoint to serve default package.json content so we don't keep a copy in this repo

Who to Notify

@williamspiro @gcorne @bkrainer

@miketalley
Copy link
Contributor Author

miketalley commented Dec 22, 2020

I put some invalid code in my .functions/index.js file, and I get this error when running it

[ERROR] Unable to process log {"executionTime":null,"log":"","duration":"NaN ms","status":"UNHANDLED_ERROR","createdAt":1608660747691,"memory":"74/128 MB","id":-1,"payload":1608660747676}

Is there any way we can capture the stack/give more info about the error?

Taking a look. Thanks for sharing. This is fixed now

@miketalley
Copy link
Contributor Author

There is a difference in what is returned in QA vs what is returned locally.

QA

{"response":{"total":0,"offset":0,"limit":10,"results":[],"cacheKey":"103705330::BLOG_POST:SITE_PAGE:LISTING_PAGE:10:::1:searchterm:0:LONG:0:1.0:5.0:0.0:0::::0:0:/54.166.131.109:[]::0:UNKNOWN::::0:0","searchTerm":"searchterm","page":0}}

Locally

{"body":{"response":{"total":0,"offset":0,"limit":10,"results":[],"cacheKey":"103705330::BLOG_POST:SITE_PAGE:LISTING_PAGE:10:::1:searchterm:0:LONG:0:1.0:5.0:0.0:0::::0:0:/73.61.234.183:[]::0:UNKNOWN::::0:0","searchTerm":"searchterm","page":0}},"statusCode":200}

Local has the extra body, and also has the statusCode. I believe those are the only two differences

This is fixed, needed to send the body prop instead of the root in the data.

@miketalley
Copy link
Contributor Author

One thing I notice is even if I throw an error, the status-code on the call is always a 200. Can we persist the status code?

Local
image

QA
image

Fixed

@miketalley miketalley merged commit d1f4891 into master Jan 20, 2021
@miketalley miketalley deleted the serverless/local-testing branch January 20, 2021 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants