mirror of
https://github.com/openstf/stf
synced 2025-10-03 17:59:28 +02:00
Add a simple STF console for testing without the app.
This commit is contained in:
parent
3be72ae8c9
commit
0bf07ab776
5 changed files with 222 additions and 6 deletions
21
lib/cli.js
21
lib/cli.js
|
@ -105,6 +105,27 @@ program
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('console')
|
||||||
|
.description('start console')
|
||||||
|
.option('-s, --connect-sub <endpoint>', 'sub endpoint', cliargs.list)
|
||||||
|
.option('-p, --connect-push <endpoint>', 'push endpoint', cliargs.list)
|
||||||
|
.action(function(options) {
|
||||||
|
if (!options.connectSub) {
|
||||||
|
this.missingArgument('--connect-sub')
|
||||||
|
}
|
||||||
|
if (!options.connectPush) {
|
||||||
|
this.missingArgument('--connect-push')
|
||||||
|
}
|
||||||
|
|
||||||
|
require('./roles/console')({
|
||||||
|
endpoints: {
|
||||||
|
sub: options.connectSub
|
||||||
|
, push: options.connectPush
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('local [serial..]')
|
.command('local [serial..]')
|
||||||
.description('start everything locally')
|
.description('start everything locally')
|
||||||
|
|
87
lib/roles/console.js
Normal file
87
lib/roles/console.js
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
var readline = require('readline')
|
||||||
|
|
||||||
|
var zmq = require('zmq')
|
||||||
|
var Promise = require('bluebird')
|
||||||
|
|
||||||
|
var logger = require('../util/logger')
|
||||||
|
var tx = require('../util/tx')
|
||||||
|
|
||||||
|
module.exports = function(options) {
|
||||||
|
var log = logger.createLogger('console')
|
||||||
|
|
||||||
|
// Input
|
||||||
|
var sub = zmq.socket('sub')
|
||||||
|
sub.subscribe('ALL')
|
||||||
|
options.endpoints.sub.forEach(function(endpoint) {
|
||||||
|
log.info('SUB connected to %s', endpoint)
|
||||||
|
sub.connect(endpoint)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Output
|
||||||
|
var push = zmq.socket('push')
|
||||||
|
options.endpoints.push.forEach(function(endpoint) {
|
||||||
|
log.info('PUSH connected to %s', endpoint)
|
||||||
|
push.connect(endpoint)
|
||||||
|
})
|
||||||
|
|
||||||
|
// User input
|
||||||
|
var rl = readline.createInterface({
|
||||||
|
input: process.stdin
|
||||||
|
, output: process.stdout
|
||||||
|
})
|
||||||
|
rl.setPrompt('stf> ')
|
||||||
|
rl.prompt()
|
||||||
|
|
||||||
|
rl.on('line', function(line) {
|
||||||
|
var args = line.trim().split(/\s+/g)
|
||||||
|
switch (args.shift()) {
|
||||||
|
case 'help':
|
||||||
|
console.log()
|
||||||
|
console.log('Available commands:')
|
||||||
|
console.log()
|
||||||
|
console.log(' help - show help')
|
||||||
|
console.log()
|
||||||
|
rl.prompt()
|
||||||
|
break
|
||||||
|
case 'ls':
|
||||||
|
tx.q(push, sub, 'ALL', ['ls'])
|
||||||
|
.timeout(1000)
|
||||||
|
.then(function(results) {
|
||||||
|
results.forEach(function(result) {
|
||||||
|
console.log('%s', result.serial)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(Promise.TimeoutError, function(err) {
|
||||||
|
console.log(err.message)
|
||||||
|
})
|
||||||
|
.finally(function() {
|
||||||
|
rl.prompt()
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case 'shell':
|
||||||
|
tx.q(push, sub, 'ALL', ['shell', args.join(' ')])
|
||||||
|
.timeout(1000)
|
||||||
|
.then(function(results) {
|
||||||
|
results.forEach(function(result) {
|
||||||
|
console.log('%s: %s', result.serial, result.value.toString().trim())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(Promise.TimeoutError, function(err) {
|
||||||
|
console.log(err.message)
|
||||||
|
})
|
||||||
|
.finally(function() {
|
||||||
|
rl.prompt()
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case 'exit':
|
||||||
|
case 'quit':
|
||||||
|
process.exit(0)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
console.log('Unknown command')
|
||||||
|
rl.prompt()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
|
@ -16,6 +16,10 @@ module.exports = function(options) {
|
||||||
appDealer.connect(endpoint)
|
appDealer.connect(endpoint)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
appDealer.on('message', function(channel, id, cmd) {
|
||||||
|
devDealer.send([].slice.call(arguments))
|
||||||
|
})
|
||||||
|
|
||||||
// Device side
|
// Device side
|
||||||
var devDealer = zmq.socket('dealer')
|
var devDealer = zmq.socket('dealer')
|
||||||
options.endpoints.devDealer.forEach(function(endpoint) {
|
options.endpoints.devDealer.forEach(function(endpoint) {
|
||||||
|
@ -24,6 +28,6 @@ module.exports = function(options) {
|
||||||
})
|
})
|
||||||
|
|
||||||
devDealer.on('message', function() {
|
devDealer.on('message', function() {
|
||||||
log.debug(arguments)
|
appDealer.send([].slice.call(arguments))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,34 @@ module.exports = function(options) {
|
||||||
sub.connect(endpoint)
|
sub.connect(endpoint)
|
||||||
})
|
})
|
||||||
|
|
||||||
sub.on('message', function() {
|
sub.on('message', function(channel, id, cmd) {
|
||||||
var args = [].slice.call(target)
|
push.send([id, options.serial, 'ACK'])
|
||||||
, channel = args.unshift()
|
switch (cmd.toString()) {
|
||||||
, cmd = args.unshift()
|
case 'ls':
|
||||||
|
log.info('Responding to "ls"')
|
||||||
|
push.send([id, options.serial, 'OKY'])
|
||||||
|
break
|
||||||
|
case 'shell':
|
||||||
|
var line = arguments[3]
|
||||||
|
log.info('Running shell command "%s"', line)
|
||||||
|
adb.shellAsync(options.serial, line)
|
||||||
|
.then(function(out) {
|
||||||
|
var chunks = []
|
||||||
|
out.on('data', function(chunk) {
|
||||||
|
chunks.push(chunk)
|
||||||
|
})
|
||||||
|
out.on('end', function(chunk) {
|
||||||
|
push.send([id, options.serial, 'OKY', Buffer.concat(chunks)])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
push.send([id, options.serial, 'ERR', err.message])
|
||||||
|
})
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
log.warn('Unknown command "%s"', cmd)
|
||||||
|
break
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Respond to messages directed to everyone
|
// Respond to messages directed to everyone
|
||||||
|
@ -35,7 +59,10 @@ module.exports = function(options) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Introduce worker
|
// Introduce worker
|
||||||
push.send(['HELO', options.serial])
|
// push.send(['HELO', options.serial])
|
||||||
|
|
||||||
|
// Adb
|
||||||
|
var adb = Promise.promisifyAll(adbkit.createClient())
|
||||||
|
|
||||||
function gracefullyExit() {
|
function gracefullyExit() {
|
||||||
log.info('Bye')
|
log.info('Bye')
|
||||||
|
|
77
lib/util/tx.js
Normal file
77
lib/util/tx.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
var uuid = require('node-uuid')
|
||||||
|
var Promise = require('bluebird')
|
||||||
|
|
||||||
|
function newId() {
|
||||||
|
return uuid.v4()
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.newId = newId
|
||||||
|
|
||||||
|
function q(output, input, channel, args) {
|
||||||
|
var deferred = Promise.defer()
|
||||||
|
, ourId = newId()
|
||||||
|
, results = []
|
||||||
|
, mapping = {}
|
||||||
|
, remaining = 0 // @todo pass expected number to query
|
||||||
|
|
||||||
|
function onMessage(theirId, serial, state, data) {
|
||||||
|
if (ourId === theirId.toString()) {
|
||||||
|
serial = serial.toString()
|
||||||
|
state = state.toString()
|
||||||
|
|
||||||
|
var mapped = mapping[serial]
|
||||||
|
|
||||||
|
if (!mapped) {
|
||||||
|
results.push(mapped = mapping[serial] = {
|
||||||
|
serial: serial
|
||||||
|
, state: state
|
||||||
|
, progress: 0
|
||||||
|
, value: null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mapped.state = state
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case 'ACK':
|
||||||
|
deferred.progress(results)
|
||||||
|
++remaining
|
||||||
|
break
|
||||||
|
case 'PRG':
|
||||||
|
mapped.progress = +data
|
||||||
|
deferred.progress(results)
|
||||||
|
break
|
||||||
|
case 'ERR':
|
||||||
|
mapped.value = data
|
||||||
|
--remaining
|
||||||
|
break
|
||||||
|
case 'OKY':
|
||||||
|
mapped.progress = 100
|
||||||
|
mapped.value = data
|
||||||
|
--remaining
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remaining) {
|
||||||
|
deferred.progress(results)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deferred.resolve(results)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input.on('message', onMessage)
|
||||||
|
input.subscribe(ourId)
|
||||||
|
|
||||||
|
output.send([channel, ourId].concat(args))
|
||||||
|
|
||||||
|
return deferred.promise.finally(function() {
|
||||||
|
input.unsubscribe(ourId)
|
||||||
|
input.removeListener('message', onMessage)
|
||||||
|
mapping = results = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.q = q
|
Loading…
Add table
Add a link
Reference in a new issue