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