summary refs log tree commit diff
path: root/nixos/tests/ergochat.nix
blob: 2e9dc55e648e6bb32320d178dcb29197fe7bd6a8 (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
let
  clients = [
    "ircclient1"
    "ircclient2"
  ];
  server = "ergochat";
  ircPort = 6667;
  channel = "nixos-cat";
  iiDir = "/tmp/irc";
in

import ./make-test-python.nix ({ pkgs, lib, ... }: {
  name = "ergochat";
  nodes = {
    "${server}" = {
      networking.firewall.allowedTCPPorts = [ ircPort ];
      services.ergochat = {
        enable = true;
        settings.server.motd = pkgs.writeText "ergo.motd" ''
          The default MOTD doesn't contain the word "nixos" in it.
          This one does.
        '';
      };
    };
  } // lib.listToAttrs (builtins.map (client: lib.nameValuePair client {
    imports = [
      ./common/user-account.nix
    ];

    systemd.services.ii = {
      requires = [ "network.target" ];
      wantedBy = [ "default.target" ];

      serviceConfig = {
        Type = "simple";
        ExecPreStartPre = "mkdir -p ${iiDir}";
        ExecStart = ''
          ${lib.getBin pkgs.ii}/bin/ii -n ${client} -s ${server} -i ${iiDir}
        '';
        User = "alice";
      };
    };
  }) clients);

  testScript =
    let
      msg = client: "Hello, my name is ${client}";
      clientScript = client: [
        ''
          ${client}.wait_for_unit("network.target")
          ${client}.systemctl("start ii")
          ${client}.wait_for_unit("ii")
          ${client}.wait_for_file("${iiDir}/${server}/out")
        ''
        # look for the custom text in the MOTD.
        ''
          ${client}.wait_until_succeeds("grep 'nixos' ${iiDir}/${server}/out")
        ''
        # wait until first PING from server arrives before joining,
        # so we don't try it too early
        ''
          ${client}.wait_until_succeeds("grep 'PING' ${iiDir}/${server}/out")
        ''
        # join ${channel}
        ''
          ${client}.succeed("echo '/j #${channel}' > ${iiDir}/${server}/in")
          ${client}.wait_for_file("${iiDir}/${server}/#${channel}/in")
        ''
        # send a greeting
        ''
          ${client}.succeed(
              "echo '${msg client}' > ${iiDir}/${server}/#${channel}/in"
          )
        ''
        # check that all greetings arrived on all clients
      ] ++ builtins.map (other: ''
        ${client}.succeed(
            "grep '${msg other}$' ${iiDir}/${server}/#${channel}/out"
        )
      '') clients;

      # foldl', but requires a non-empty list instead of a start value
      reduce = f: list:
        builtins.foldl' f (builtins.head list) (builtins.tail list);
    in ''
      start_all()
      ${server}.systemctl("status ergochat")
      ${server}.wait_for_open_port(${toString ircPort})

      # run clientScript for all clients so that every list
      # entry is executed by every client before advancing
      # to the next one.
    '' + lib.concatStrings
      (reduce
        (lib.zipListsWith (cs: c: cs + c))
        (builtins.map clientScript clients));
})