Disclaimer: This is not an official Google product.
This is a simple emulator that allows you to test your Cloud Functions on your local machine.
@google-cloud/functions-emulator is currently in pre-1.0.0 development. Before the 1.0.0 release backwards compatible changes and bug fixes will bump the patch version number and breaking changes will bump the minor version number.
npm install -g @google-cloud/functions-emulator
Print the available commands:
functions --help
Commands:
call <function> Invokes a function.
clear Resets the emulator to its default state and clears and
deployed functions.
delete <function> Undeploys a previously deployed function (does NOT delete
the function source code).
deploy Deploys a function with the given module path and entry
point.
describe <function> Describes the details of a single deployed function.
logs Manages emulator logs access.
kill Force kills the emulator process if it stops responding.
list Lists deployed functions.
prune Removes any functions known to the emulator but which no
longer exist in their corresponding module.
restart Restarts the emulator.
start Starts the emulator.
status Removes any functions known to the emulator but which no
longer exist in their corresponding module.
stop Stops the emulator gracefully.
Options:
--help Show help [boolean]
The emulator can host both BACKGROUND and HTTP (foreground) Cloud Functions.
By default the emulator will consider functions deployed to be BACKGROUND
functions. To deploy an HTTP function, use the --trigger-http
argument:
functions deploy <module> <function> --trigger-http
Start the Emulator:
functions start
Deploy a BACKGROUND function (the first argument is the path to your module, the second argument is the name of the function):
functions deploy ../myModule helloWorld
Invoke the function:
functions call helloWorld
Stop the Emulator:
functions stop
For HTTP functions, just use the --trigger-http
argument.
Deploy an HTTP function:
functions deploy ../myModule helloHttp --trigger-http
Invoke the function (default port is 8008):
curl http://localhost:8008/helloHttp
A local configuration (config.js) file is provided that allows you to configure:
Property | Type | Description |
---|---|---|
port | integer | The TCP port on which the emulator will listen (default: 8008) |
verbose | boolean | true if you want to see logs from the emulator itself (default: false ) |
projectId | string | Your GCP project ID (default: none) |
timeout | integer | Timeout (ms) to wait for the emulator to start (default: 3000) |
Functions running in the emulator run in their own (detached) process, so
console logs from your function (e.g. console.log()
calls) will not be piped to
the stdout stream of the emulator. Instead a log file can be found in app/logs/cloud-functions-emulator.log
You can view the logs from your functions using the logs read
command:
functions logs read
By default this will return the most recent 20 log lines. You can alter this
with the --limit
flag.
functions logs read --limit 100
Alternatively, you can simply tail the log file itself.
Mac/Linux:
tail -f logs/cloud-functions-emulator.log
(Note this log will automatically roll when it reaches 1MB.)
To start the emulator in debug mode, simply use the --debug
flag:
functions start --debug
While running in debug mode a separate debug server will be started on port 5858 (default debugger port for Node). You can then attach to the debugger process with your favorite IDE.
If you started the emulator with the --debug
flag, you can simply "Attach" to the emulator from withing Visual Studio Code.
Refer to the documentation for debugging in Visual Studio Code for more information.
Node 7.0.0 introduces a new (experimental) --inspect
flag to allow for integration with Chrome Developer Tools.
To debug functions in the emulator when running Node 7+, start the emulator with the --inspect
flag (instead of --debug
)
functions start --inspect
This will start the internal Node process with this flag. To access the debugger in Chrome, you'll need to inspect the
log file written by the emulator, which by default is located in logs\cloud-functions-emulator.log
. Look for a log entry
that appears like this:
Debugger listening on port 9229.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/remote/serve_file/@60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=localhost:9229/165471ce-1e76-421f-b52d-e3b8a14bcb0c
When you open the chrome devtools debugger you may not see your function source file. Just invoke your function once to have its source file appear in the debugger window
If your IDE doesn't support connecting to a Node.js debugger process, you can easily debug your Cloud Functions in the emulator using node-inspector
First, install node-inspector
npm install -g node-inspector
Start the emulator in debug mode
functions start --debug
Now start the node inspector process (we recommend doing this in a separate console window)
node-inspector
This will start an HTTP server on port 8080, you can then browse to this URL in Chrome
open http://127.0.0.1:8080/?port=5858
Now when you invoke your function, you can debug!
functions call helloWorld
When running functions locally you sometimes want to change the behavior of modules which connect to external services. For example you might be accessing a database, API or external system that you don't want to, or can't access from your local environment.
The Cloud Functions Emulator provides a way to inject mock versions of node modules imported into your function.
-
Enable the use of mocks in
config.js
{ ... enableMocks: true, ... }
-
Edit
mocks.js
and mock the dependencies you want// You can create handcrafted mocks, or use a mocking library var sinon = require('sinon'); /** * Called when the require() method is called * @param {String} func The name of the current function being invoked * @param {String} module The name of the module being required */ exports.onRequire = function (func, module) { // Return an object or module to override the named module argument if(module === 'redis') { // Create a mock of redis var mockRedis = sinon.mock(require("redis")); mockRedis.expects('createClient').returns({}); // Mock more methods as needed... return mockRedis; } return undefined; };
-
You don't need to change your function code at all!
exports.helloRedis = function (event, callback) { var redis = require("redis"); // <== this will be a mock client = redis.createClient(); ... };
-
If you see the following error in the console when you stop the debugger:
Assertion failed: ((err) == (0)), function Stop, file ../src/debug-agent.cc, line 155.
You can safely ignore it. It's an open issue in Node.js
-
If you restart the emulator while the debug server is running you may need to refresh the browser for the default debug breakpoint to fire.
-
Disconnecting the debugger can sometimes leave the emulator in a weird state. If you want to kill the emulator process (because it's stuck), then you'll have to kill the underlying
node
processfunctions kill
If that doesn't work, then you may need to go medieval
Mac/Linux:
pgrep -f emulator.js | xargs kill
-
If you see the following error when deploying
Error: Module version mismatch
This usually means that the module you are trying to deploy has a dependency that either conflicts with the same dependency in the emulator, but has a different version, or it indicates that the dependencies in the module being deployed was built with a different version of npm. In most cases, deleteing
node_modules
from the module being deployed and re-runningnpm install
will resolve this. -
If you see the following error when trying to invoke a function
TypeError: res.send is not a function
It means you deployed an HTTP function as a BACKGROUND function (so it's expecting an HTTP request but the emulator didn't give it one). Make sure to deploy HTTP functions with the
--trigger-http
flag. -
If the emulator times out when starting, check the logs (
logs\cloud-functions-emulator.log
)If you see the following error:
Unable to open devtools socket: address already in use
It means the chrome devtools debugger is running and using the default debug port. Close the Chrome tab with the debugger and try again.
Copyright 2016, Google, Inc.
Licensed under the Apache License, Version 2.0
See the full license.