Let the home-assistant instance linger around for 30s so it can run regular jobs and trigger more code paths that could result in errors.
124 lines
4.1 KiB
Nix
124 lines
4.1 KiB
Nix
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
|
|
|
let
|
|
configDir = "/var/lib/foobar";
|
|
mqttUsername = "homeassistant";
|
|
mqttPassword = "secret";
|
|
in {
|
|
name = "home-assistant";
|
|
meta.maintainers = lib.teams.home-assistant.members;
|
|
|
|
nodes.hass = { pkgs, ... }: {
|
|
environment.systemPackages = with pkgs; [ mosquitto ];
|
|
services.mosquitto = {
|
|
enable = true;
|
|
listeners = [ {
|
|
users = {
|
|
"${mqttUsername}" = {
|
|
acl = [ "readwrite #" ];
|
|
password = mqttPassword;
|
|
};
|
|
};
|
|
} ];
|
|
};
|
|
services.home-assistant = {
|
|
inherit configDir;
|
|
enable = true;
|
|
package = (pkgs.home-assistant.override {
|
|
extraComponents = [ "zha" ];
|
|
}).overrideAttrs (oldAttrs: {
|
|
doInstallCheck = false;
|
|
});
|
|
config = {
|
|
homeassistant = {
|
|
name = "Home";
|
|
time_zone = "UTC";
|
|
latitude = "0.0";
|
|
longitude = "0.0";
|
|
elevation = 0;
|
|
};
|
|
frontend = {};
|
|
mqtt = {
|
|
broker = "127.0.0.1";
|
|
username = mqttUsername;
|
|
password = mqttPassword;
|
|
};
|
|
binary_sensor = [{
|
|
platform = "mqtt";
|
|
state_topic = "home-assistant/test";
|
|
payload_on = "let_there_be_light";
|
|
payload_off = "off";
|
|
}];
|
|
wake_on_lan = {};
|
|
switch = [{
|
|
platform = "wake_on_lan";
|
|
mac = "00:11:22:33:44:55";
|
|
host = "127.0.0.1";
|
|
}];
|
|
# tests component-based capability assignment (CAP_NET_BIND_SERVICE)
|
|
emulated_hue = {
|
|
host_ip = "127.0.0.1";
|
|
listen_port = 80;
|
|
};
|
|
logger = {
|
|
default = "info";
|
|
logs."homeassistant.components.mqtt" = "debug";
|
|
};
|
|
};
|
|
lovelaceConfig = {
|
|
title = "My Awesome Home";
|
|
views = [{
|
|
title = "Example";
|
|
cards = [{
|
|
type = "markdown";
|
|
title = "Lovelace";
|
|
content = "Welcome to your **Lovelace UI**.";
|
|
}];
|
|
}];
|
|
};
|
|
lovelaceConfigWritable = true;
|
|
};
|
|
};
|
|
|
|
testScript = ''
|
|
start_all()
|
|
hass.wait_for_unit("home-assistant.service")
|
|
with subtest("Check that YAML configuration file is in place"):
|
|
hass.succeed("test -L ${configDir}/configuration.yaml")
|
|
with subtest("lovelace config is copied because lovelaceConfigWritable = true"):
|
|
hass.succeed("test -f ${configDir}/ui-lovelace.yaml")
|
|
with subtest("Check that Home Assistant's web interface and API can be reached"):
|
|
hass.wait_for_open_port(8123)
|
|
hass.succeed("curl --fail http://localhost:8123/lovelace")
|
|
with subtest("Toggle a binary sensor using MQTT"):
|
|
hass.wait_for_open_port(1883)
|
|
hass.succeed(
|
|
"mosquitto_pub -V mqttv5 -t home-assistant/test -u ${mqttUsername} -P '${mqttPassword}' -m let_there_be_light"
|
|
)
|
|
with subtest("Check that capabilities are passed for emulated_hue to bind to port 80"):
|
|
hass.wait_for_open_port(80)
|
|
hass.succeed("curl --fail http://localhost:80/description.xml")
|
|
with subtest("Check extra components are considered in systemd unit hardening"):
|
|
hass.succeed("systemctl show -p DeviceAllow home-assistant.service | grep -q char-ttyUSB")
|
|
with subtest("Print log to ease debugging"):
|
|
output_log = hass.succeed("cat ${configDir}/home-assistant.log")
|
|
print("\n### home-assistant.log ###\n")
|
|
print(output_log + "\n")
|
|
|
|
# wait for home-assistant to fully boot
|
|
hass.sleep(30)
|
|
hass.wait_for_unit("home-assistant.service")
|
|
|
|
with subtest("Check that no errors were logged"):
|
|
assert "ERROR" not in output_log
|
|
|
|
# example line: 2020-06-20 10:01:32 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on home-assistant/test: b'let_there_be_light'
|
|
with subtest("Check we received the mosquitto message"):
|
|
assert "let_there_be_light" in output_log
|
|
|
|
with subtest("Check systemd unit hardening"):
|
|
hass.log(hass.succeed("systemctl show home-assistant.service"))
|
|
hass.log(hass.succeed("systemd-analyze security home-assistant.service"))
|
|
'';
|
|
})
|