257 lines
9.7 KiB
JavaScript
257 lines
9.7 KiB
JavaScript
import cockpit from "cockpit";
|
|
import QUnit from "qunit-tests";
|
|
import { machines } from "./machines";
|
|
|
|
const dbus = cockpit.dbus(null, { bus: "internal" });
|
|
let configDir;
|
|
|
|
QUnit.module("machines.d parsing tests", {
|
|
beforeEach: () => cockpit.spawn(["mkdir", "-p", configDir + "/cockpit/machines.d"]),
|
|
afterEach: () => cockpit.spawn(["rm", "-rf", configDir + "/cockpit/machines.d"]),
|
|
after: () => cockpit.spawn(["rm", "-r", configDir]),
|
|
});
|
|
|
|
/***
|
|
* Tests for parsing on-disk JSON configuration
|
|
*/
|
|
|
|
function machinesParseTest(assert, machines_defs, expectedProperty) {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
const setup = [];
|
|
|
|
for (const fname in machines_defs) {
|
|
let path = fname;
|
|
if (fname.indexOf('/') < 0)
|
|
path = configDir + "/cockpit/machines.d/" + fname;
|
|
setup.push(cockpit.file(path).replace(machines_defs[fname]));
|
|
}
|
|
|
|
Promise.all(setup).then(function() {
|
|
dbus.call("/machines", "org.freedesktop.DBus.Properties",
|
|
"Get", ["cockpit.Machines", "Machines"],
|
|
{ type: "ss" })
|
|
.done(function(reply) {
|
|
assert.equal(reply[0].t, "a{sa{sv}}", "expected return type");
|
|
assert.deepEqual(reply[0].v, expectedProperty, "expected property value");
|
|
})
|
|
.always(function() {
|
|
assert.equal(this.state(), "resolved", "finished successfully");
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
QUnit.test("no machine definitions", function (assert) {
|
|
machinesParseTest(assert, {}, {});
|
|
});
|
|
|
|
QUnit.test("empty json", function (assert) {
|
|
machinesParseTest(assert, { "01.json": "" }, {});
|
|
});
|
|
|
|
QUnit.test("two definitions", function (assert) {
|
|
machinesParseTest(assert,
|
|
{
|
|
"01.json": '{"green": {"visible": true, "address": "1.2.3.4"}, ' +
|
|
' "9.8.7.6": {"visible": false, "address": "9.8.7.6", "user": "admin"}}'
|
|
},
|
|
{
|
|
green: {
|
|
address: { t: "s", v: "1.2.3.4" },
|
|
visible: { t: "b", v: true }
|
|
},
|
|
"9.8.7.6": {
|
|
address: { t: "s", v: "9.8.7.6" },
|
|
user: { t: "s", v: "admin" },
|
|
visible: { t: "b", v: false }
|
|
}
|
|
});
|
|
});
|
|
|
|
QUnit.test("invalid json", function (assert) {
|
|
machinesParseTest(assert, { "01.json": '{"green":' }, {});
|
|
});
|
|
|
|
QUnit.test("invalid data types", function (assert) {
|
|
machinesParseTest(assert, { "01.json": '{"green": []}' }, {});
|
|
});
|
|
|
|
QUnit.test("merge several JSON files", function (assert) {
|
|
/* 99-webui.json changes a property in green, adds a
|
|
* property to blue, and adds an entire new host yellow */
|
|
machinesParseTest(
|
|
assert,
|
|
{
|
|
"01-green.json": '{"green": {"visible": true, "address": "1.2.3.4"}}',
|
|
"02-blue.json": '{"blue": {"address": "9.8.7.6"}}',
|
|
"09-webui.json": '{"green": {"visible": false}, ' +
|
|
' "blue": {"user": "joe"}, ' +
|
|
' "yellow": {"address": "fe80::1", "user": "sue"}}'
|
|
},
|
|
{
|
|
green: {
|
|
address: { t: "s", v: "1.2.3.4" },
|
|
visible: { t: "b", v: false }
|
|
},
|
|
blue: {
|
|
address: { t: "s", v: "9.8.7.6" },
|
|
user: { t: "s", v: "joe" },
|
|
},
|
|
yellow: {
|
|
address: { t: "s", v: "fe80::1" },
|
|
user: { t: "s", v: "sue" },
|
|
}
|
|
}
|
|
);
|
|
});
|
|
|
|
QUnit.test("merge JSON files with errors", function (assert) {
|
|
machinesParseTest(
|
|
assert,
|
|
{
|
|
"01-valid.json": '{"green": {"visible": true, "address": "1.2.3.4"}}',
|
|
"02-syntax.json": '[a',
|
|
"03-toptype.json": '["green"]',
|
|
"04-toptype.json": '{"green": ["visible"]}',
|
|
"05-valid.json": '{"blue": {"address": "fe80::1"}}',
|
|
// goodprop should still be considered
|
|
"06-proptype.json": '{"green": {"visible": [], "address": {"bar": null}, "goodprop": "yeah"}}',
|
|
"07-valid.json": '{"green": {"user": "joe"}}',
|
|
"08-empty.json": ''
|
|
},
|
|
{
|
|
green: {
|
|
address: { t: "s", v: "1.2.3.4" },
|
|
visible: { t: "b", v: true },
|
|
user: { t: "s", v: "joe" },
|
|
goodprop: { t: "s", v: "yeah" },
|
|
},
|
|
blue: {
|
|
address: { t: "s", v: "fe80::1" }
|
|
}
|
|
}
|
|
);
|
|
});
|
|
|
|
/***
|
|
* Tests for Update()
|
|
*/
|
|
|
|
function machinesUpdateTest(assert, origJson, host, props, expectedJson) {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
const f = configDir + "/cockpit/machines.d/99-webui.json";
|
|
|
|
cockpit.file(f).replace(origJson)
|
|
.done(function(tag) {
|
|
dbus.call("/machines", "cockpit.Machines", "Update", ["99-webui.json", host, props], { type: "ssa{sv}" })
|
|
.then(function(reply) {
|
|
assert.deepEqual(reply, [], "no expected return value");
|
|
return cockpit.file(f, { syntax: JSON }).read()
|
|
.done(function(content, tag) {
|
|
assert.deepEqual(content, expectedJson, "expected file content");
|
|
})
|
|
.fail(function(err) {
|
|
assert.equal(err, undefined, "expected no error");
|
|
});
|
|
})
|
|
.always(function() {
|
|
assert.equal(this.state(), "resolved", "finished successfully");
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
QUnit.test("no config files", function (assert) {
|
|
machinesUpdateTest(assert, null, "green", { visible: cockpit.variant('b', true), address: cockpit.variant('s', "1.2.3.4") },
|
|
{ green: { address: "1.2.3.4", visible: true } });
|
|
});
|
|
|
|
QUnit.test("add host to existing map", function (assert) {
|
|
machinesUpdateTest(assert,
|
|
'{"green": {"visible": true, "address": "1.2.3.4"}}',
|
|
"blue",
|
|
{ visible: cockpit.variant('b', false), address: cockpit.variant('s', "9.8.7.6") },
|
|
{
|
|
green: { address: "1.2.3.4", visible: true },
|
|
blue: { address: "9.8.7.6", visible: false }
|
|
});
|
|
});
|
|
|
|
QUnit.test("change bool host property", function (assert) {
|
|
machinesUpdateTest(assert,
|
|
'{"green": {"visible": true, "address": "1.2.3.4"}}',
|
|
"green",
|
|
{ visible: cockpit.variant('b', false) },
|
|
{ green: { address: "1.2.3.4", visible: false } });
|
|
});
|
|
|
|
QUnit.test("change string host property", function (assert) {
|
|
machinesUpdateTest(assert,
|
|
'{"green": {"visible": true, "address": "1.2.3.4"}}',
|
|
"green",
|
|
{ address: cockpit.variant('s', "fe80::1") },
|
|
{ green: { address: "fe80::1", visible: true } });
|
|
});
|
|
|
|
QUnit.test("add host property", function (assert) {
|
|
machinesUpdateTest(assert,
|
|
'{"green": {"visible": true, "address": "1.2.3.4"}}',
|
|
"green",
|
|
{ color: cockpit.variant('s', "pitchblack") },
|
|
{ green: { address: "1.2.3.4", visible: true, color: "pitchblack" } });
|
|
});
|
|
|
|
QUnit.test("Update() only writes delta", function (assert) {
|
|
const done = assert.async();
|
|
|
|
cockpit.file(configDir + "/cockpit/machines.d/01-green.json")
|
|
.replace('{"green": {"address": "1.2.3.4"}, "blue": {"address": "fe80::1"}}')
|
|
.done(function(tag) {
|
|
machinesUpdateTest(assert,
|
|
null,
|
|
"green",
|
|
{ color: cockpit.variant('s', "pitchblack") },
|
|
{ green: { color: "pitchblack" } });
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("updating and existing delta file", function (assert) {
|
|
const done = assert.async();
|
|
|
|
cockpit.file(configDir + "/cockpit/machines.d/01-green.json")
|
|
.replace('{"green": {"address": "1.2.3.4"}, "blue": {"address": "fe80::1"}}')
|
|
.done(function(tag) {
|
|
machinesUpdateTest(assert,
|
|
'{"green": {"address": "9.8.7.6", "user": "joe"}}',
|
|
"green",
|
|
{ color: cockpit.variant('s', "pitchblack") },
|
|
{ green: { address: "9.8.7.6", user: "joe", color: "pitchblack" } });
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("colors.parse()", function (assert) {
|
|
const colors = [
|
|
["#960064", "rgb(150, 0, 100)"],
|
|
["rgb(150, 0, 100)", "rgb(150, 0, 100)"],
|
|
["#ccc", "rgb(204, 204, 204)"],
|
|
];
|
|
assert.expect(colors.length);
|
|
colors.forEach(function(color) {
|
|
assert.equal(machines.colors.parse(color[0]), color[1], "parsed color " + color[0]);
|
|
});
|
|
});
|
|
|
|
/* The test cockpit-bridge gets started with temp $XDG_CONFIG_DIRS instead of defaulting to /etc/.
|
|
* Read it from the bridge so that we can put our test files into it. */
|
|
const proxy = dbus.proxy("cockpit.Environment", "/environment");
|
|
proxy.wait(function () {
|
|
configDir = proxy.Variables.XDG_CONFIG_DIRS;
|
|
QUnit.start();
|
|
});
|