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

Command persistence. fix #133, fix #127 #142

Merged
merged 8 commits into from
Jul 17, 2015
12 changes: 11 additions & 1 deletion lib/agent/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var handle_error = function(err) {
}

////////////////////////////////////////////////////////////////////
// build/parse/perform/process exports
// build/run/parse/perform/process exports

exports.build = function build(command, target, options) {
var obj = { command: command, target: target };
Expand Down Expand Up @@ -103,6 +103,8 @@ exports.perform = function(command) {
if (!command)
return handle_error(new Error('No command received'));

logger.debug("Command received: " + JSON.stringify(command));

var methods = {
'start' : actions.start,
'stop' : actions.stop,
Expand All @@ -114,6 +116,14 @@ exports.perform = function(command) {
'upgrade' : updater.check
}

// Intercept {command: 'get', target: 'report', options: {interval: 5}}
// This kind of report should be storable. To ensure it can be stored we need
// to change it to {command: 'report', target: 'stolen'}
if (command.command === "get" && command.target === "report" && command.options.interval) {
command.command = 'report';
command.target = 'stolen';
}

var type = command.command || command.name,
method = methods[type];

Expand Down
21 changes: 13 additions & 8 deletions lib/agent/plugins/control-panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,14 @@ function sync() {
if (result.settings)
update_settings(result.settings);

if (result.status && result.status.missing == true)
missing(result.status.delay);
if (result.status && result.status.missing === true) {
var opts = {
interval: result.status.delay || 20,
exclude: result.status.exclude
};

missing(opts);
}

if (result.running_actions && result.running_actions.length > 1) {
logger.warn('Restarting ' + result.running_actions.length + ' actions!');
Expand Down Expand Up @@ -141,6 +147,11 @@ function update_settings(obj) {
process(obj.local, common.config);
}

function missing(opts) {
logger.info('Holy mother of satan! Device seems to be missing!');
commands.run('report', 'stolen', opts);
}

function scan_hardware() {
commands.run('get', 'specs');
}
Expand All @@ -155,12 +166,6 @@ function load_adapter(name, cb) {
});
}

function missing(interval) {
logger.info('Holy mother of satan! Device seems to be missing!');
var interval = interval || 20;
commands.run('report', 'stolen', { interval: interval });
}

function found() {
logger.info('Device no longer missing.');
commands.run('cancel', 'stolen');
Expand Down
175 changes: 120 additions & 55 deletions lib/agent/plugins/control-panel/test/main_load.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ describe('main.load', function() {
hooks : hooks,
logger : common.logger,
config : config,
commands : { perform: function(cmd) { /* noop */ } },
helpers : { running_on_background: function() { return background } }
commands : {
perform: function(cmd) { /* noop */ },
},
helpers : { running_on_background: function() { return background } }
}

var call = function(cb) {
Expand All @@ -51,8 +53,8 @@ describe('main.load', function() {

var setup_stub;

var stub_setup = function() {
setup_stub = sinon.stub(setup, 'start', function(obk, cb) {
var stub_setup = function() {
setup_stub = sinon.stub(setup, 'start', function(obk, cb) {
cb(new Error('Setup worked, but were stopping here.'));
})
}
Expand Down Expand Up @@ -212,13 +214,13 @@ describe('main.load', function() {
needle_stub.restore();
keys_stub.restore();
done();
})
});

})
});

})
});

})
});

describe('without callback', function() {

Expand All @@ -237,9 +239,9 @@ describe('main.load', function() {
done();
}, 10);

})
});

})
});

})

Expand All @@ -250,15 +252,15 @@ describe('main.load', function() {
config.set('protocol', default_protocol);

background = false; // so we get a callback
})
});

it('calls setup()', function(done) {
call(function(err) {
should.exist(err);
err.message.should.eql('Setup worked, but were stopping here.');
done();
})
})
});
});

describe('if setup() failed', function() {

Expand All @@ -271,20 +273,20 @@ describe('main.load', function() {

before(function() {
background = true;
common.logger.pause()
common.logger.pause();

// playing with fire here!
setinterval_stub = sinon.stub(global, 'setInterval', function(fn, delay) {
if (delay === 10000)
if (delay === 10000)
setinterval_called = true;
});

})
});

after(function() {
setinterval_stub.restore(); // or heaven will fall apart
common.logger.resume()
})
common.logger.resume();
});

it ('does not callback', function(done) {
var called_back = false;
Expand All @@ -297,7 +299,7 @@ describe('main.load', function() {
called_back.should.be.false;
done();
}, 20)
})
});

it ('waits for config', function(done) {

Expand All @@ -308,7 +310,7 @@ describe('main.load', function() {
setinterval_called.should.be.true;
done();
}, 20)
})
});

})

Expand All @@ -323,73 +325,136 @@ describe('main.load', function() {
should.exist(err);
err.message.should.eql('Setup worked, but were stopping here.');
done();
})
})
});
});

})
});

})
});

describe('if setup() succeeded', function() {

var stubs = [];
var stubs = [],
status_stub;

// generic empty callback function with ultramegasuper callback position detection
var fn = function() {
var fn = function() {
var cb;

// find callback in arguments
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] == 'function')
cb = arguments[i];
}

cb && cb();
};
};

before(function() {
// first, reset the setup_stub defined at the start
setup_stub.restore();

stubs.push(sinon.stub(setup, 'start', fn))
stubs.push(sinon.stub(setup, 'start', fn));
stubs.push(sinon.stub(interval, 'load', fn));
stubs.push(sinon.stub(push, 'load', fn));
stubs.push(sinon.stub(api.devices.get, 'status', fn));
})
});

after(function() {
// now reset own own stubs
stubs.forEach(function(s) { s.restore() })

// reset the setup_stub back to original
stubs.forEach(function(s) { s.restore() });
stub_setup();
})
});

it('callsback no errors', function(done) {
describe('sync', function() {

call(function(err) {
should.not.exist(err);
done();
})
var response = {
body: {
status: {
missing: true,
delay: 2,
exclude: ['picture', 'screenshot']
}
}
};

})
before(function() {
status_stub = sinon.stub(api.devices.get, 'status', function(cb) {
return cb(null, response);
});
});

it('boots', function(done) {
after(function() {
status_stub.restore();
});

describe('when missing', function() {

it('trigger report with exclude options', function(done) {
var common_dup = {
hooks : hooks,
logger : common.logger,
config : config,
commands : {
perform: sinon.spy(),
run: sinon.spy(),
},
helpers : { running_on_background: function() { return background } }
}

common_dup.commands.perform = sinon.spy();

var missing_opts = {
interval: response.body.status.delay,
exclude: response.body.status.exclude
}

main.load.call(common_dup, function(err) {
common_dup.commands.run.callCount.should.equal(1);
common_dup.commands.run.firstCall.args[0].should.equal('report');
common_dup.commands.run.firstCall.args[1].should.equal('stolen');
common_dup.commands.run.firstCall.args[2].should.eql(missing_opts);
done();
});
});
});

call(function() {
});

// all stubs should have beenc called
stubs.forEach(function(s) {
s.called.should.be.true;
})
describe('with generic stubs', function() {

done()
})
before(function() {
status_stub = sinon.stub(api.devices.get, 'status', fn)
});

})
after(function() {
status_stub.restore();
});

})
it('callbacks with no errors', function(done) {

})
call(function(err) {
should.not.exist(err);
done();
});

});

it('boots', function(done) {

call(function() {

// all stubs should have beenc called
stubs.forEach(function(s) {
s.called.should.be.true;
});

done();
});

});

});

});

});

})
});
Loading