UNPKG

msgflo

Version:

Polyglot FBP runtime based on message queues

141 lines (113 loc) 4.24 kB
msgflo = require '../' path = require 'path' chai = require 'chai' unless chai child_process = require 'child_process' debug = require('debug')('msgflo:spec:heterogenous') python = process.env.PYTHON or 'python' foreignParticipants = # 'PythonRepeat': [python, path.join __dirname, 'fixtures', './repeat.py'] # 'CppRepeat': [python, path.join __dirname, 'fixtures', './repeat-cpp'] # TODO: use setup.participant + Library code startProcess = (args, callback) -> prog = args[0] args = args.slice(1) debug 'starting', prog, args.join(' ') child = child_process.spawn prog, args debug 'started PID', child.pid returned = false child.on 'error', (err) -> debug 'error', err return if returned returned = true return callback err # We assume that when somethis is send on stdout, starting is complete child.stdout.on 'data', (data) -> debug 'stdout', data.toString() return if returned returned = true return callback null child.stderr.on 'data', (data) -> debug 'stderr', data.toString() return if returned returned = true return callback new Error data.toString() return child startForeign = (commands, name, callback) -> args = commands[name] return startProcess args, callback exports.testParticipant = testParticipant = (state, name) -> state.repeat = { bar: 'foo' } if typeof state.repeat == 'undefined' describe "#{name} participant", -> participant = null definitions = null onParticipantDiscovered = null waitDefinition = (waitForComponent, cb) -> checkAndCallback = () -> console.log 'disc', definitions.length, waitForComponent, definitions for def in definitions if def.component == waitForComponent return cb def checkAndCallback() onParticipantDiscovered = checkAndCallback beforeEach (done) -> @timeout 4000 definitions = [] onDiscovery = (msg) -> def = msg.data definitions.push def state.broker.ackMessage msg if typeof onParticipantDiscovered == 'function' onParticipantDiscovered def, definitions state.broker.subscribeParticipantChange onDiscovery participant = startForeign state.commands, name, done afterEach (done) -> participant.kill() done() describe 'when started', -> it 'sends definition on fbp queue', (done) -> waitDefinition name, (def) -> chai.expect(def).to.be.an 'object' chai.expect(def).to.have.keys ['id', 'icon', 'role', 'component', 'label', 'inports', 'outports'] done() describe 'sending data on inport queue', -> @timeout 4000 it 'repeats the same data on outport queue', (done) -> broker = state.broker onReceive = (msg) -> broker.ackMessage msg chai.expect(msg.data).to.eql state.repeat done() # TODO: look up in definition waitDefinition name, (def) -> inQueue = null outQueue = null for port in def.inports inQueue = port.queue if port.id == 'in' for port in def.outports outQueue = port.queue if port.id == 'out' receiveQueue = 'test.RECEIVE' binding = { type: 'pubsub', src: outQueue, tgt: receiveQueue } send = () -> broker.sendTo 'inqueue', inQueue, state.repeat, (err) -> chai.expect(err).to.not.exist broker.createQueue 'inqueue', receiveQueue, (err) -> chai.expect(err).to.not.exist broker.addBinding binding, (err) -> chai.expect(err).to.not.exist broker.subscribeToQueue receiveQueue, onReceive, (err) -> chai.expect(err).to.not.exist setTimeout send, 1000 # HACK: wait for inqueue to be setup describe 'Heterogenous', -> address = 'amqp://localhost' g = broker: null commands: foreignParticipants repeat: undefined # default beforeEach (done) -> g.broker = msgflo.transport.getBroker address g.broker.connect done afterEach (done) -> g.broker.disconnect done names = Object.keys g.commands names.forEach (name) -> testParticipant g, name