add testcase

This commit is contained in:
Quan HL
2023-03-05 21:41:54 +07:00
parent e363ec2592
commit 432abd6367
6 changed files with 1250 additions and 10 deletions

View File

@@ -1,10 +1,20 @@
version: '3'
version: '3.9'
networks:
speech-utils:
driver: bridge
ipam:
config:
- subnet: 172.41.0.0/16
services:
redis:
image: redis:alpine
ports:
- "3379:6379"
networks:
speech-utils:
ipv4_address: 172.41.0.5
redis-auth:
image: redis:alpine
@@ -13,3 +23,17 @@ services:
- "3380:6379"
volumes:
- ./tmp:/tmp
networks:
speech-utils:
ipv4_address: 172.41.0.6
webhook-tts-scaffold:
image: jambonz/webhook-tts-test-scaffold:latest
ports:
- "3100:3000/tcp"
volumes:
- ./test-apps:/tmp
networks:
speech-utils:
ipv4_address: 172.41.0.10

View File

@@ -4,6 +4,8 @@ const opts = config.get('redis');
const fs = require('fs');
const {makeSynthKey} = require('../lib/utils');
const logger = require('pino')();
const bent = require('bent');
const getJSON = bent('json')
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
@@ -330,36 +332,42 @@ test('Custom Vendor speech synth tests', async(t) => {
const fn = require('..');
const {synthAudio, client} = fn(opts, logger);
if (!process.env.CUSTOM_VENDOR_TTS_URL) {
t.pass('skipping Custom Vendor speech synth tests since CUSTOM_VENDOR_TTS_URL not provided');
return t.end();
}
try {
let opts = await synthAudio(stats, {
vendor: 'custom:somethingnew',
credentials: {
use_for_tts: 1,
custom_tts_url: process.env.CUSTOM_VENDOR_TTS_URL,
custom_tts_url: "http://172.41.0.10:3000/somethingnew",
auth_token: 'some_jwt_token'
},
language: 'en-US',
voice: 'English-US.Female-1',
text: 'This is a test. This is only a test',
});
t.ok(!opts.servedFromCache, `successfully synthesized nuance audio to ${opts.filePath}`);
t.ok(!opts.servedFromCache, `successfully synthesized custom vendor audio to ${opts.filePath}`);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/somethingnew`);
t.ok(obj.headers.Authorization == 'Bearer some_jwt_token', 'Custom Vendor Authentication Header is correct');
t.ok(obj.body.language == 'en-US', 'Custom Vendor Language is correct');
t.ok(obj.body.format == 'audio/mpeg', 'Custom Vendor format is correct');
t.ok(obj.body.voice == 'English-US.Female-1', 'Custom Vendor voice is correct');
t.ok(obj.body.type == 'text', 'Custom Vendor type is correct');
t.ok(obj.body.text == 'This is a test. This is only a test', 'Custom Vendor text is correct');
opts = await synthAudio(stats, {
vendor: 'custom:somethingnew',
vendor: 'custom:somethingnew2',
credentials: {
use_for_tts: 1,
custom_tts_url: process.env.CUSTOM_VENDOR_TTS_URL,
custom_tts_url: "http://172.41.0.10:3000/somethingnew2",
auth_token: 'some_jwt_token'
},
language: 'en-US',
voice: 'English-US.Female-1',
text: '<speak>This is a test. This is only a test</speak>',
});
t.ok(!opts.servedFromCache, `successfully synthesized nuance audio to ${opts.filePath}`);
t.ok(!opts.servedFromCache, `successfully synthesized Custom Vendor audio to ${opts.filePath}`);
obj = await getJSON(`http://127.0.0.1:3100/lastRequest/somethingnew2`);
t.ok(obj.body.type == 'ssml', 'Custom Vendor type is correct');
t.ok(obj.body.text == '<speak>This is a test. This is only a test</speak>');
} catch (err) {
console.error(err);
t.end(err);

23
test/webhook/Dockerfile Normal file
View File

@@ -0,0 +1,23 @@
FROM --platform=linux/amd64 node:18.6.0-alpine as base
RUN apk --update --no-cache add --virtual .builds-deps build-base python3
WORKDIR /opt/app/
FROM base as build
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
FROM base
COPY --from=build /opt/app /opt/app/
ARG NODE_ENV
ENV NODE_ENV $NODE_ENV
CMD [ "node", "app.js" ]

125
test/webhook/app.js Normal file
View File

@@ -0,0 +1,125 @@
const express = require('express');
const app = express();
const Websocket = require('ws');
const listenPort = process.env.HTTP_PORT || 3000;
let hook_mapping = new Map();
let ws_packet_count = new Map();
let ws_metadata = new Map();
/** websocket server for listen audio */
const recvAudio = (socket, req) => {
let packets = 0;
let path = req.url;
console.log('received websocket connection');
socket.on('message', (data, isBinary) => {
if (!isBinary) {
try {
const msg = JSON.parse(data);
console.log({msg}, 'received websocket message');
ws_metadata.set(path, msg);
}
catch (err) {
console.log({err}, 'error parsing websocket message');
}
}
else {
packets += data.length;
}
});
socket.on('error', (err) => {
console.log({err}, 'listen websocket: error');
});
socket.on('close', () => {
ws_packet_count.set(path, packets);
})
};
const wsServer = new Websocket.Server({ noServer: true });
wsServer.setMaxListeners(0);
wsServer.on('connection', recvAudio.bind(null));
const server = app.listen(listenPort, () => {
console.log(`sample jambones app server listening on ${listenPort}`);
});
server.on('upgrade', (request, socket, head) => {
console.log('received upgrade request');
wsServer.handleUpgrade(request, socket, head, (socket) => {
wsServer.emit('connection', socket, request);
});
});
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
/*
* Markup language
*/
app.all('/:key', (req, res) => {
let key = req.params.key;
console.log(req.body, 'POST /' + key);
addRequestToMap(key, req, hook_mapping);
return res.json({"audio":"content"})
});
// Fetch Requests
app.get('/requests/:key', (req, res) => {
let key = req.params.key;
if (hook_mapping.has(key)) {
return res.json(hook_mapping.get(key));
} else {
return res.sendStatus(404);
}
})
app.get('/lastRequest/:key', (req, res) => {
let key = req.params.key;
if (hook_mapping.has(key)) {
let requests = hook_mapping.get(key);
return res.json(requests[requests.length - 1]);
} else {
return res.sendStatus(404);
}
})
// WS Fetch
app.get('/ws_packet_count/:key', (req, res) => {
let key = `/${req.params.key}`;
console.log(key, ws_packet_count);
if (ws_packet_count.has(key)) {
return res.json({ count: ws_packet_count.get(key) });
} else {
return res.sendStatus(404);
}
})
app.get('/ws_metadata/:key', (req, res) => {
let key = `/${req.params.key}`;
console.log(key, ws_packet_count);
if (ws_metadata.has(key)) {
return res.json({ metadata: ws_metadata.get(key) });
} else {
return res.sendStatus(404);
}
})
function addRequestToMap(key, req, map) {
let headers = new Map()
for(let i = 0; i < req.rawHeaders.length; i++) {
if (i % 2 === 0) {
headers.set(req.rawHeaders[i], req.rawHeaders[i + 1])
}
}
let request = {
'url': req.url,
'headers': Object.fromEntries(headers),
'body': req.body
}
if (map.has(key)) {
map.get(key).push(request);
} else {
map.set(key, [request]);
}
}

1045
test/webhook/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

15
test/webhook/package.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "webhook_tts",
"version": "1.0.0",
"description": "simple webhook tts for test purposes",
"main": "app.js",
"scripts": {
"start": "node app"
},
"author": "Dave Horton",
"license": "MIT",
"dependencies": {
"express": "^4.18.2",
"ws": "^8.12.0"
}
}