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 };
20 };
21 } // lib.listToAttrs (builtins.map (client: lib.nameValuePair client {
22 imports = [
23 ./common/user-account.nix
24 ];
25
26 systemd.services.ii = {
27 requires = [ "network.target" ];
28 wantedBy = [ "default.target" ];
29
30 serviceConfig = {
31 Type = "simple";
32 ExecPreStartPre = "mkdir -p ${iiDir}";
33 ExecStart = ''
34 ${lib.getBin pkgs.ii}/bin/ii -n ${client} -s ${server} -i ${iiDir}
35 '';
36 User = "alice";
37 };
38 };
39 }) clients);
40
41 testScript =
42 let
43 msg = client: "Hello, my name is ${client}";
44 clientScript = client: [
45 ''
46 ${client}.wait_for_unit("network.target")
47 ${client}.systemctl("start ii")
48 ${client}.wait_for_unit("ii")
49 ${client}.wait_for_file("${iiDir}/${server}/out")
50 ''
51 # wait until first PING from server arrives before joining,
52 # so we don't try it too early
53 ''
54 ${client}.wait_until_succeeds("grep 'PING' ${iiDir}/${server}/out")
55 ''
56 # join ${channel}
57 ''
58 ${client}.succeed("echo '/j #${channel}' > ${iiDir}/${server}/in")
59 ${client}.wait_for_file("${iiDir}/${server}/#${channel}/in")
60 ''
61 # send a greeting
62 ''
63 ${client}.succeed(
64 "echo '${msg client}' > ${iiDir}/${server}/#${channel}/in"
65 )
66 ''
67 # check that all greetings arrived on all clients
68 ] ++ builtins.map (other: ''
69 ${client}.succeed(
70 "grep '${msg other}$' ${iiDir}/${server}/#${channel}/out"
71 )
72 '') clients;
73
74 # foldl', but requires a non-empty list instead of a start value
75 reduce = f: list:
76 builtins.foldl' f (builtins.head list) (builtins.tail list);
77 in ''
78 start_all()
79 ${server}.systemctl("status solanum")
80 ${server}.wait_for_open_port(${toString ircPort})
81
82 # run clientScript for all clients so that every list
83 # entry is executed by every client before advancing
84 # to the next one.
85 '' + lib.concatStrings
86 (reduce
87 (lib.zipListsWith (cs: c: cs + c))
88 (builtins.map clientScript clients));
89})