Skip to content
Open
13 changes: 12 additions & 1 deletion bin/blueoak-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@
* Copyright (c) 2015-2016 PointSource, LLC.
* MIT Licensed
*/
var parseArgs = require('minimist');
var server = require('../');

// parse arguments
var argv = parseArgs(process.argv.slice(2));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this work if invoked as blueoak-server?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean like this?
blueoak-server --mocks mock-service

Instead of like this?
./node_modules/blueoak-server/bin/blueoak-server.js --mocks mock-service

Yes, it works on Node v6.8.1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks


// convert mocks from CSV into an array
var mocks = argv.mocks || argv.m;
if (mocks) {
mocks = mocks.split(',');
}

server.init({
appDir: process.cwd()
appDir: process.cwd(),
mocks: mocks
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should have a different script/invocation that supports mocks instead of adding testing support directly into the main command ...
say bin/bos-mock.js

Copy link
Copy Markdown
Author

@adamrbennett adamrbennett Aug 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I know what you mean. My initial preference was to avoid modifying the main script, but I figured it doesn't add much overhead, and it might be nice to parse other CLI args in the future.

I took this approach for the simplicity and it lends itself well to Dockerization. With ENTRYPOINT ["blueoak-server"] arguments can be passed to the container at the command line more simply. For example, docker run blueoak-server --mocks mock-service instead of docker run --entrypoint bin/bos-mock.js blueoak-server --mocks mock-service

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're considering this as a foundation for future CLI, should we integrate a framework like commander instead?
(I think probably...)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, commander provides a better UX with usage output.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since mocks are used for testing/prototyping, I think it would make sense that their default directory is tests/mocks, or tests/bos-mocks/, or even tests/bos-mocks/services if it would ever make sense to have mocks for middleware or handlers (which it might)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree. Good point about mocking the other things. Only concern would be potential collisions with existing projects that already have test/s directories. While I prefer tests/mocks, I think tests/bos-mocks is far less likely to collide with code in existing projects.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah ... and it looks like test/bos-mocks is the way to go since the template project has a test dir, not a tests dir

which makes me think:

  1. should/can the mocks directory be configurable through?
  2. can/should the list of mocks be provided through configuration?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add a config to define the location of mocks, but I initially chose not to because BOS appears to favor convention over configuration for the locations of other things like handlers, services, etc.

I avoided declaring mocks in the configuration for the following reasons:

  1. To keep the config under test as similar as possible to the release/runtime config.
  2. To be able to easily control which services are mocked without changing config (i.e.: mocks won't be loaded simply because they exist or are declared, but only if they're also identified in the CLI argument). Although, this approach could still apply if mocks are declared in config.

Let me know how you'd like to proceed here and I'll make the necessary updates.

}, function(err) {
if (err) {
console.warn('Startup failed', err);
Expand Down
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ module.exports.init = function (opts, callback) {
global.__appDir = opts.appDir;
}

if (opts.mocks) {
global.__mocks = opts.mocks;
}

//Load the bootstrap services first (config and logging) since they're only needed for the master
initServices({bootstrap: true}, function (err) {
if (err) {
Expand Down Expand Up @@ -362,4 +366,3 @@ function checkNodeVersion(logger) {
module.exports.testUtility = function () {
return require('./testlib/util');
};

17 changes: 13 additions & 4 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,15 @@ function createLoader() {
debug('Loading services from %s', dir);
di.iterateOverJsFiles(dir, function(dir, file) {
var modPath = path.resolve(dir, file);

// load mock if appropriate
if (global.__mocks && _.includes(global.__mocks, file.substring(0, file.indexOf('.js')))) {
var mock = path.resolve(global.__appDir, 'mocks', file);
if (mock) {
modPath = mock;
}
}

var mod;
try {
mod = subRequire(modPath); //subRequire inserts the _id field
Expand Down Expand Up @@ -486,11 +495,11 @@ function createLoader() {
}

/*
* Strips the prefix + suffix underscores from the service name, allowing you to inject the service
* without having to think of an alternative name. For example, you can inject the logger service
* Strips the prefix + suffix underscores from the service name, allowing you to inject the service
* without having to think of an alternative name. For example, you can inject the logger service
* as "_logger_" and still be free to assign the service to the variable "logger".
*
* camelCamel strings are then coverted into dash-case. Based off of:
*
* camelCamel strings are then coverted into dash-case. Based off of:
* https://github.com/epeli/underscore.string/blob/master/dasherize.js
*/
function normalizeServiceName(str) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"express-static": "^1.0.3",
"jsonwebtoken": "^5.4.1",
"lodash": "^3.9.3",
"minimist": "^1.2.0",
"multer": "^1.1.0",
"node-cache": "^3.0.0",
"node-statsd": "^0.1.1",
Expand Down
9 changes: 9 additions & 0 deletions test/integration/fixtures/server12/config/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"express": {
"port": "5000"
},

"cluster": {
"maxWorkers": 1
}
}
8 changes: 8 additions & 0 deletions test/integration/fixtures/server12/mocks/dummyservice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright (c) 2015-2016 PointSource, LLC.
* MIT Licensed
*/
exports.init = function(logger) {
logger.info('Dummy Service Mock initialized');
process.exit(0); // exit test here
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a better test for the dummy service not to exit, but to provide a function that can be called from the test after server startup has completed

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that sounds much better. I might run into challenges but I'll do some exploration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

};
7 changes: 7 additions & 0 deletions test/integration/fixtures/server12/services/dummyservice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright (c) 2015-2016 PointSource, LLC.
* MIT Licensed
*/
exports.init = function() {
throw new Error('Dummy Service initialized');
};
13 changes: 8 additions & 5 deletions test/integration/launchUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ exports.launch = function (fixtureName, opts, done) {
opts.exec = '../../bin/blueoak-server.js';
}

var args = opts.mocks ? ['--mocks', opts.mocks] : [];

var bosPath = path.resolve(__dirname, opts.exec);
output = '';
lastLaunch = spawner(execer + bosPath,
lastLaunch = spawner(execer + bosPath, args,
{
'cwd': path.resolve(__dirname, 'fixtures/' + fixtureName),
'env': opts.env
Expand All @@ -42,13 +44,15 @@ exports.launch = function (fixtureName, opts, done) {
}
);
setTimeout(function () {
// stack traces usually start with 'Error:', if there's that pattern, return it
output = /^Error:*/m.test(output) ? output : null;
if (!opts.fullOutput) {
// stack traces usually start with 'Error:', if there's that pattern, return it
output = /^Error:*/m.test(output) ? output : null;
}
done(output);
}, 4000);
};

exports.finish = function (done) {
exports.finish = function (done) {
if (process.platform === 'win32') {
child_process.exec('taskkill /PID ' + lastLaunch.pid + ' /T /F');
}
Expand All @@ -65,4 +69,3 @@ exports.finish = function (done) {
});
}
};

23 changes: 22 additions & 1 deletion test/integration/testLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,25 @@ describe('SERVER11 - middleware should get loaded from node modules', function (
done();
});
});
});
});

describe('SERVER12 - mocks should get loaded when specified by the --mocks command line argument', function () {
this.timeout(5000);

after(function (done) {
util.finish(done);
});

it('Launch server and load mocks', function (done) {
util.launch('server12',
{
appDir: path.resolve(__dirname, 'fixtures/server12'),
mocks: 'dummyservice',
fullOutput: true
}, function(output) {
assert.ok(output.indexOf('Dummy Service Mock initialized') > -1);
assert.ok(output.indexOf('Dummy Service initialized') < 0);
done();
});
});
});