1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
/* global QUnit */
function connect() {
let ws = new WebSocket(`ws://${window.location.host}/cockpit/socket`, "cockpit1");
let connection = {
oncontrol: () => {},
onmessage: () => {},
onclose: () => {},
send: (channel, data) => ws.send(channel + "\n" + data),
control: message => connection.send("", JSON.stringify(message)),
close: () => ws.close()
};
ws.onmessage = event => {
let message = event.data;
let pos = message.indexOf("\n");
if (pos < 0)
throw new Error("invalid message");
let channel = message.substring(0, pos);
let data = message.substring(pos + 1);
if (channel === "")
connection.oncontrol(JSON.parse(data));
else
connection.onmessage(channel, data);
};
ws.onclose = () => connection.onclose();
return new Promise((resolve, reject) => {
ws.onopen = () => resolve(connection);
ws.onerror = () => reject();
});
}
QUnit.test("first message from host is init", async function (assert) {
assert.expect(5);
let done = assert.async();
let connection = await connect();
connection.oncontrol = message => {
assert.strictEqual(message.command, "init");
assert.strictEqual(message.version, 1);
assert.ok("channel-seed" in message);
assert.ok("host" in message);
assert.ok("csrf-token" in message);
connection.close();
done();
};
connection.onmessage = () => { throw new Error("should not be reached") };
});
QUnit.test("host must ensure that init is the first message", async function (assert) {
assert.expect(2);
let done = assert.async(2);
let connection = await connect();
// ensure that the server closes the connection on protocol error
connection.onclose = () => done();
// send something first that's not "init"
connection.control({ command: "ping" });
connection.oncontrol = message => {
if (message.command === "init")
return;
assert.equal(message.command, "close");
assert.equal(message.problem, "protocol-error");
done();
};
});
QUnit.module("tests that need test-server warnings disabled", function (hooks) {
/*
* Some of these tests will trigger cockpit-ws or cockpit-bridge to print out
* warnings (on protocol errors, for example). Let the test server know that
* before starting the tests, so it doesn't treat those messages as fatal.
*/
// hooks wait for the promise to be resolved before continuing
hooks.before(() => fetch("/mock/expect-warnings"));
hooks.after(() => fetch("/mock/dont-expect-warnings"));
QUnit.test("host must return an error when 'channel' is not given in 'open'", async function (assert) {
assert.expect(2);
let done = assert.async(2);
let connection = await connect();
// ensure that the server closes the connection on protocol error
connection.onclose = () => done();
connection.oncontrol = message => {
if (message.command === "init")
return;
assert.equal(message.command, "close");
assert.equal(message.problem, "protocol-error");
done();
};
connection.control({ command: "init", version: 1 });
connection.control({ command: "open", payload: "fsread", path: "/etc/passwd" });
});
});
QUnit.start();
|