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