1let
2 clients = [
3 "ircclient1"
4 "ircclient2"
5 ];
6 server = "solanum";
7 ircPort = 6667;
8 channel = "nixos-cat";
9 iiDir = "/tmp/irc";
10in
11
12import ./make-test-python.nix ({ pkgs, lib, ... }: {
13 name = "solanum";
14 nodes = {
15 "${server}" = {
16 networking.firewall.allowedTCPPorts = [ ircPort ];
17 services.solanum = {
18 enable = true;
19 motd = ''
20 The default MOTD doesn't contain the word "nixos" in it.
21 This one does.
22 '';
23 };
24 };
25 } // lib.listToAttrs (builtins.map (client: lib.nameValuePair client {
26 imports = [
27 ./common/user-account.nix
28 ];
29
30 systemd.services.ii = {
31 requires = [ "network.target" ];
32 wantedBy = [ "default.target" ];
33
34 serviceConfig = {
35 Type = "simple";
36 ExecPreStartPre = "mkdir -p ${iiDir}";
37 ExecStart = ''
38 ${lib.getBin pkgs.ii}/bin/ii -n ${client} -s ${server} -i ${iiDir}
39 '';
40 User = "alice";
41 };
42 };
43 }) clients);
44
45 testScript =
46 let
47 msg = client: "Hello, my name is ${client}";
48 clientScript = client: [
49 ''
50 ${client}.wait_for_unit("network.target")
51 ${client}.systemctl("start ii")
52 ${client}.wait_for_unit("ii")
53 ${client}.wait_for_file("${iiDir}/${server}/out")
54 ''
55 # look for the custom text in the MOTD.
56 ''
57 ${client}.wait_until_succeeds("grep 'nixos' ${iiDir}/${server}/out")
58 ''
59 # wait until first PING from server arrives before joining,
60 # so we don't try it too early
61 ''
62 ${client}.wait_until_succeeds("grep 'PING' ${iiDir}/${server}/out")
63 ''
64 # join ${channel}
65 ''
66 ${client}.succeed("echo '/j #${channel}' > ${iiDir}/${server}/in")
67 ${client}.wait_for_file("${iiDir}/${server}/#${channel}/in")
68 ''
69 # send a greeting
70 ''
71 ${client}.succeed(
72 "echo '${msg client}' > ${iiDir}/${server}/#${channel}/in"
73 )
74 ''
75 # check that all greetings arrived on all clients
76 ] ++ builtins.map (other: ''
77 ${client}.succeed(
78 "grep '${msg other}$' ${iiDir}/${server}/#${channel}/out"
79 )
80 '') clients;
81
82 # foldl', but requires a non-empty list instead of a start value
83 reduce = f: list:
84 builtins.foldl' f (builtins.head list) (builtins.tail list);
85 in ''
86 start_all()
87 ${server}.systemctl("status solanum")
88 ${server}.wait_for_open_port(${toString ircPort})
89
90 # run clientScript for all clients so that every list
91 # entry is executed by every client before advancing
92 # to the next one.
93 '' + lib.concatStrings
94 (reduce
95 (lib.zipListsWith (cs: c: cs + c))
96 (builtins.map clientScript clients));
97})