1{ system ? builtins.currentSystem
2, config ? { }
3, pkgs ? import ../.. { inherit system config; }
4}:
5
6with import ../lib/testing-python.nix { inherit system pkgs; };
7with pkgs.lib;
8
9let assertions = rec {
10 path = program: path: ''
11 with subtest("The path of ${program} should be ${path}"):
12 p = machine.succeed("type -p \"${program}\" | head -c -1")
13 assert p == "${path}", f"${program} is {p}, expected ${path}"
14 '';
15 unit = name: state: ''
16 with subtest("Unit ${name} should be ${state}"):
17 machine.require_unit_state("${name}", "${state}")
18 '';
19 version = ''
20 import re
21
22 with subtest("binary should report the correct version"):
23 pkgver = "${pkgs.atop.version}"
24 ver = re.sub(r'(?s)^Version: (\d\.\d\.\d).*', r'\1', machine.succeed("atop -V"))
25 assert ver == pkgver, f"Version is `{ver}`, expected `{pkgver}`"
26 '';
27 atoprc = contents:
28 if builtins.stringLength contents > 0 then ''
29 with subtest("/etc/atoprc should have the correct contents"):
30 f = machine.succeed("cat /etc/atoprc")
31 assert f == "${contents}", f"/etc/atoprc contents: '{f}', expected '${contents}'"
32 '' else ''
33 with subtest("/etc/atoprc should not be present"):
34 machine.succeed("test ! -e /etc/atoprc")
35 '';
36 wrapper = present:
37 if present then path "atop" "/run/wrappers/bin/atop" + ''
38 with subtest("Wrapper should be setuid root"):
39 stat = machine.succeed("stat --printf '%a %u' /run/wrappers/bin/atop")
40 assert stat == "4511 0", f"Wrapper stat is {stat}, expected '4511 0'"
41 ''
42 else path "atop" "/run/current-system/sw/bin/atop";
43 atopService = present:
44 if present then
45 unit "atop.service" "active"
46 + ''
47 with subtest("atop.service should have written some data to /var/log/atop"):
48 files = int(machine.succeed("ls -1 /var/log/atop | wc -l"))
49 assert files > 0, "Expected at least 1 data file"
50 '' else unit "atop.service" "inactive";
51 atopRotateTimer = present:
52 unit "atop-rotate.timer" (if present then "active" else "inactive");
53 atopacctService = present:
54 if present then
55 unit "atopacct.service" "active"
56 + ''
57 with subtest("atopacct.service should enable process accounting"):
58 machine.succeed("test -f /run/pacct_source")
59
60 with subtest("atopacct.service should write data to /run/pacct_shadow.d"):
61 files = int(machine.succeed("ls -1 /run/pacct_shadow.d | wc -l"))
62 assert files >= 1, "Expected at least 1 pacct_shadow.d file"
63 '' else unit "atopacct.service" "inactive";
64 netatop = present:
65 if present then
66 unit "netatop.service" "active"
67 + ''
68 with subtest("The netatop kernel module should be loaded"):
69 out = machine.succeed("modprobe -n -v netatop")
70 assert out == "", f"Module should be loaded already, but modprobe would have done {out}."
71 '' else ''
72 with subtest("The netatop kernel module should be absent"):
73 machine.fail("modprobe -n -v netatop")
74 '';
75 atopgpu = present:
76 if present then
77 (unit "atopgpu.service" "active") + (path "atopgpud" "/run/current-system/sw/bin/atopgpud")
78 else (unit "atopgpu.service" "inactive") + ''
79 with subtest("atopgpud should not be present"):
80 machine.fail("type -p atopgpud")
81 '';
82};
83in
84{
85 name = "atop";
86
87 justThePackage = makeTest {
88 name = "atop-justThePackage";
89 machine = {
90 environment.systemPackages = [ pkgs.atop ];
91 };
92 testScript = with assertions; builtins.concatStringsSep "\n" [
93 version
94 (atoprc "")
95 (wrapper false)
96 (atopService false)
97 (atopRotateTimer false)
98 (atopacctService false)
99 (netatop false)
100 (atopgpu false)
101 ];
102 };
103 defaults = makeTest {
104 name = "atop-defaults";
105 machine = {
106 programs.atop = {
107 enable = true;
108 };
109 };
110 testScript = with assertions; builtins.concatStringsSep "\n" [
111 version
112 (atoprc "")
113 (wrapper false)
114 (atopService true)
115 (atopRotateTimer true)
116 (atopacctService true)
117 (netatop false)
118 (atopgpu false)
119 ];
120 };
121 minimal = makeTest {
122 name = "atop-minimal";
123 machine = {
124 programs.atop = {
125 enable = true;
126 atopService.enable = false;
127 atopRotateTimer.enable = false;
128 atopacctService.enable = false;
129 };
130 };
131 testScript = with assertions; builtins.concatStringsSep "\n" [
132 version
133 (atoprc "")
134 (wrapper false)
135 (atopService false)
136 (atopRotateTimer false)
137 (atopacctService false)
138 (netatop false)
139 (atopgpu false)
140 ];
141 };
142 netatop = makeTest {
143 name = "atop-netatop";
144 machine = {
145 programs.atop = {
146 enable = true;
147 netatop.enable = true;
148 };
149 };
150 testScript = with assertions; builtins.concatStringsSep "\n" [
151 version
152 (atoprc "")
153 (wrapper false)
154 (atopService true)
155 (atopRotateTimer true)
156 (atopacctService true)
157 (netatop true)
158 (atopgpu false)
159 ];
160 };
161 atopgpu = makeTest {
162 name = "atop-atopgpu";
163 machine = {
164 nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (getName pkg) [
165 "cudatoolkit"
166 ];
167
168 programs.atop = {
169 enable = true;
170 atopgpu.enable = true;
171 };
172 };
173 testScript = with assertions; builtins.concatStringsSep "\n" [
174 version
175 (atoprc "")
176 (wrapper false)
177 (atopService true)
178 (atopRotateTimer true)
179 (atopacctService true)
180 (netatop false)
181 (atopgpu true)
182 ];
183 };
184 everything = makeTest {
185 name = "atop-everthing";
186 machine = {
187 nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (getName pkg) [
188 "cudatoolkit"
189 ];
190
191 programs.atop = {
192 enable = true;
193 settings = {
194 flags = "faf1";
195 interval = 2;
196 };
197 setuidWrapper.enable = true;
198 netatop.enable = true;
199 atopgpu.enable = true;
200 };
201 };
202 testScript = with assertions; builtins.concatStringsSep "\n" [
203 version
204 (atoprc "flags faf1\\ninterval 2\\n")
205 (wrapper true)
206 (atopService true)
207 (atopRotateTimer true)
208 (atopacctService true)
209 (netatop true)
210 (atopgpu true)
211 ];
212 };
213}