1import ../make-test-python.nix (
2 { pkgs, lib, ... }:
3 let
4 host = "smoke.test";
5 port = 8065;
6 url = "http://${host}:${toString port}";
7 siteName = "NixOS Smoke Tests, Inc.";
8
9 makeMattermost =
10 mattermostConfig: extraConfig:
11 lib.mkMerge [
12 (
13 { config, ... }:
14 {
15 environment = {
16 systemPackages = [
17 pkgs.mattermost
18 pkgs.curl
19 pkgs.jq
20 ];
21 };
22 networking.hosts = {
23 "127.0.0.1" = [ host ];
24 };
25
26 # Assume that Postgres won't update across stateVersion.
27 services.postgresql = {
28 package = lib.mkForce pkgs.postgresql;
29 initialScript = lib.mkIf (!config.services.mattermost.database.peerAuth) (
30 pkgs.writeText "init.sql" ''
31 create role ${config.services.mattermost.database.user} with login nocreatedb nocreaterole encrypted password '${config.services.mattermost.database.password}';
32 ''
33 );
34 };
35
36 system.stateVersion = lib.mkDefault (lib.versions.majorMinor lib.version);
37
38 services.mattermost = lib.recursiveUpdate {
39 enable = true;
40 inherit siteName;
41 host = "0.0.0.0";
42 inherit port;
43 siteUrl = url;
44 socket = {
45 enable = true;
46 export = true;
47 };
48 database = {
49 peerAuth = lib.mkDefault true;
50 };
51 telemetry.enableSecurityAlerts = false;
52 settings = {
53 SupportSettings.AboutLink = "https://nixos.org";
54 PluginSettings.AutomaticPrepackagedPlugins = false;
55 AnnouncementSettings = {
56 # Disable this since it doesn't work in the sandbox and causes a timeout.
57 AdminNoticesEnabled = false;
58 UserNoticesEnabled = false;
59 };
60 };
61 } mattermostConfig;
62
63 # Upgrade to the latest Mattermost.
64 specialisation.latest.configuration = {
65 services.mattermost.package = lib.mkForce pkgs.mattermostLatest;
66 system.stateVersion = lib.mkVMOverride (lib.versions.majorMinor lib.version);
67 };
68 }
69 )
70 extraConfig
71 ];
72
73 makeMysql =
74 mattermostConfig: extraConfig:
75 lib.mkMerge [
76 mattermostConfig
77 (
78 { pkgs, config, ... }:
79 {
80 services.mattermost.database = {
81 driver = lib.mkForce "mysql";
82 peerAuth = lib.mkForce true;
83 };
84 }
85 )
86 extraConfig
87 ];
88 in
89 {
90 name = "mattermost";
91
92 nodes = rec {
93 postgresMutable = makeMattermost {
94 mutableConfig = true;
95 preferNixConfig = false;
96 settings.SupportSettings.HelpLink = "https://search.nixos.org";
97 } { };
98 postgresMostlyMutable =
99 makeMattermost
100 {
101 mutableConfig = true;
102 preferNixConfig = true;
103 plugins = with pkgs; [
104 # Build the demo plugin.
105 (mattermost.buildPlugin {
106 pname = "mattermost-plugin-starter-template";
107 version = "0.1.0";
108 src = fetchFromGitHub {
109 owner = "mattermost";
110 repo = "mattermost-plugin-starter-template";
111 # Newer versions have issues with their dependency lockfile.
112 rev = "7c98e89ac1a268ce8614bc665571b7bbc9a70df2";
113 hash = "sha256-uyfxB0GZ45qL9ssWUord0eKQC6S0TlCTtjTOXWtK4H0=";
114 };
115 vendorHash = "sha256-Jl4F9YkHNqiFP9/yeyi4vTntqxMk/J1zhEP6QLSvJQA=";
116 npmDepsHash = "sha256-z08nc4XwT+uQjQlZiUydJyh8mqeJoYdPFWuZpw9k99s=";
117 })
118
119 # Build the todos plugin.
120 (mattermost.buildPlugin {
121 pname = "mattermost-plugin-todo";
122 version = "0.8-pre";
123 src = fetchFromGitHub {
124 owner = "mattermost-community";
125 repo = "mattermost-plugin-todo";
126 # 0.7.1 didn't work, seems to use an older set of node dependencies.
127 rev = "f25dc91ea401c9f0dcd4abcebaff10eb8b9836e5";
128 hash = "sha256-OM+m4rTqVtolvL5tUE8RKfclqzoe0Y38jLU60Pz7+HI=";
129 };
130 vendorHash = "sha256-5KpechSp3z/Nq713PXYruyNxveo6CwrCSKf2JaErbgg=";
131 npmDepsHash = "sha256-o2UOEkwb8Vx2lDWayNYgng0GXvmS6lp/ExfOq3peyMY=";
132 extraGoModuleAttrs = {
133 npmFlags = [ "--legacy-peer-deps" ];
134 };
135 })
136 ];
137 }
138 {
139 # Last version to support the "old" config layout.
140 system.stateVersion = lib.mkForce "24.11";
141
142 # Supports the "new" config layout.
143 specialisation.upgrade.configuration.system.stateVersion = lib.mkVMOverride (
144 lib.versions.majorMinor lib.version
145 );
146 };
147 postgresImmutable = makeMattermost {
148 package = pkgs.mattermost.overrideAttrs (prev: {
149 webapp = prev.webapp.overrideAttrs (prevWebapp: {
150 # Ensure that users can add patches.
151 postPatch =
152 prevWebapp.postPatch or ""
153 + ''
154 substituteInPlace channels/src/root.html --replace-fail "Mattermost" "Patched Mattermost"
155 '';
156 });
157 });
158 mutableConfig = false;
159
160 # Make sure something other than the default works.
161 user = "mmuser";
162 group = "mmgroup";
163
164 database = {
165 # Ensure that this gets tested on Postgres.
166 peerAuth = false;
167 };
168 settings.SupportSettings.HelpLink = "https://search.nixos.org";
169 } { };
170 postgresEnvironmentFile = makeMattermost {
171 mutableConfig = false;
172 database.fromEnvironment = true;
173 settings.SupportSettings.AboutLink = "https://example.org";
174 environmentFile = pkgs.writeText "mattermost-env" ''
175 MM_SQLSETTINGS_DATASOURCE=postgres:///mattermost?host=/run/postgresql
176 MM_SUPPORTSETTINGS_ABOUTLINK=https://nixos.org
177 '';
178 } { };
179
180 mysqlMutable = makeMysql postgresMutable { };
181 mysqlMostlyMutable = makeMysql postgresMostlyMutable { };
182 mysqlImmutable = makeMysql postgresImmutable {
183 # Let's try to use this on MySQL.
184 services.mattermost.database = {
185 peerAuth = lib.mkForce true;
186 user = lib.mkForce "mmuser";
187 name = lib.mkForce "mmuser";
188 };
189 };
190 mysqlEnvironmentFile = makeMysql postgresEnvironmentFile {
191 services.mattermost.environmentFile = lib.mkForce (
192 pkgs.writeText "mattermost-env" ''
193 MM_SQLSETTINGS_DATASOURCE=mattermost@unix(/run/mysqld/mysqld.sock)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s
194 MM_SUPPORTSETTINGS_ABOUTLINK=https://nixos.org
195 ''
196 );
197 };
198 };
199
200 testScript =
201 { nodes, ... }:
202 let
203 expectConfig = pkgs.writeShellScript "expect-config" ''
204 set -euo pipefail
205 config="$(curl ${lib.escapeShellArg "${url}/api/v4/config/client?format=old"})"
206 echo "Config: $(echo "$config" | ${pkgs.jq}/bin/jq)" >&2
207 [[ "$(echo "$config" | ${pkgs.jq}/bin/jq -r ${lib.escapeShellArg ".SiteName == $siteName and .Version == $mattermostVersion and "}"($1)" --arg siteName ${lib.escapeShellArg siteName} --arg mattermostVersion "$2" --arg sep '-')" = "true" ]]
208 '';
209
210 setConfig = pkgs.writeShellScript "set-config" ''
211 set -eo pipefail
212 mattermostConfig=/etc/mattermost/config.json
213 nixosVersion="$2"
214 if [ -z "$nixosVersion" ]; then
215 nixosVersion="$(nixos-version)"
216 fi
217 nixosVersion="$(echo "$nixosVersion" | sed -nr 's/^([0-9]{2})\.([0-9]{2}).*/\1\2/p')"
218 echo "NixOS version: $nixosVersion" >&2
219 if [ "$nixosVersion" -lt 2505 ]; then
220 mattermostConfig=/var/lib/mattermost/config/config.json
221 fi
222 newConfig="$(${pkgs.jq}/bin/jq -r "$1" "$mattermostConfig")"
223 echo "New config @ $mattermostConfig: $(echo "$newConfig" | ${pkgs.jq}/bin/jq)" >&2
224 truncate -s 0 "$mattermostConfig"
225 echo "$newConfig" >> "$mattermostConfig"
226 '';
227
228 expectPlugins = pkgs.writeShellScript "expect-plugins" ''
229 set -euo pipefail
230 case "$1" in
231 ""|*[!0-9]*)
232 plugins="$(curl ${lib.escapeShellArg "${url}/api/v4/plugins/webapp"})"
233 echo "Plugins: $(echo "$plugins" | ${pkgs.jq}/bin/jq)" >&2
234 [[ "$(echo "$plugins" | ${pkgs.jq}/bin/jq -r "$1")" == "true" ]]
235 ;;
236 *)
237 code="$(curl -s -o /dev/null -w "%{http_code}" ${lib.escapeShellArg "${url}/api/v4/plugins/webapp"})"
238 [[ "$code" == "$1" ]]
239 ;;
240 esac
241 '';
242
243 ensurePost = pkgs.writeShellScript "ensure-post" ''
244 set -euo pipefail
245
246 url="$1"
247 failIfNotFound="$2"
248
249 # Make sure the user exists
250 thingExists='(type == "array" and length > 0)'
251 userExists="($thingExists and ("'.[0].username == "nixos"))'
252 if mmctl user list --json | jq | tee /dev/stderr | jq -e "$userExists | not"; then
253 if [ "$failIfNotFound" -ne 0 ]; then
254 echo "User didn't exist!" >&2
255 exit 1
256 else
257 mmctl user create \
258 --email tests@nixos.org \
259 --username nixos --password nixosrules --system-admin --email-verified >&2
260
261 # Make sure the user exists.
262 while mmctl user list --json | jq | tee /dev/stderr | jq -e "$userExists | not"; do
263 sleep 1
264 done
265 fi
266 fi
267
268 # Auth.
269 mmctl auth login "$url" --name nixos --username nixos --password nixosrules
270
271 # Make sure the team exists
272 teamExists="($thingExists and ("'.[0].display_name == "NixOS Smoke Tests, Inc."))'
273 if mmctl team list --json | jq | tee /dev/stderr | jq -e "$teamExists | not"; then
274 if [ "$failIfNotFound" -ne 0 ]; then
275 echo "Team didn't exist!" >&2
276 exit 1
277 else
278 mmctl team create \
279 --name nixos \
280 --display-name "NixOS Smoke Tests, Inc."
281
282 # Teams take a second to create.
283 while mmctl team list --json | jq | tee /dev/stderr | jq -e "$teamExists | not"; do
284 sleep 1
285 done
286
287 # Add the user.
288 mmctl team users add nixos tests@nixos.org
289 fi
290 fi
291
292 authToken="$(cat ~/.config/mmctl/config | jq -r '.nixos.authToken')"
293 authHeader="Authorization: Bearer $authToken"
294 acceptHeader="Accept: application/json; charset=UTF-8"
295
296 # Make sure the test post exists.
297 postContents="pls enjoy this NixOS meme I made"
298 postAttachment=${./test.jpg}
299 postAttachmentSize="$(stat -c%s $postAttachment)"
300 postAttachmentHash="$(sha256sum $postAttachment | awk '{print $1}')"
301 postAttachmentId=""
302 postPredicate='select(.message == $message and (.file_ids | length) > 0 and (.metadata.files[0].size | tonumber) == ($size | tonumber))'
303 postExists="($thingExists and ("'(.[] | '"$postPredicate"' | length) > 0))'
304 if mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | jq --arg message "$postContents" --arg size "$postAttachmentSize" -e "$postExists | not"; then
305 if [ "$failIfNotFound" -ne 0 ]; then
306 echo "Post didn't exist!" >&2
307 exit 1
308 else
309 # Can't use mmcli for this seemingly.
310 channelId="$(mmctl channel list nixos --json | jq | tee /dev/stderr | jq -r '.[] | select(.name == "off-topic") | .id')"
311 echo "Channel ID: $channelId" >&2
312
313 # Upload the file.
314 echo "Uploading file at $postAttachment (size: $postAttachmentSize)..." >&2
315 postAttachmentId="$(curl "$url/api/v4/files" -X POST -H "$acceptHeader" -H "$authHeader" \
316 -F "files=@$postAttachment" -F "channel_id=$channelId" -F "client_ids=test" | jq | tee /dev/stderr | jq -r '.file_infos[0].id')"
317
318 # Create the post with it attached.
319 postJson="$(echo '{}' | jq -c --arg channelId "$channelId" --arg message "$postContents" --arg fileId "$postAttachmentId" \
320 '{channel_id: $channelId, message: $message, file_ids: [$fileId]}')"
321 echo "Creating post with contents $postJson..." >&2
322 curl "$url/api/v4/posts" -X POST -H "$acceptHeader" -H "$authHeader" --json "$postJson" | jq >&2
323 fi
324 fi
325
326 if mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | jq --arg message "$postContents" --arg size "$postAttachmentSize" -e "$postExists"; then
327 # Get the attachment ID.
328 getPostAttachmentId=".[] | $postPredicate | .file_ids[0]"
329 postAttachmentId="$(mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | \
330 jq --arg message "$postContents" --arg size "$postAttachmentSize" -r "$getPostAttachmentId")"
331
332 echo "Expected post attachment hash: $postAttachmentHash" >&2
333 actualPostAttachmentHash="$(curl "$url/api/v4/files/$postAttachmentId?download=1" -H "$authHeader" | sha256sum | awk '{print $1}')"
334 echo "Actual post attachment hash: $postAttachmentHash" >&2
335 if [ "$actualPostAttachmentHash" != "$postAttachmentHash" ]; then
336 echo "Post attachment hash mismatched!" >&2
337 exit 1
338 fi
339
340 # Make sure it's on the filesystem in the expected place
341 fsPath="$(find /var/lib/mattermost/data -name "$(basename -- "$postAttachment")" -print -quit)"
342 if [ -z "$fsPath" ] || [ ! -f "$fsPath" ]; then
343 echo "Attachment didn't exist on the filesystem!" >&2
344 exit 1
345 fi
346
347 # And that the hash matches.
348 actualFsAttachmentHash="$(sha256sum "$fsPath" | awk '{print $1}')"
349 if [ "$actualFsAttachmentHash" == "$postAttachmentHash" ]; then
350 echo "Post attachment hash was OK!" >&2
351 exit 0
352 else
353 echo "Attachment hash mismatched on disk!" >&2
354 exit 1
355 fi
356 else
357 echo "Post didn't exist when it should have!" >&2
358 exit 1
359 fi
360 '';
361 in
362 ''
363 import sys
364 import shlex
365 import threading
366 import queue
367
368 def wait_mattermost_up(node, site_name="${siteName}"):
369 print(f"wait_mattermost_up({node.name!r}, site_name={site_name!r})", file=sys.stderr)
370 node.wait_for_unit("multi-user.target")
371 node.systemctl("start mattermost.service")
372 node.wait_for_unit("mattermost.service")
373 node.wait_for_open_port(8065)
374 node.succeed(f"curl {shlex.quote('${url}')} >/dev/null")
375 node.succeed(f"curl {shlex.quote('${url}')}/index.html | grep {shlex.quote(site_name)}")
376
377 def restart_mattermost(node, site_name="${siteName}"):
378 print(f"restart_mattermost({node.name!r}, site_name={site_name!r})", file=sys.stderr)
379 node.systemctl("restart mattermost.service")
380 wait_mattermost_up(node, site_name)
381
382 def expect_config(node, mattermost_version, *configs):
383 print(f"expect_config({node.name!r}, {mattermost_version!r}, *{configs!r})", file=sys.stderr)
384 for config in configs:
385 node.succeed(f"${expectConfig} {shlex.quote(config)} {shlex.quote(mattermost_version)}")
386
387 def expect_plugins(node, jq_or_code):
388 print(f"expect_plugins({node.name!r}, {jq_or_code!r})", file=sys.stderr)
389 node.succeed(f"${expectPlugins} {shlex.quote(str(jq_or_code))}")
390
391 def ensure_post(node, fail_if_not_found=False):
392 print(f"ensure_post({node.name!r}, fail_if_not_found={fail_if_not_found!r})", file=sys.stderr)
393 node.succeed(f"${ensurePost} {shlex.quote('${url}')} {1 if fail_if_not_found else 0}")
394
395 def set_config(node, *configs, nixos_version='${lib.versions.majorMinor lib.version}'):
396 print(f"set_config({node.name!r}, *{configs!r}, nixos_version={nixos_version!r})", file=sys.stderr)
397 for config in configs:
398 args = [shlex.quote("${setConfig}")]
399 args.append(shlex.quote(config))
400 if nixos_version:
401 args.append(shlex.quote(str(nixos_version)))
402 node.succeed(' '.join(args))
403
404 def switch_to_specialisation(node, toplevel: str, specialisation: str):
405 print(f"switch_to_specialisation({node.name!r}, {toplevel!r}, {specialisation!r})", file=sys.stderr)
406 node.succeed(f"{toplevel}/specialisation/{specialisation}/bin/switch-to-configuration switch || true")
407
408 def run_mattermost_tests(shutdown_queue: queue.Queue,
409 mutableToplevel: str, mutable,
410 mostlyMutableToplevel: str, mostlyMutablePlugins: str, mostlyMutable,
411 immutableToplevel: str, immutable,
412 environmentFileToplevel: str, environmentFile):
413 esr, latest = '${pkgs.mattermost.version}', '${pkgs.mattermostLatest.version}'
414
415 ## Mutable node tests ##
416 mutable.start()
417 wait_mattermost_up(mutable)
418
419 # Get the initial config
420 expect_config(mutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
421
422 # Edit the config and make a post
423 set_config(
424 mutable,
425 '.SupportSettings.AboutLink = "https://mattermost.com"',
426 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"'
427 )
428 ensure_post(mutable)
429 restart_mattermost(mutable)
430
431 # AboutLink and HelpLink should be changed, and the post should exist
432 expect_config(mutable, esr, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
433 ensure_post(mutable, fail_if_not_found=True)
434
435 # Switch to the latest Mattermost version
436 switch_to_specialisation(mutable, mutableToplevel, "latest")
437 wait_mattermost_up(mutable)
438
439 # AboutLink and HelpLink should be changed, still, and the post should still exist
440 expect_config(mutable, latest, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
441 ensure_post(mutable, fail_if_not_found=True)
442 shutdown_queue.put(mutable)
443
444 ## Mostly mutable node tests ##
445 mostlyMutable.start()
446 wait_mattermost_up(mostlyMutable)
447
448 # Get the initial config
449 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org"')
450
451 # No plugins.
452 expect_plugins(mostlyMutable, 'length == 0')
453
454 # Edit the config and make a post
455 set_config(
456 mostlyMutable,
457 '.SupportSettings.AboutLink = "https://mattermost.com"',
458 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"',
459 nixos_version='24.11' # Default 'mostlyMutable' config is an old version
460 )
461 ensure_post(mostlyMutable)
462 restart_mattermost(mostlyMutable)
463
464 # HelpLink should be changed but AboutLink should not, and the post should exist
465 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
466 ensure_post(mostlyMutable, fail_if_not_found=True)
467
468 # Switch to the newer config and make sure the plugins directory is replaced with a directory,
469 # since it could have been a symlink on previous versions.
470 mostlyMutable.systemctl("stop mattermost.service")
471 mostlyMutable.succeed('[ -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]')
472 switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "upgrade")
473 wait_mattermost_up(mostlyMutable)
474
475 # HelpLink should be changed, still, and the post should still exist
476 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
477 ensure_post(mostlyMutable, fail_if_not_found=True)
478
479 # Edit the config and make a post
480 set_config(
481 mostlyMutable,
482 '.SupportSettings.AboutLink = "https://mattermost.com/foo"',
483 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual/bar"',
484 '.PluginSettings.PluginStates."com.mattermost.plugin-todo".Enable = true'
485 )
486 ensure_post(mostlyMutable)
487 restart_mattermost(mostlyMutable)
488
489 # AboutLink should be overridden by NixOS configuration; HelpLink should be what we set above
490 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual/bar"')
491
492 # Single plugin that's now enabled.
493 expect_plugins(mostlyMutable, 'length == 1')
494
495 # Post should exist.
496 ensure_post(mostlyMutable, fail_if_not_found=True)
497
498 # Switch to the latest Mattermost version
499 switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "latest")
500 wait_mattermost_up(mostlyMutable)
501
502 # AboutLink should be overridden and the post should still exist
503 expect_config(mostlyMutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual/bar"')
504 ensure_post(mostlyMutable, fail_if_not_found=True)
505
506 shutdown_queue.put(mostlyMutable)
507
508 ## Immutable node tests ##
509 immutable.start()
510 wait_mattermost_up(immutable, "Patched Mattermost")
511
512 # Get the initial config
513 expect_config(immutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
514
515 # Edit the config and make a post
516 set_config(
517 immutable,
518 '.SupportSettings.AboutLink = "https://mattermost.com"',
519 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"'
520 )
521 ensure_post(immutable)
522 restart_mattermost(immutable, "Patched Mattermost")
523
524 # Our edits should be ignored on restart
525 expect_config(immutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
526
527 # No plugins.
528 expect_plugins(immutable, 'length == 0')
529
530 # Post should exist.
531 ensure_post(immutable, fail_if_not_found=True)
532
533 # Switch to the latest Mattermost version
534 switch_to_specialisation(immutable, immutableToplevel, "latest")
535 wait_mattermost_up(immutable)
536
537 # AboutLink and HelpLink should be changed, still, and the post should still exist
538 expect_config(immutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
539 ensure_post(immutable, fail_if_not_found=True)
540
541 shutdown_queue.put(immutable)
542
543 ## Environment File node tests ##
544 environmentFile.start()
545 wait_mattermost_up(environmentFile)
546 ensure_post(environmentFile)
547
548 # Settings in the environment file should override settings set otherwise, and the post should exist
549 expect_config(environmentFile, esr, '.AboutLink == "https://nixos.org"')
550 ensure_post(environmentFile, fail_if_not_found=True)
551
552 # Switch to the latest Mattermost version
553 switch_to_specialisation(environmentFile, environmentFileToplevel, "latest")
554 wait_mattermost_up(environmentFile)
555
556 # AboutLink should be changed still, and the post should still exist
557 expect_config(environmentFile, latest, '.AboutLink == "https://nixos.org"')
558 ensure_post(environmentFile, fail_if_not_found=True)
559
560 shutdown_queue.put(environmentFile)
561
562 # Run shutdowns asynchronously so we can pipeline them.
563 shutdown_queue: queue.Queue = queue.Queue()
564 def shutdown_worker():
565 while True:
566 node = shutdown_queue.get()
567 print(f"Shutting down node {node.name!r} asynchronously", file=sys.stderr)
568 node.shutdown()
569 shutdown_queue.task_done()
570 threading.Thread(target=shutdown_worker, daemon=True).start()
571
572 ${pkgs.lib.optionalString pkgs.stdenv.isx86_64 ''
573 # Only run the MySQL tests on x86_64 so we don't have to debug MySQL ARM issues.
574 run_mattermost_tests(
575 shutdown_queue,
576 "${nodes.mysqlMutable.system.build.toplevel}",
577 mysqlMutable,
578 "${nodes.mysqlMostlyMutable.system.build.toplevel}",
579 "${nodes.mysqlMostlyMutable.services.mattermost.pluginsBundle}",
580 mysqlMostlyMutable,
581 "${nodes.mysqlImmutable.system.build.toplevel}",
582 mysqlImmutable,
583 "${nodes.mysqlEnvironmentFile.system.build.toplevel}",
584 mysqlEnvironmentFile
585 )
586 ''}
587
588 run_mattermost_tests(
589 shutdown_queue,
590 "${nodes.postgresMutable.system.build.toplevel}",
591 postgresMutable,
592 "${nodes.postgresMostlyMutable.system.build.toplevel}",
593 "${nodes.postgresMostlyMutable.services.mattermost.pluginsBundle}",
594 postgresMostlyMutable,
595 "${nodes.postgresImmutable.system.build.toplevel}",
596 postgresImmutable,
597 "${nodes.postgresEnvironmentFile.system.build.toplevel}",
598 postgresEnvironmentFile
599 )
600
601 # Drain the queue
602 shutdown_queue.join()
603 '';
604 }
605)