* socket: Fork @iov/socket * socket: Remove nonces * socket: Update package.json * socket: Update README * socket: Remove tslint * socket: Fix lint warnings * scripts: Fork socketserver from IOV Core * root: Update NOTICE for socket * tendermint-rpc: Replace @iov/socket dependency with @cosmjs/socket * root: Update CI config for tendermint/socket * scripts: Add wait to tendermint start script * socket: Add coverage
249 lines
6.9 KiB
TypeScript
249 lines
6.9 KiB
TypeScript
import { SocketWrapper } from "./socketwrapper";
|
|
|
|
function pendingWithoutSocketServer(): void {
|
|
if (!process.env.SOCKETSERVER_ENABLED) {
|
|
pending("Set SOCKETSERVER_ENABLED to enable socket tests");
|
|
}
|
|
}
|
|
|
|
describe("SocketWrapper", () => {
|
|
const socketServerUrlNonExisting = "ws://localhost:4443/websocket";
|
|
const socketServerUrl = "ws://localhost:4444/websocket";
|
|
const socketServerUrlSlow = "ws://localhost:4445/websocket";
|
|
|
|
it("can be constructed", () => {
|
|
const socket = new SocketWrapper(socketServerUrl, fail, fail);
|
|
expect(socket).toBeTruthy();
|
|
});
|
|
|
|
it("can connect", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrl,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
() => {
|
|
socket.disconnect();
|
|
done();
|
|
},
|
|
);
|
|
expect(socket).toBeTruthy();
|
|
socket.connect();
|
|
});
|
|
|
|
it("fails to connect to non-existing server", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrlNonExisting,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => {
|
|
if (error.message) {
|
|
// error message only available in nodejs
|
|
expect(error.message).toMatch(/ECONNREFUSED/i);
|
|
}
|
|
done();
|
|
},
|
|
() => done.fail("Got unexpected open event"),
|
|
);
|
|
expect(socket).toBeTruthy();
|
|
socket.connect();
|
|
});
|
|
|
|
it("fails to connect to non-existing server but timeout is not triggered", (done) => {
|
|
pendingWithoutSocketServer();
|
|
const timeout = 1200; // ms
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrlNonExisting,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => {
|
|
expect(error).toBeTruthy();
|
|
|
|
// All done. Delay test end to ensure the timeout is not triggered
|
|
setTimeout(done, timeout * 1.3);
|
|
},
|
|
() => done.fail("Got unexpected open event"),
|
|
() => 0,
|
|
timeout,
|
|
);
|
|
expect(socket).toBeTruthy();
|
|
socket.connect();
|
|
});
|
|
|
|
it("can connect to slow server", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrlSlow,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
() => {
|
|
socket.disconnect();
|
|
done();
|
|
},
|
|
);
|
|
expect(socket).toBeTruthy();
|
|
socket.connect();
|
|
});
|
|
|
|
it("times out when establishing connection takes too long", async () => {
|
|
pendingWithoutSocketServer();
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrlSlow,
|
|
() => fail("Got unexpected message event"),
|
|
(error) => fail(error.message || "Unknown socket error"),
|
|
() => fail("Got unexpected opened event"),
|
|
() => fail("Got unexpected closed event"),
|
|
2_000,
|
|
);
|
|
socket.connect();
|
|
|
|
await socket.connected
|
|
.then(() => fail("must not resolve"))
|
|
.catch((error) => expect(error).toMatch(/connection attempt timed out/i));
|
|
});
|
|
|
|
it("can connect and disconnect", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
let opened = 0;
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrl,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
() => {
|
|
opened += 1;
|
|
socket.disconnect();
|
|
},
|
|
(closeEvent) => {
|
|
expect(closeEvent.wasClean).toEqual(true);
|
|
expect(closeEvent.code).toEqual(1000 /* Normal Closure */);
|
|
|
|
expect(opened).toEqual(1);
|
|
done();
|
|
},
|
|
);
|
|
socket.connect();
|
|
});
|
|
|
|
it("can disconnect before waiting for open", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrl,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
() => done.fail("Got unexpected open event"),
|
|
(closeEvent) => {
|
|
expect(closeEvent.wasClean).toEqual(false);
|
|
expect(closeEvent.code).toEqual(4001);
|
|
done();
|
|
},
|
|
);
|
|
socket.connect();
|
|
socket.disconnect();
|
|
});
|
|
|
|
it("can disconnect before waiting for open and timeout will not be triggered", (done) => {
|
|
pendingWithoutSocketServer();
|
|
const timeout = 500; // ms
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrl,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
() => done.fail("Got unexpected open event"),
|
|
(closeEvent) => {
|
|
expect(closeEvent.wasClean).toEqual(false);
|
|
expect(closeEvent.code).toEqual(4001);
|
|
|
|
// All done. Delay test end to ensure the timeout is not triggered
|
|
setTimeout(done, timeout * 1.3);
|
|
},
|
|
timeout,
|
|
);
|
|
socket.connect();
|
|
socket.disconnect();
|
|
});
|
|
|
|
it("can send events when connected", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
const responseMessages = new Array<string>();
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrl,
|
|
(response) => {
|
|
expect(response.type).toEqual("message");
|
|
responseMessages.push(response.data);
|
|
|
|
if (responseMessages.length === 3) {
|
|
socket.disconnect();
|
|
}
|
|
},
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
async () => {
|
|
await socket.send("aabbccdd");
|
|
await socket.send("whatever");
|
|
await socket.send("lalala");
|
|
},
|
|
() => {
|
|
expect(responseMessages.length).toEqual(3);
|
|
done();
|
|
},
|
|
);
|
|
socket.connect();
|
|
});
|
|
|
|
it("can send events after timeout period", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
// The "timeout period" is the period in which a timeout could potentially be triggered
|
|
|
|
const timeoutPeriodLength = 1_500;
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrl,
|
|
(response) => {
|
|
expect(response.type).toEqual("message");
|
|
expect(response.data).toEqual("Hello world");
|
|
socket.disconnect();
|
|
},
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
undefined,
|
|
() => done(),
|
|
timeoutPeriodLength,
|
|
);
|
|
socket.connect();
|
|
|
|
setTimeout(() => socket.send("Hello world"), 2 * timeoutPeriodLength);
|
|
});
|
|
|
|
it("cannot send on a disconnect socket (it will never come back)", (done) => {
|
|
pendingWithoutSocketServer();
|
|
|
|
const socket = new SocketWrapper(
|
|
socketServerUrl,
|
|
() => done.fail("Got unexpected message event"),
|
|
(error) => done.fail(error.message || "Unknown socket error"),
|
|
() => {
|
|
socket.disconnect();
|
|
},
|
|
() => {
|
|
socket
|
|
.send("la li lu")
|
|
.then(() => done.fail("must not resolve"))
|
|
.catch((error) => {
|
|
expect(error).toMatch(/socket was closed/i);
|
|
done();
|
|
});
|
|
},
|
|
);
|
|
socket.connect();
|
|
});
|
|
});
|