1
0
Fork 0
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:
Simo Kinnunen 2014-01-14 18:41:48 +09:00
parent 3be72ae8c9
commit 0bf07ab776
5 changed files with 222 additions and 6 deletions

View file

@ -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
View 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
}
})
}

View file

@ -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))
}) })
} }

View file

@ -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
View 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