import WebSocket from 'ws'; import { uts, wait } from '../dist/sys/tools.js'; import ws from "./tests/ws.js" import { spawn } from "child_process"; import { oConf } from "../dist/sys/config.js" import mariadb from "mariadb"; let inCI = process.argv.includes("ci"); oConf.connect(inCI ? 'test.juml' : 'testLocal.juml'); const connection = await mariadb.createConnection({ host: oConf.get("Database", "host"), port: oConf.get("Database", "port"), user: oConf.get("Database", "user"), password: oConf.get("Database", "password"), database: oConf.get("Database", "database"), multipleStatements: true }); await wait(100); let req = await connection.query("SELECT table_name as n FROM information_schema.tables WHERE table_schema = ?;", [oConf.get("Database", "database")]); let sql = [...req].map(d => "DROP TABLE IF EXISTS `" + d.n + "`;").join(""); if (sql.length > 5) await connection.query("SET FOREIGN_KEY_CHECKS = 0;" + sql + "SET FOREIGN_KEY_CHECKS = 1;", []); connection.close(); function conn(url) { const ws = new WebSocket(url); ws.on('close', function open() { wsOpen = false; }); let wsOpen = true; var list = []; var c = 0; ws.on('message', function message(data) { data = data.toString(); if (data == "error") return void console.log("Server error"); var json = JSON.parse(data); for (let i = 0; i < list.length; i++) { const e = list[i]; if (e[0] == json.id) { e[2]({ state: json.state, data: json.data }); list.splice(i, 1); return; } } }); this.close = function () { ws.close(); } setInterval(() => { for (let i = 0; i < list.length; i++) { const e = list[i]; if (e[1] + 5 < uts()) { e[2]("timeout"); list.splice(i, 1); } } }, 1000); function req(act, data) { return new Promise((res, rej) => { if (!wsOpen) { console.error("WebSocket is closed"); rej("WebSocket is closed"); return; } var id = ++c; list.push([id, uts(), res, rej]); ws.send(JSON.stringify({ id, act, data })); }) } this.req = req; }; function shallowEqual(object1, object2) { const keys1 = Object.keys(object1); const keys2 = Object.keys(object2); if (keys1.length < keys2.length) { return false; } for (let key of keys1) { if (object1[key] != object2[key]) { return false; } } return true; } async function wsTester(url) { async function test(conn, act, data, expState, expData) { console.log("Testing Act:", act, "with Data:", data); let resp = await conn.req(act, data); if (resp.state != expState) { console.error(`Expected state: '${expState}', but got: '${resp.state}'`); kill(); process.exit(1); } if (typeof expData == "object" && expData != null) { if (!shallowEqual(expData, resp.data)) { console.error(`Expected data: '${expData}', but got: '${resp.data}'`); kill(); process.exit(1); } } else if (expData != null) { if (expData != resp.data) { console.error(`Expected data: '${expData}', but got: '${resp.data}'`); kill(); process.exit(1); } } return resp.data; } for (let i = 0; i < ws.length; i++) { const currTest = ws[i]; console.log(`Testing '${currTest[0]}':`); const handler = [new conn(url)]; await wait(100); let resp = true; try { resp = await currTest[1](handler[0], test, async () => { let h = new conn(url); await wait(100); handler.push(h); return h; }); } catch (error) { console.error("Test Error: ", error); kill(); process.exit(1); } handler.forEach(h => h.close()); if (resp === false) { console.log("Test respond with error indication!"); kill(); process.exit(1); } } } const ls = spawn('node', ['.', '-c', inCI ? 'test.juml' : 'testLocal.juml', '-d']); process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; ls.stdout.on('data', (data) => { process.stdout.write(data); if (data.includes("Listening...")) test(); }); ls.stderr.on('data', (data) => { console.error(`stderr: ${data}`); }); ls.on('close', (code) => { console.log(`child process exited with code ${code}`); process.exit(code); }); function kill() { ls.kill('SIGINT'); } let startet = false; async function test() { if (startet) return; startet = true; console.log("Start testing"); await wsTester("wss://localhost:7224/"); kill(); process.exit(0); }