1import ./make-test-python.nix ({ pkgs, lib, ... }: let
2 user = "alice";
3in {
4 name = "ayatana-indicators";
5
6 meta = {
7 maintainers = lib.teams.lomiri.members;
8 };
9
10 nodes.machine = { config, ... }: {
11 imports = [
12 ./common/auto.nix
13 ./common/user-account.nix
14 ];
15
16 test-support.displayManager.auto = {
17 enable = true;
18 inherit user;
19 };
20
21 services.xserver = {
22 enable = true;
23 desktopManager.mate.enable = true;
24 };
25 services.displayManager.defaultSession = lib.mkForce "mate";
26
27 services.ayatana-indicators = {
28 enable = true;
29 packages = with pkgs; [
30 ayatana-indicator-datetime
31 ayatana-indicator-messages
32 ayatana-indicator-power
33 ayatana-indicator-session
34 ] ++ (with pkgs.lomiri; [
35 lomiri-indicator-network
36 telephony-service
37 ]);
38 };
39
40 # Setup needed by some indicators
41
42 services.accounts-daemon.enable = true; # messages
43
44 # Lomiri-ish setup for Lomiri indicators
45 # TODO move into a Lomiri module, once the package set is far enough for the DE to start
46
47 networking.networkmanager.enable = true; # lomiri-network-indicator
48 # TODO potentially urfkill for lomiri-network-indicator?
49
50 services.dbus.packages = with pkgs.lomiri; [
51 libusermetrics
52 ];
53
54 environment.systemPackages = with pkgs.lomiri; [
55 lomiri-schemas
56 ];
57
58 services.telepathy.enable = true;
59
60 users.users.usermetrics = {
61 group = "usermetrics";
62 home = "/var/lib/usermetrics";
63 createHome = true;
64 isSystemUser = true;
65 };
66
67 users.groups.usermetrics = { };
68 };
69
70 # TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready?
71 testScript = { nodes, ... }: let
72 runCommandOverServiceList = list: command:
73 lib.strings.concatMapStringsSep "\n" command list;
74
75 runCommandOverAyatanaIndicators = runCommandOverServiceList
76 (builtins.filter
77 (service: !(lib.strings.hasPrefix "lomiri" service || lib.strings.hasPrefix "telephony-service" service))
78 nodes.machine.systemd.user.targets."ayatana-indicators".wants);
79
80 runCommandOverAllIndicators = runCommandOverServiceList
81 nodes.machine.systemd.user.targets."ayatana-indicators".wants;
82 in ''
83 start_all()
84 machine.wait_for_x()
85
86 # Desktop environment should reach graphical-session.target
87 machine.wait_for_unit("graphical-session.target", "${user}")
88
89 # MATE relies on XDG autostart to bring up the indicators.
90 # Not sure *when* XDG autostart fires them up, and awaiting pgrep success seems to misbehave?
91 machine.sleep(10)
92
93 # Now check if all indicators were brought up successfully, and kill them for later
94 '' + (runCommandOverAyatanaIndicators (service: let serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service; in ''
95 machine.succeed("pgrep -u ${user} -f ${serviceExec}")
96 machine.succeed("pkill -f ${serviceExec}")
97 '')) + ''
98
99 # Ayatana target is the preferred way of starting up indicators on SystemD session, the graphical session is responsible for starting this if it supports them.
100 # Mate currently doesn't do this, so start it manually for checking (https://github.com/mate-desktop/mate-indicator-applet/issues/63)
101 machine.systemctl("start ayatana-indicators.target", "${user}")
102 machine.wait_for_unit("ayatana-indicators.target", "${user}")
103
104 # Let all indicator services do their startups, potential post-launch crash & restart cycles so we can properly check for failures
105 # Not sure if there's a better way of awaiting this without false-positive potential
106 machine.sleep(10)
107
108 # Now check if all indicator services were brought up successfully
109 '' + runCommandOverAllIndicators (service: ''
110 machine.wait_for_unit("${service}", "${user}")
111 '');
112})