Skip to content
This repository has been archived by the owner on May 15, 2019. It is now read-only.

Commit

Permalink
Feature deploy checks (#7)
Browse files Browse the repository at this point in the history
* Added check to ensure module path is a directory.  Updated README to be more explicit

* Updated version number and changelog
  • Loading branch information
jasonpolites authored and jmdobry committed Nov 23, 2016
1 parent f66c1b9 commit d058e82
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 47 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
##### 0.3.1 - 23 November 2016

Adds checks to deploy command to ensure module path is a directory
Adds more clarity to README for deploy command

##### 0.1.0 - 24 October 2016

Initial Release
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ 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
functions deploy <module path> <function name> --trigger-http

For example:

functions deploy ~/myModule helloWorld --trigger-http

This would deploy the `helloWorld` function in the Node module contained in the `~/myModule` path.

*Note: The module path should be a directory containing the Node module you want to deploy*

### Invoking a Function

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@google-cloud/functions-emulator",
"description": "Google Cloud Functions Emulator",
"version": "0.3.0",
"version": "0.3.1",
"license": "Apache-2.0",
"author": "Google Inc.",
"engines": {
Expand Down
94 changes: 54 additions & 40 deletions src/emulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,57 +200,71 @@ var self = {
var p = req.query.path;
var name = req.params.name;

console.debug('Loading module in path ' + p);
var mod = null;

// Ensure the path is a directory
try {
// Make sure we remove the module from cache first to capture any changes
self._unrequire(p);
mod = require(p);
} catch (err) {
console.error(err);
if (!fs.lstatSync(p).isDirectory()) {
res.status(400).send('\nModule specified is not a directory\n');
return;
}

res.status(400).send(
'\nFailed to require module being deployed. Make sure your module compiles and you have run `npm install` on it first\n' +
err.stack);
return;
}
console.debug('Loading module in path ' + p);

if (!mod[name]) {
res.status(404).send('\nNo function found in module ' + p +
' with name ' + name);
return;
}
var mod = null;

var type = req.query.type.toUpperCase();
var url = null;
try {
// Make sure we remove the module from cache first to capture any changes
self._unrequire(p);
mod = require(p);
} catch (err) {
console.error(err);

if (type === 'B') {
type = 'BACKGROUND';
} else if (type === 'H') {
type = 'HTTP';
}
res.status(400).send(
'\nFailed to require module being deployed. Make sure your module compiles and you have run `npm install` on it first\n' +
err.stack);
return;
}

if (type === 'HTTP') {
url = 'http://localhost:' + config.port + '/' + name;
}
if (!mod[name]) {
res.status(404).send('\nNo function found in module ' + p +
' with name ' + name);
return;
}

try {
self._functions[name] = {
name: name,
path: p,
type: type,
url: url
};
var type = req.query.type.toUpperCase();
var url = null;

jsonfile.writeFileSync(self._functionsFile, self._functions);
if (type === 'B') {
type = 'BACKGROUND';
} else if (type === 'H') {
type = 'HTTP';
}

console.debug('Deployed function ' + name + ' at path ' + p);
if (type === 'HTTP') {
url = 'http://localhost:' + config.port + '/' + name;
}

res.json(self._functions[name]);
try {
self._functions[name] = {
name: name,
path: p,
type: type,
url: url
};

jsonfile.writeFileSync(self._functionsFile, self._functions);

console.debug('Deployed function ' + name + ' at path ' + p);

res.json(self._functions[name]);
} catch (err) {
console.debug(err.stack);
res.status(400).send(err.message);
}
} catch (err) {
console.debug(err.stack);
res.status(400).send(err.message);
console.error(err);
res.status(400).send(
'\nFailed during module path check\n' +
err.stack);
}
});

Expand Down
31 changes: 26 additions & 5 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@

'use strict';

var chai = require('chai');
var path = require('path');
var controller = require('../src/controller.js');

var PROJECT_ID = 'foobar';
const chai = require('chai');
const path = require('path');
const controller = require('../src/controller.js');
const fs = require('fs');
const PROJECT_ID = 'foobar';

// Empty writer
controller.writer = {
Expand Down Expand Up @@ -163,6 +163,27 @@ describe('Cloud Functions Emulator Tests', function () {
});
});

it('Fails deployment when the module path is not a directory', function (done) {
var filePath = path.join(TEST_MODULE, 'index.js');

// Ensure the file exists so we know the failure is for the right reason
try {
if (fs.lstatSync(filePath).isFile()) {
controller.deploy(filePath, 'hello', {}, function (err) {
if (err) {
done();
return;
}
done(new Error("Deployment should have failed but didn't"));
});
} else {
done(new Error('Test does not use a file path as the input to the deploy command'));
}
} catch (e) {
done(e);
}
});

it('Returns the expected values in the list after deployment', function (done) {
controller.deploy(TEST_MODULE, 'hello', 'B', function (err) {
if (err) {
Expand Down

0 comments on commit d058e82

Please sign in to comment.