summary refs log tree commit diff
path: root/nixos/tests/home-assistant.nix
blob: 699be8fd7dc6a7a93547782bf21ded44cf1d54a5 (plain) (blame)
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
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;
      checkPasswords = true;
      users = {
        "${mqttUsername}" = {
          acl = [ "topic readwrite #" ];
          password = mqttPassword;
        };
      };
    };
    services.home-assistant = {
      inherit configDir;
      enable = true;
      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";
        }];
        # 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("Print log to ease debugging"):
        output_log = hass.succeed("cat ${configDir}/home-assistant.log")
        print("\n### home-assistant.log ###\n")
        print(output_log + "\n")

    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"))
  '';
})