1import ./make-test-python.nix ({ pkgs, lib, ... }:
2
3let
4 port = 1888;
5 username = "mqtt";
6 password = "VERY_secret";
7 topic = "test/foo";
8in {
9 name = "mosquitto";
10 meta = with pkgs.lib; {
11 maintainers = with maintainers; [ peterhoeg ];
12 };
13
14 nodes = let
15 client = { pkgs, ... }: {
16 environment.systemPackages = with pkgs; [ mosquitto ];
17 };
18 in {
19 server = { pkgs, ... }: {
20 networking.firewall.allowedTCPPorts = [ port ];
21 services.mosquitto = {
22 inherit port;
23 enable = true;
24 host = "0.0.0.0";
25 checkPasswords = true;
26 users.${username} = {
27 inherit password;
28 acl = [
29 "topic readwrite ${topic}"
30 ];
31 };
32 };
33
34 # disable private /tmp for this test
35 systemd.services.mosquitto.serviceConfig.PrivateTmp = lib.mkForce false;
36 };
37
38 client1 = client;
39 client2 = client;
40 };
41
42 testScript = let
43 file = "/tmp/msg";
44 in ''
45 def mosquitto_cmd(binary):
46 return (
47 "${pkgs.mosquitto}/bin/mosquitto_{} "
48 "-V mqttv311 "
49 "-h server "
50 "-p ${toString port} "
51 "-u ${username} "
52 "-P '${password}' "
53 "-t ${topic}"
54 ).format(binary)
55
56
57 def publish(args):
58 return "{} {}".format(mosquitto_cmd("pub"), args)
59
60
61 def subscribe(args):
62 return "({} -C 1 {} | tee ${file} &)".format(mosquitto_cmd("sub"), args)
63
64
65 start_all()
66 server.wait_for_unit("mosquitto.service")
67
68 for machine in server, client1, client2:
69 machine.fail("test -f ${file}")
70
71 # QoS = 0, so only one subscribers should get it
72 server.execute(subscribe("-q 0"))
73
74 # we need to give the subscribers some time to connect
75 client2.execute("sleep 5")
76 client2.succeed(publish("-m FOO -q 0"))
77
78 server.wait_until_succeeds("grep -q FOO ${file}")
79 server.execute("rm ${file}")
80
81 # QoS = 1, so both subscribers should get it
82 server.execute(subscribe("-q 1"))
83 client1.execute(subscribe("-q 1"))
84
85 # we need to give the subscribers some time to connect
86 client2.execute("sleep 5")
87 client2.succeed(publish("-m BAR -q 1"))
88
89 for machine in server, client1:
90 machine.wait_until_succeeds("grep -q BAR ${file}")
91 machine.execute("rm ${file}")
92 '';
93})