about summary refs log tree commit diff
path: root/nixos/tests/home-assistant.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/tests/home-assistant.nix')
-rw-r--r--nixos/tests/home-assistant.nix98
1 files changed, 92 insertions, 6 deletions
diff --git a/nixos/tests/home-assistant.nix b/nixos/tests/home-assistant.nix
index 1ab5755863f74..31f8a4bcc1981 100644
--- a/nixos/tests/home-assistant.nix
+++ b/nixos/tests/home-assistant.nix
@@ -10,6 +10,7 @@ in {
 
   nodes.hass = { pkgs, ... }: {
     environment.systemPackages = with pkgs; [ mosquitto ];
+
     services.mosquitto = {
       enable = true;
       listeners = [ {
@@ -21,14 +22,42 @@ in {
         };
       } ];
     };
+
+    services.postgresql = {
+      enable = true;
+      ensureDatabases = [ "hass" ];
+      ensureUsers = [{
+        name = "hass";
+        ensurePermissions = {
+          "DATABASE hass" = "ALL PRIVILEGES";
+        };
+      }];
+    };
+
     services.home-assistant = {
-      inherit configDir;
       enable = true;
+      inherit configDir;
+
+      # tests loading components by overriding the package
       package = (pkgs.home-assistant.override {
+        extraPackages = ps: with ps; [
+          colorama
+        ];
         extraComponents = [ "zha" ];
       }).overrideAttrs (oldAttrs: {
         doInstallCheck = false;
       });
+
+      # tests loading components from the module
+      extraComponents = [
+        "wake_on_lan"
+      ];
+
+      # test extra package passing from the module
+      extraPackages = python3Packages: with python3Packages; [
+        psycopg2
+      ];
+
       config = {
         homeassistant = {
           name = "Home";
@@ -37,28 +66,58 @@ in {
           longitude = "0.0";
           elevation = 0;
         };
+
+        # configure the recorder component to use the postgresql db
+        recorder.db_url = "postgresql://@/hass";
+
+        # we can't load default_config, because the updater requires
+        # network access and would cause an error, so load frontend
+        # here explicitly.
+        # https://www.home-assistant.io/integrations/frontend/
         frontend = {};
+
+        # configure an mqtt broker connection
+        # https://www.home-assistant.io/integrations/mqtt
         mqtt = {
           broker = "127.0.0.1";
           username = mqttUsername;
           password = mqttPassword;
         };
-        binary_sensor = [{
+
+        # create a mqtt sensor that syncs state with its mqtt topic
+        # https://www.home-assistant.io/integrations/sensor.mqtt/
+        binary_sensor = [ {
           platform = "mqtt";
           state_topic = "home-assistant/test";
           payload_on = "let_there_be_light";
           payload_off = "off";
-        }];
-        # tests component-based capability assignment (CAP_NET_BIND_SERVICE)
+        } ];
+
+        # set up a wake-on-lan switch to test capset capability required
+        # for the ping suid wrapper
+        # https://www.home-assistant.io/integrations/wake_on_lan/
+        switch = [ {
+          platform = "wake_on_lan";
+          mac = "00:11:22:33:44:55";
+          host = "127.0.0.1";
+        } ];
+
+        # test component-based capability assignment (CAP_NET_BIND_SERVICE)
+        # https://www.home-assistant.io/integrations/emulated_hue/
         emulated_hue = {
           host_ip = "127.0.0.1";
           listen_port = 80;
         };
+
+        # show mqtt interaction in the log
+        # https://www.home-assistant.io/integrations/logger/
         logger = {
           default = "info";
           logs."homeassistant.components.mqtt" = "debug";
         };
       };
+
+      # configure the sample lovelace dashboard
       lovelaceConfig = {
         title = "My Awesome Home";
         views = [{
@@ -75,25 +134,52 @@ in {
   };
 
   testScript = ''
+    import re
+
     start_all()
+
+    # Parse the package path out of the systemd unit, as we cannot
+    # access the final package, that is overriden inside the module,
+    # by any other means.
+    pattern = re.compile(r"path=(?P<path>[\/a-z0-9-.]+)\/bin\/hass")
+    response = hass.execute("systemctl show -p ExecStart home-assistant.service")[1]
+    match = pattern.search(response)
+    package = match.group('path')
+
     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"):
+
+    with subtest("Check the lovelace config is copied because lovelaceConfigWritable = true"):
         hass.succeed("test -f ${configDir}/ui-lovelace.yaml")
+
+    with subtest("Check extraComponents and extraPackages are considered from the package"):
+        hass.succeed(f"grep -q 'colorama' {package}/extra_packages")
+        hass.succeed(f"grep -q 'zha' {package}/extra_components")
+
+    with subtest("Check extraComponents and extraPackages are considered from the module"):
+        hass.succeed(f"grep -q 'psycopg2' {package}/extra_packages")
+        hass.succeed(f"grep -q 'wake_on_lan' {package}/extra_components")
+
     with subtest("Check that Home Assistant's web interface and API can be reached"):
+        hass.wait_until_succeeds("journalctl -u home-assistant.service | grep -q 'Home Assistant initialized in'")
         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")
@@ -107,7 +193,7 @@ in {
         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("systemctl cat home-assistant.service"))
         hass.log(hass.succeed("systemd-analyze security home-assistant.service"))
   '';
 })