mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2026-10-04 02:04:22 +00:00
Compare commits
18
Commits
v0.4.0
...
v0.5-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7bf420dd6 | ||
|
|
55b02c924f | ||
|
|
df02837c82 | ||
|
|
e3963bf057 | ||
|
|
238f3fe05a | ||
|
|
51e926629c | ||
|
|
3df94ced57 | ||
|
|
62063a7250 | ||
|
|
3d58fdd242 | ||
|
|
12ba6b3968 | ||
|
|
ae8469cfee | ||
|
|
bf7c09fc83 | ||
|
|
4476c233ff | ||
|
|
45883238e1 | ||
|
|
471f3dc0bb | ||
|
|
5ba9058216 | ||
|
|
6f82454be2 | ||
|
|
5f60580040 |
+1
-1
@@ -8,7 +8,7 @@
|
||||
"jsx": false,
|
||||
"modules": false
|
||||
},
|
||||
"ecmaVersion": 2017
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"plugins": ["promise"],
|
||||
"rules": {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
- run: npm install
|
||||
- run: npm run jslint
|
||||
- run: npm test
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
sudo: required
|
||||
language: node_js
|
||||
node_js:
|
||||
- "lts/*"
|
||||
services:
|
||||
- docker
|
||||
- mysql
|
||||
script:
|
||||
- npm test
|
||||
+10
-7
@@ -1,13 +1,16 @@
|
||||
FROM node:lts-alpine
|
||||
FROM node:alpine as builder
|
||||
RUN apk update && apk add --no-cache python make g++
|
||||
WORKDIR /opt/app/
|
||||
COPY package.json ./
|
||||
RUN npm install
|
||||
RUN npm prune
|
||||
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
FROM node:alpine as app
|
||||
WORKDIR /opt/app
|
||||
COPY . /opt/app
|
||||
COPY --from=builder /opt/app/node_modules ./node_modules
|
||||
|
||||
ARG NODE_ENV
|
||||
ENV NODE_ENV $NODE_ENV
|
||||
|
||||
COPY package.json /usr/src/app/
|
||||
RUN npm install
|
||||
COPY . /usr/src/app
|
||||
|
||||
CMD [ "npm", "start" ]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# sbc-inbound [](http://travis-ci.org/jambonz/sbc-inbound)
|
||||
# sbc-inbound 
|
||||
|
||||
This application provides a part of the SBC (Session Border Controller) functionality of jambonz. It handles incoming INVITE requests from carrier sip trunks or from sip devices and webrtc applications. SIP INVITEs from known carriers are allowed in, while INVITEs from sip devices are challenged to authenticate. SIP traffic that is allowed in is sent on to a jambonz application server in a private subnet.
|
||||
|
||||
|
||||
+45
-24
@@ -13,8 +13,8 @@ const MS_TEAMS_SIP_ENDPOINT = 'sip.pstnhub.microsoft.com';
|
||||
const createBLegFromHeader = (req) => {
|
||||
const from = req.getParsedHeader('From');
|
||||
const uri = parseUri(from.uri);
|
||||
if (uri && uri.user) return `sip:${uri.user}@localhost`;
|
||||
return 'sip:anonymous@localhost';
|
||||
if (uri && uri.user) return `<sip:${uri.user}@localhost>`;
|
||||
return '<sip:anonymous@localhost>';
|
||||
};
|
||||
|
||||
class CallSession extends Emitter {
|
||||
@@ -79,7 +79,13 @@ class CallSession extends Emitter {
|
||||
this.logger.info(`uri will be: ${uri}, proxy ${proxy}`);
|
||||
|
||||
try {
|
||||
const opts = Object.assign(this.rtpEngineOpts.offer, {sdp: this.req.body});
|
||||
const opts = {
|
||||
...this.rtpEngineOpts.common,
|
||||
...this.rtpEngineOpts.uac.mediaOpts,
|
||||
'from-tag': this.rtpEngineOpts.uas.tag,
|
||||
direction: ['public', 'private'],
|
||||
sdp: this.req.body
|
||||
};
|
||||
const response = await this.offer(opts);
|
||||
this.logger.debug({opts, response}, 'response from rtpengine to offer');
|
||||
if ('ok' !== response.result) {
|
||||
@@ -129,8 +135,14 @@ class CallSession extends Emitter {
|
||||
proxyResponseHeaders: ['all'],
|
||||
localSdpB: response.sdp,
|
||||
localSdpA: async(sdp, res) => {
|
||||
this.toTag = res.getParsedHeader('To').params.tag;
|
||||
const opts = Object.assign(this.rtpEngineOpts.answer, {sdp, 'to-tag': this.toTag});
|
||||
this.rtpEngineOpts.uac.tag = res.getParsedHeader('To').params.tag;
|
||||
const opts = {
|
||||
...this.rtpEngineOpts.common,
|
||||
...this.rtpEngineOpts.uas.mediaOpts,
|
||||
'from-tag': this.rtpEngineOpts.uas.tag,
|
||||
'to-tag': this.rtpEngineOpts.uac.tag,
|
||||
sdp
|
||||
};
|
||||
const response = await this.answer(opts);
|
||||
if ('ok' !== response.result) {
|
||||
this.logger.error(`rtpengine answer failed with ${JSON.stringify(response)}`);
|
||||
@@ -190,8 +202,8 @@ class CallSession extends Emitter {
|
||||
});
|
||||
});
|
||||
uas.on('modify', this._onReinvite.bind(this, uas));
|
||||
uac.on('modify', this._onReinvite.bind(this, uac));
|
||||
|
||||
uac.on('modify', this._onFeatureServerReinvite.bind(this, uac));
|
||||
uac.on('refer', this._onFeatureServerTransfer.bind(this, uac));
|
||||
uas.on('refer', this._onRefer.bind(this, uas));
|
||||
|
||||
@@ -253,41 +265,50 @@ class CallSession extends Emitter {
|
||||
|
||||
async _onReinvite(dlg, req, res) {
|
||||
try {
|
||||
let opts = Object.assign(this.rtpEngineOpts.offer, {sdp: req.body, 'to-tag': this.toTag});
|
||||
/* check for re-invite with no SDP -- seen that from BT when they provide UUI info */
|
||||
if (!req.body) {
|
||||
this.logger.info('got a reINVITE with no SDP; just respond with our current offer');
|
||||
res.send(200, {body: dlg.local.sdp});
|
||||
return;
|
||||
}
|
||||
const fromTag = dlg.type === 'uas' ? this.rtpEngineOpts.uas.tag : this.rtpEngineOpts.uac.tag;
|
||||
const toTag = dlg.type === 'uas' ? this.rtpEngineOpts.uac.tag : this.rtpEngineOpts.uas.tag;
|
||||
const offerMedia = dlg.type === 'uas' ? this.rtpEngineOpts.uac.mediaOpts : this.rtpEngineOpts.uas.mediaOpts;
|
||||
const answerMedia = dlg.type === 'uas' ? this.rtpEngineOpts.uas.mediaOpts : this.rtpEngineOpts.uac.mediaOpts;
|
||||
const direction = dlg.type === 'uas' ? ['public', 'private'] : ['private', 'public'];
|
||||
let opts = {
|
||||
...this.rtpEngineOpts.common,
|
||||
...offerMedia,
|
||||
'from-tag': fromTag,
|
||||
'to-tag': toTag,
|
||||
direction,
|
||||
sdp: req.body,
|
||||
};
|
||||
|
||||
let response = await this.offer(opts);
|
||||
if ('ok' !== response.result) {
|
||||
res.send(488);
|
||||
throw new Error(`_onReinvite: rtpengine failed: offer: ${JSON.stringify(response)}`);
|
||||
}
|
||||
this.logger.info({opts, response}, 'sent offer for reinvite to rtpengine');
|
||||
const sdp = await dlg.other.modify(response.sdp);
|
||||
opts = Object.assign(this.rtpEngineOpts.answer, {sdp});
|
||||
opts = {
|
||||
...this.rtpEngineOpts.common,
|
||||
...answerMedia,
|
||||
'from-tag': fromTag,
|
||||
'to-tag': toTag,
|
||||
sdp
|
||||
};
|
||||
response = await this.answer(opts);
|
||||
if ('ok' !== response.result) {
|
||||
res.send(488);
|
||||
throw new Error(`_onReinvite: rtpengine failed: ${JSON.stringify(response)}`);
|
||||
}
|
||||
this.logger.info({opts, response}, 'sent answer for reinvite to rtpengine');
|
||||
res.send(200, {body: response.sdp});
|
||||
} catch (err) {
|
||||
this.logger.error(err, 'Error handling reinvite');
|
||||
}
|
||||
}
|
||||
|
||||
async _onFeatureServerReinvite(dlg, req, res) {
|
||||
try {
|
||||
const opts = Object.assign(this.rtpEngineOpts.answer, {sdp: req.body, 'to-tag': this.toTag});
|
||||
const response = await this.answer(opts);
|
||||
if ('ok' !== response.result) {
|
||||
res.send(488);
|
||||
throw new Error(`_onFeatureServerReinvite: rtpengine failed: ${JSON.stringify(response)}`);
|
||||
}
|
||||
res.send(200, {body: dlg.local.sdp});
|
||||
} catch (err) {
|
||||
this.logger.error(err, 'Error handling reinvite from feature server');
|
||||
}
|
||||
}
|
||||
|
||||
async _onFeatureServerTransfer(dlg, req, res) {
|
||||
try {
|
||||
const referTo = req.getParsedHeader('Refer-To');
|
||||
|
||||
+4
-2
@@ -1,7 +1,9 @@
|
||||
const debug = require('debug')('jambonz:sbc-inbound');
|
||||
const Emitter = require('events');
|
||||
const parseUri = require('drachtio-srf').parseUri;
|
||||
const msProxyIps = process.env.MS_TEAMS_SIP_PROXY_IPS ? process.env.MS_TEAMS_SIP_PROXY_IPS.split(',').map((i) => i.trim()) : [];
|
||||
const msProxyIps = process.env.MS_TEAMS_SIP_PROXY_IPS ?
|
||||
process.env.MS_TEAMS_SIP_PROXY_IPS.split(',').map((i) => i.trim()) :
|
||||
[];
|
||||
|
||||
class AuthOutcomeReporter extends Emitter {
|
||||
constructor(stats) {
|
||||
@@ -15,7 +17,7 @@ class AuthOutcomeReporter extends Emitter {
|
||||
module.exports = function(srf, logger) {
|
||||
const {lookupSipGatewayBySignalingAddress, lookupAuthHook} = srf.locals.dbHelpers;
|
||||
const {stats} = srf.locals;
|
||||
const authenticator = require('jambonz-http-authenticator')(lookupAuthHook, logger, {
|
||||
const authenticator = require('@jambonz/http-authenticator')(lookupAuthHook, logger, {
|
||||
blacklistUnknownRealms: true,
|
||||
emitter: new AuthOutcomeReporter(stats)
|
||||
});
|
||||
|
||||
+15
-11
@@ -12,20 +12,24 @@ function getAppserver(srf) {
|
||||
}
|
||||
|
||||
function makeRtpEngineOpts(req, srcIsUsingSrtp, dstIsUsingSrtp, teams = false) {
|
||||
const srtpOpts = teams ? srtpCharacteristics['teams'] : srtpCharacteristics['default'];
|
||||
const from = req.getParsedHeader('from');
|
||||
const common = {'call-id': req.get('Call-ID'), 'from-tag': from.params.tag};
|
||||
const srtpOpts = teams ? srtpCharacteristics['teams'] : srtpCharacteristics['default'];
|
||||
const dstOpts = dstIsUsingSrtp ? srtpOpts : rtpCharacteristics;
|
||||
const srctOpts = srcIsUsingSrtp ? srtpOpts : rtpCharacteristics;
|
||||
const common = {
|
||||
'call-id': req.get('Call-ID'),
|
||||
'replace': ['origin', 'session-connection']
|
||||
};
|
||||
return {
|
||||
common,
|
||||
offer: Object.assign(
|
||||
{'sdp': req.body, 'replace': ['origin', 'session-connection']},
|
||||
{'direction': [ 'public', 'private']},
|
||||
common,
|
||||
dstIsUsingSrtp ? srtpOpts : rtpCharacteristics),
|
||||
answer: Object.assign(
|
||||
{'replace': ['origin', 'session-connection']},
|
||||
common,
|
||||
srcIsUsingSrtp ? srtpOpts : rtpCharacteristics)
|
||||
uas: {
|
||||
tag: from.params.tag,
|
||||
mediaOpts: srctOpts
|
||||
},
|
||||
uac: {
|
||||
tag: null,
|
||||
mediaOpts: dstOpts
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Generated
+5451
-1163
File diff suppressed because it is too large
Load Diff
+9
-9
@@ -20,26 +20,26 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node app",
|
||||
"test": "NODE_ENV=test JAMBONES_MYSQL_HOST=localhost JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=error DRACHTIO_SECRET=cymru DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 JAMBONES_RTPENGINES=127.0.0.1:12222 JAMBONES_FEATURE_SERVERS=172.38.0.11 node test/ | ./node_modules/.bin/tap-spec",
|
||||
"test": "NODE_ENV=test JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=error DRACHTIO_SECRET=cymru DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 JAMBONES_RTPENGINES=127.0.0.1:12222 JAMBONES_FEATURE_SERVERS=172.38.0.11 node test/ | ./node_modules/.bin/tap-spec",
|
||||
"coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test",
|
||||
"jslint": "eslint app.js lib"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jambonz/db-helpers": "^0.4.2",
|
||||
"@jambonz/realtimedb-helpers": "0.2.16",
|
||||
"@jambonz/db-helpers": "^0.5.12",
|
||||
"@jambonz/http-authenticator": "^0.1.6",
|
||||
"@jambonz/realtimedb-helpers": "^0.2.20",
|
||||
"@jambonz/rtpengine-utils": "^0.1.7",
|
||||
"@jambonz/stats-collector": "0.0.4",
|
||||
"debug": "^4.1.1",
|
||||
"@jambonz/stats-collector": "^0.1.4",
|
||||
"debug": "^4.3.1",
|
||||
"drachtio-fn-b2b-sugar": "0.0.12",
|
||||
"drachtio-srf": "^4.4.37",
|
||||
"jambonz-http-authenticator": "0.1.5",
|
||||
"pino": "^6.5.1",
|
||||
"drachtio-srf": "^4.4.44",
|
||||
"pino": "^6.8.0",
|
||||
"rtpengine-client": "^0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"blue-tape": "^1.0.0",
|
||||
"clear-module": "^4.1.1",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint": "^7.15.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"nyc": "^15.1.0",
|
||||
"tap-spec": "^5.0.0"
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
const test = require('tape').test ;
|
||||
const exec = require('child_process').exec ;
|
||||
const pwd = process.env.TRAVIS ? '' : '-p$MYSQL_ROOT_PASSWORD';
|
||||
|
||||
test('creating jambones_test database', (t) => {
|
||||
exec(`mysql -h localhost -u root ${pwd} < ${__dirname}/db/create_test_db.sql`, (err, stdout, stderr) => {
|
||||
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp < ${__dirname}/db/create_test_db.sql`, (err, stdout, stderr) => {
|
||||
if (err) return t.end(err);
|
||||
t.pass('database successfully created');
|
||||
t.end();
|
||||
@@ -11,7 +10,7 @@ test('creating jambones_test database', (t) => {
|
||||
});
|
||||
|
||||
test('creating schema', (t) => {
|
||||
exec(`mysql -h localhost -u root ${pwd} -D jambones_test < ${__dirname}/db/jambones-sql.sql`, (err, stdout, stderr) => {
|
||||
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp -D jambones_test < ${__dirname}/db/jambones-sql.sql`, (err, stdout, stderr) => {
|
||||
if (err) return t.end(err);
|
||||
t.pass('schema successfully created');
|
||||
t.end();
|
||||
@@ -19,7 +18,7 @@ test('creating schema', (t) => {
|
||||
});
|
||||
|
||||
test('populating test case data', (t) => {
|
||||
exec(`mysql -h localhost -u root ${pwd} -D jambones_test < ${__dirname}/db/populate-test-data.sql`, (err, stdout, stderr) => {
|
||||
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp -D jambones_test < ${__dirname}/db/populate-test-data.sql`, (err, stdout, stderr) => {
|
||||
if (err) return t.end(err);
|
||||
t.pass('test data set created');
|
||||
t.end();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
create database jambones_test;
|
||||
create user jambones_test@localhost IDENTIFIED WITH mysql_native_password by 'jambones_test';
|
||||
grant all on jambones_test.* to jambones_test@localhost;
|
||||
create user jambones_test@'%' IDENTIFIED WITH mysql_native_password by 'jambones_test';
|
||||
grant all on jambones_test.* to jambones_test@'%';
|
||||
|
||||
@@ -55,8 +55,8 @@ api_key_sid CHAR(36) NOT NULL UNIQUE ,
|
||||
token CHAR(36) NOT NULL UNIQUE ,
|
||||
account_sid CHAR(36),
|
||||
service_provider_sid CHAR(36),
|
||||
expires_at TIMESTAMP NULL,
|
||||
last_used TIMESTAMP NULL,
|
||||
expires_at TIMESTAMP NULL DEFAULT NULL,
|
||||
last_used TIMESTAMP NULL DEFAULT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (api_key_sid)
|
||||
) ENGINE=InnoDB COMMENT='An authorization token that is used to access the REST api';
|
||||
@@ -98,6 +98,10 @@ description VARCHAR(255),
|
||||
account_sid CHAR(36) COMMENT 'if provided, indicates this entity represents a customer PBX that is associated with a specific account',
|
||||
application_sid CHAR(36) COMMENT 'If provided, all incoming calls from this source will be routed to the associated application',
|
||||
e164_leading_plus BOOLEAN NOT NULL DEFAULT false,
|
||||
requires_register BOOLEAN NOT NULL DEFAULT false,
|
||||
register_username VARCHAR(64),
|
||||
register_sip_realm VARCHAR(64),
|
||||
register_password VARCHAR(64),
|
||||
PRIMARY KEY (voip_carrier_sid)
|
||||
) ENGINE=InnoDB COMMENT='A Carrier or customer PBX that can send or receive calls';
|
||||
|
||||
@@ -148,8 +152,9 @@ CREATE TABLE applications
|
||||
application_sid CHAR(36) NOT NULL UNIQUE ,
|
||||
name VARCHAR(64) NOT NULL,
|
||||
account_sid CHAR(36) NOT NULL COMMENT 'account that this application belongs to',
|
||||
call_hook_sid CHAR(36) COMMENT 'webhook to call for inbound calls to phone numbers owned by this account',
|
||||
call_hook_sid CHAR(36) COMMENT 'webhook to call for inbound calls ',
|
||||
call_status_hook_sid CHAR(36) COMMENT 'webhook to call for call status events',
|
||||
messaging_hook_sid CHAR(36) COMMENT 'webhook to call for inbound SMS/MMS ',
|
||||
speech_synthesis_vendor VARCHAR(64) NOT NULL DEFAULT 'google',
|
||||
speech_synthesis_language VARCHAR(12) NOT NULL DEFAULT 'en-US',
|
||||
speech_synthesis_voice VARCHAR(64),
|
||||
@@ -242,6 +247,8 @@ ALTER TABLE applications ADD FOREIGN KEY call_hook_sid_idxfk (call_hook_sid) REF
|
||||
|
||||
ALTER TABLE applications ADD FOREIGN KEY call_status_hook_sid_idxfk (call_status_hook_sid) REFERENCES webhooks (webhook_sid);
|
||||
|
||||
ALTER TABLE applications ADD FOREIGN KEY messaging_hook_sid_idxfk (messaging_hook_sid) REFERENCES webhooks (webhook_sid);
|
||||
|
||||
CREATE INDEX service_provider_sid_idx ON service_providers (service_provider_sid);
|
||||
CREATE INDEX name_idx ON service_providers (name);
|
||||
CREATE INDEX root_domain_idx ON service_providers (root_domain);
|
||||
|
||||
@@ -7,7 +7,7 @@ values ('ed649e33-e771-403a-8c99-1780eabbc803', '3f35518f-5a0d-4c2e-90a5-2407bb3
|
||||
|
||||
insert into voip_carriers (voip_carrier_sid, name) values ('287c1452-620d-4195-9f19-c9814ef90d78', 'westco');
|
||||
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, inbound, outbound)
|
||||
values ('124a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', '172.38.0.20', true, true);
|
||||
values ('124a5339-c62c-4075-9e19-f4de70a96597', '287c1452-620d-4195-9f19-c9814ef90d78', '172.38.0.20/32', true, true);
|
||||
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound)
|
||||
values ('efbc4830-57cd-4c78-a56f-d64fdf210fe8', '287c1452-620d-4195-9f19-c9814ef90d78', '3.3.3.3', 5062, false, true);
|
||||
|
||||
|
||||
@@ -7,7 +7,20 @@ networks:
|
||||
config:
|
||||
- subnet: 172.38.0.0/16
|
||||
|
||||
services:
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "--protocol", "tcp"]
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
networks:
|
||||
sbc-inbound:
|
||||
ipv4_address: 172.38.0.2
|
||||
sbc:
|
||||
image: drachtio/drachtio-server:latest
|
||||
command: drachtio --contact "sip:*;transport=udp" --loglevel debug --sofia-loglevel 9
|
||||
@@ -16,6 +29,9 @@ services:
|
||||
networks:
|
||||
sbc-inbound:
|
||||
ipv4_address: 172.38.0.10
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
|
||||
appserver:
|
||||
image: drachtio/sipp:latest
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require('./docker_start');
|
||||
require('./create-test-db');
|
||||
require('./sip-tests');
|
||||
require('./remove-test-db');
|
||||
require('./docker_stop');
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
const test = require('tape').test ;
|
||||
const exec = require('child_process').exec ;
|
||||
const pwd = process.env.TRAVIS ? '' : '-p$MYSQL_ROOT_PASSWORD';
|
||||
|
||||
test('dropping jambones_test database', (t) => {
|
||||
exec(`mysql -h localhost -u root ${pwd} < ${__dirname}/db/remove_test_db.sql`, (err, stdout, stderr) => {
|
||||
if (err) return t.end(err);
|
||||
t.pass('database successfully dropped');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
const { spawn } = require('child_process');
|
||||
const debug = require('debug')('test:sipp');
|
||||
const debug = require('debug')('jambonz:ci');
|
||||
let network;
|
||||
const obj = {};
|
||||
let output = '';
|
||||
@@ -27,7 +27,7 @@ obj.output = () => {
|
||||
obj.sippUac = (file, bindAddress) => {
|
||||
const cmd = 'docker';
|
||||
const args = [
|
||||
'run', '-ti', '--rm', '--net', `${network}`,
|
||||
'run', '--rm', '--net', `${network}`,
|
||||
'-v', `${__dirname}/scenarios:/tmp/scenarios`,
|
||||
'drachtio/sipp', 'sipp', '-sf', `/tmp/scenarios/${file}`,
|
||||
'-m', '1',
|
||||
@@ -37,7 +37,7 @@ obj.sippUac = (file, bindAddress) => {
|
||||
'sbc'
|
||||
];
|
||||
|
||||
if (bindAddress) args.splice(5, 0, '--ip', bindAddress);
|
||||
if (bindAddress) args.splice(4, 0, '--ip', bindAddress);
|
||||
|
||||
//console.log(args.join(' '));
|
||||
clearOutput();
|
||||
@@ -57,11 +57,11 @@ obj.sippUac = (file, bindAddress) => {
|
||||
});
|
||||
|
||||
child_process.stdout.on('data', (data) => {
|
||||
//debug(`stdout: ${data}`);
|
||||
debug(`stderr: ${data}`);
|
||||
addOutput(data.toString());
|
||||
});
|
||||
child_process.stdout.on('data', (data) => {
|
||||
//debug(`stdout: ${data}`);
|
||||
child_process.stderr.on('data', (data) => {
|
||||
debug(`stderr: ${data}`);
|
||||
addOutput(data.toString());
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user