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 = prevWebapp.postPatch or "" + ''
152 substituteInPlace channels/src/root.html --replace-fail "Mattermost" "Patched Mattermost"
153 '';
154 });
155 });
156 mutableConfig = false;
157
158 # Make sure something other than the default works.
159 user = "mmuser";
160 group = "mmgroup";
161
162 database = {
163 # Ensure that this gets tested on Postgres.
164 peerAuth = false;
165 };
166 settings.SupportSettings.HelpLink = "https://search.nixos.org";
167 } { };
168 postgresEnvironmentFile = makeMattermost {
169 mutableConfig = false;
170 database.fromEnvironment = true;
171 settings.SupportSettings.AboutLink = "https://example.org";
172 environmentFile = pkgs.writeText "mattermost-env" ''
173 MM_SQLSETTINGS_DATASOURCE=postgres:///mattermost?host=/run/postgresql
174 MM_SUPPORTSETTINGS_ABOUTLINK=https://nixos.org
175 '';
176 } { };
177
178 mysqlMutable = makeMysql postgresMutable { };
179 mysqlMostlyMutable = makeMysql postgresMostlyMutable { };
180 mysqlImmutable = makeMysql postgresImmutable {
181 # Let's try to use this on MySQL.
182 services.mattermost.database = {
183 peerAuth = lib.mkForce true;
184 user = lib.mkForce "mmuser";
185 name = lib.mkForce "mmuser";
186 };
187 };
188 mysqlEnvironmentFile = makeMysql postgresEnvironmentFile {
189 services.mattermost.environmentFile = lib.mkForce (
190 pkgs.writeText "mattermost-env" ''
191 MM_SQLSETTINGS_DATASOURCE=mattermost@unix(/run/mysqld/mysqld.sock)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s
192 MM_SUPPORTSETTINGS_ABOUTLINK=https://nixos.org
193 ''
194 );
195 };
196 };
197
198 testScript =
199 { nodes, ... }:
200 let
201 expectConfig = pkgs.writeShellScript "expect-config" ''
202 set -euo pipefail
203 config="$(curl ${lib.escapeShellArg "${url}/api/v4/config/client?format=old"})"
204 echo "Config: $(echo "$config" | ${pkgs.jq}/bin/jq)" >&2
205 [[ "$(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" ]]
206 '';
207
208 setConfig = pkgs.writeShellScript "set-config" ''
209 set -eo pipefail
210 mattermostConfig=/etc/mattermost/config.json
211 nixosVersion="$2"
212 if [ -z "$nixosVersion" ]; then
213 nixosVersion="$(nixos-version)"
214 fi
215 nixosVersion="$(echo "$nixosVersion" | sed -nr 's/^([0-9]{2})\.([0-9]{2}).*/\1\2/p')"
216 echo "NixOS version: $nixosVersion" >&2
217 if [ "$nixosVersion" -lt 2505 ]; then
218 mattermostConfig=/var/lib/mattermost/config/config.json
219 fi
220 newConfig="$(${pkgs.jq}/bin/jq -r "$1" "$mattermostConfig")"
221 echo "New config @ $mattermostConfig: $(echo "$newConfig" | ${pkgs.jq}/bin/jq)" >&2
222 truncate -s 0 "$mattermostConfig"
223 echo "$newConfig" >> "$mattermostConfig"
224 '';
225
226 expectPlugins = pkgs.writeShellScript "expect-plugins" ''
227 set -euo pipefail
228 case "$1" in
229 ""|*[!0-9]*)
230 plugins="$(curl ${lib.escapeShellArg "${url}/api/v4/plugins/webapp"})"
231 echo "Plugins: $(echo "$plugins" | ${pkgs.jq}/bin/jq)" >&2
232 [[ "$(echo "$plugins" | ${pkgs.jq}/bin/jq -r "$1")" == "true" ]]
233 ;;
234 *)
235 code="$(curl -s -o /dev/null -w "%{http_code}" ${lib.escapeShellArg "${url}/api/v4/plugins/webapp"})"
236 [[ "$code" == "$1" ]]
237 ;;
238 esac
239 '';
240
241 ensurePost = pkgs.writeShellScript "ensure-post" ''
242 set -euo pipefail
243
244 url="$1"
245 failIfNotFound="$2"
246
247 # Make sure the user exists
248 thingExists='(type == "array" and length > 0)'
249 userExists="($thingExists and ("'.[0].username == "nixos"))'
250 if mmctl user list --json | jq | tee /dev/stderr | jq -e "$userExists | not"; then
251 if [ "$failIfNotFound" -ne 0 ]; then
252 echo "User didn't exist!" >&2
253 exit 1
254 else
255 mmctl user create \
256 --email tests@nixos.org \
257 --username nixos --password nixosrules --system-admin --email-verified >&2
258
259 # Make sure the user exists.
260 while mmctl user list --json | jq | tee /dev/stderr | jq -e "$userExists | not"; do
261 sleep 1
262 done
263 fi
264 fi
265
266 # Auth.
267 mmctl auth login "$url" --name nixos --username nixos --password nixosrules
268
269 # Make sure the team exists
270 teamExists="($thingExists and ("'.[0].display_name == "NixOS Smoke Tests, Inc."))'
271 if mmctl team list --json | jq | tee /dev/stderr | jq -e "$teamExists | not"; then
272 if [ "$failIfNotFound" -ne 0 ]; then
273 echo "Team didn't exist!" >&2
274 exit 1
275 else
276 mmctl team create \
277 --name nixos \
278 --display-name "NixOS Smoke Tests, Inc."
279
280 # Teams take a second to create.
281 while mmctl team list --json | jq | tee /dev/stderr | jq -e "$teamExists | not"; do
282 sleep 1
283 done
284
285 # Add the user.
286 mmctl team users add nixos tests@nixos.org
287 fi
288 fi
289
290 authToken="$(cat ~/.config/mmctl/config | jq -r '.nixos.authToken')"
291 authHeader="Authorization: Bearer $authToken"
292 acceptHeader="Accept: application/json; charset=UTF-8"
293
294 # Make sure the test post exists.
295 postContents="pls enjoy this NixOS meme I made"
296 postAttachment=${./test.jpg}
297 postAttachmentSize="$(stat -c%s $postAttachment)"
298 postAttachmentHash="$(sha256sum $postAttachment | awk '{print $1}')"
299 postAttachmentId=""
300 postPredicate='select(.message == $message and (.file_ids | length) > 0 and (.metadata.files[0].size | tonumber) == ($size | tonumber))'
301 postExists="($thingExists and ("'(.[] | '"$postPredicate"' | length) > 0))'
302 if mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | jq --arg message "$postContents" --arg size "$postAttachmentSize" -e "$postExists | not"; then
303 if [ "$failIfNotFound" -ne 0 ]; then
304 echo "Post didn't exist!" >&2
305 exit 1
306 else
307 # Can't use mmcli for this seemingly.
308 channelId="$(mmctl channel list nixos --json | jq | tee /dev/stderr | jq -r '.[] | select(.name == "off-topic") | .id')"
309 echo "Channel ID: $channelId" >&2
310
311 # Upload the file.
312 echo "Uploading file at $postAttachment (size: $postAttachmentSize)..." >&2
313 postAttachmentId="$(curl "$url/api/v4/files" -X POST -H "$acceptHeader" -H "$authHeader" \
314 -F "files=@$postAttachment" -F "channel_id=$channelId" -F "client_ids=test" | jq | tee /dev/stderr | jq -r '.file_infos[0].id')"
315
316 # Create the post with it attached.
317 postJson="$(echo '{}' | jq -c --arg channelId "$channelId" --arg message "$postContents" --arg fileId "$postAttachmentId" \
318 '{channel_id: $channelId, message: $message, file_ids: [$fileId]}')"
319 echo "Creating post with contents $postJson..." >&2
320 curl "$url/api/v4/posts" -X POST -H "$acceptHeader" -H "$authHeader" --json "$postJson" | jq >&2
321 fi
322 fi
323
324 if mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | jq --arg message "$postContents" --arg size "$postAttachmentSize" -e "$postExists"; then
325 # Get the attachment ID.
326 getPostAttachmentId=".[] | $postPredicate | .file_ids[0]"
327 postAttachmentId="$(mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | \
328 jq --arg message "$postContents" --arg size "$postAttachmentSize" -r "$getPostAttachmentId")"
329
330 echo "Expected post attachment hash: $postAttachmentHash" >&2
331 actualPostAttachmentHash="$(curl "$url/api/v4/files/$postAttachmentId?download=1" -H "$authHeader" | sha256sum | awk '{print $1}')"
332 echo "Actual post attachment hash: $postAttachmentHash" >&2
333 if [ "$actualPostAttachmentHash" != "$postAttachmentHash" ]; then
334 echo "Post attachment hash mismatched!" >&2
335 exit 1
336 fi
337
338 # Make sure it's on the filesystem in the expected place
339 fsPath="$(find /var/lib/mattermost/data -name "$(basename -- "$postAttachment")" -print -quit)"
340 if [ -z "$fsPath" ] || [ ! -f "$fsPath" ]; then
341 echo "Attachment didn't exist on the filesystem!" >&2
342 exit 1
343 fi
344
345 # And that the hash matches.
346 actualFsAttachmentHash="$(sha256sum "$fsPath" | awk '{print $1}')"
347 if [ "$actualFsAttachmentHash" == "$postAttachmentHash" ]; then
348 echo "Post attachment hash was OK!" >&2
349 exit 0
350 else
351 echo "Attachment hash mismatched on disk!" >&2
352 exit 1
353 fi
354 else
355 echo "Post didn't exist when it should have!" >&2
356 exit 1
357 fi
358 '';
359 in
360 ''
361 import sys
362 import shlex
363 import threading
364 import queue
365
366 def wait_mattermost_up(node, site_name="${siteName}"):
367 print(f"wait_mattermost_up({node.name!r}, site_name={site_name!r})", file=sys.stderr)
368 node.wait_for_unit("multi-user.target")
369 node.systemctl("start mattermost.service")
370 node.wait_for_unit("mattermost.service")
371 node.wait_for_open_port(8065)
372 node.succeed(f"curl {shlex.quote('${url}')} >/dev/null")
373 node.succeed(f"curl {shlex.quote('${url}')}/index.html | grep {shlex.quote(site_name)}")
374
375 def restart_mattermost(node, site_name="${siteName}"):
376 print(f"restart_mattermost({node.name!r}, site_name={site_name!r})", file=sys.stderr)
377 node.systemctl("restart mattermost.service")
378 wait_mattermost_up(node, site_name)
379
380 def expect_config(node, mattermost_version, *configs):
381 print(f"expect_config({node.name!r}, {mattermost_version!r}, *{configs!r})", file=sys.stderr)
382 for config in configs:
383 node.succeed(f"${expectConfig} {shlex.quote(config)} {shlex.quote(mattermost_version)}")
384
385 def expect_plugins(node, jq_or_code):
386 print(f"expect_plugins({node.name!r}, {jq_or_code!r})", file=sys.stderr)
387 node.succeed(f"${expectPlugins} {shlex.quote(str(jq_or_code))}")
388
389 def ensure_post(node, fail_if_not_found=False):
390 print(f"ensure_post({node.name!r}, fail_if_not_found={fail_if_not_found!r})", file=sys.stderr)
391 node.succeed(f"${ensurePost} {shlex.quote('${url}')} {1 if fail_if_not_found else 0}")
392
393 def set_config(node, *configs, nixos_version='${lib.versions.majorMinor lib.version}'):
394 print(f"set_config({node.name!r}, *{configs!r}, nixos_version={nixos_version!r})", file=sys.stderr)
395 for config in configs:
396 args = [shlex.quote("${setConfig}")]
397 args.append(shlex.quote(config))
398 if nixos_version:
399 args.append(shlex.quote(str(nixos_version)))
400 node.succeed(' '.join(args))
401
402 def switch_to_specialisation(node, toplevel: str, specialisation: str):
403 print(f"switch_to_specialisation({node.name!r}, {toplevel!r}, {specialisation!r})", file=sys.stderr)
404 node.succeed(f"{toplevel}/specialisation/{specialisation}/bin/switch-to-configuration switch || true")
405
406 def run_mattermost_tests(shutdown_queue: queue.Queue,
407 mutableToplevel: str, mutable,
408 mostlyMutableToplevel: str, mostlyMutablePlugins: str, mostlyMutable,
409 immutableToplevel: str, immutable,
410 environmentFileToplevel: str, environmentFile):
411 esr, latest = '${pkgs.mattermost.version}', '${pkgs.mattermostLatest.version}'
412
413 ## Mutable node tests ##
414 mutable.start()
415 wait_mattermost_up(mutable)
416
417 # Get the initial config
418 expect_config(mutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
419
420 # Edit the config and make a post
421 set_config(
422 mutable,
423 '.SupportSettings.AboutLink = "https://mattermost.com"',
424 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"'
425 )
426 ensure_post(mutable)
427 restart_mattermost(mutable)
428
429 # AboutLink and HelpLink should be changed, and the post should exist
430 expect_config(mutable, esr, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
431 ensure_post(mutable, fail_if_not_found=True)
432
433 # Switch to the latest Mattermost version
434 switch_to_specialisation(mutable, mutableToplevel, "latest")
435 wait_mattermost_up(mutable)
436
437 # AboutLink and HelpLink should be changed, still, and the post should still exist
438 expect_config(mutable, latest, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
439 ensure_post(mutable, fail_if_not_found=True)
440 shutdown_queue.put(mutable)
441
442 ## Mostly mutable node tests ##
443 mostlyMutable.start()
444 wait_mattermost_up(mostlyMutable)
445
446 # Get the initial config
447 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org"')
448
449 # No plugins.
450 expect_plugins(mostlyMutable, 'length == 0')
451
452 # Edit the config and make a post
453 set_config(
454 mostlyMutable,
455 '.SupportSettings.AboutLink = "https://mattermost.com"',
456 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"',
457 nixos_version='24.11' # Default 'mostlyMutable' config is an old version
458 )
459 ensure_post(mostlyMutable)
460 restart_mattermost(mostlyMutable)
461
462 # HelpLink should be changed but AboutLink should not, and the post should exist
463 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
464 ensure_post(mostlyMutable, fail_if_not_found=True)
465
466 # Switch to the newer config and make sure the plugins directory is replaced with a directory,
467 # since it could have been a symlink on previous versions.
468 mostlyMutable.systemctl("stop mattermost.service")
469 mostlyMutable.succeed('[ -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]')
470 switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "upgrade")
471 wait_mattermost_up(mostlyMutable)
472
473 # HelpLink should be changed, still, and the post should still exist
474 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
475 ensure_post(mostlyMutable, fail_if_not_found=True)
476
477 # Edit the config and make a post
478 set_config(
479 mostlyMutable,
480 '.SupportSettings.AboutLink = "https://mattermost.com/foo"',
481 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual/bar"',
482 '.PluginSettings.PluginStates."com.mattermost.plugin-todo".Enable = true'
483 )
484 ensure_post(mostlyMutable)
485 restart_mattermost(mostlyMutable)
486
487 # AboutLink should be overridden by NixOS configuration; HelpLink should be what we set above
488 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual/bar"')
489
490 # Single plugin that's now enabled.
491 expect_plugins(mostlyMutable, 'length == 1')
492
493 # Post should exist.
494 ensure_post(mostlyMutable, fail_if_not_found=True)
495
496 # Switch to the latest Mattermost version
497 switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "latest")
498 wait_mattermost_up(mostlyMutable)
499
500 # AboutLink should be overridden and the post should still exist
501 expect_config(mostlyMutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual/bar"')
502 ensure_post(mostlyMutable, fail_if_not_found=True)
503
504 shutdown_queue.put(mostlyMutable)
505
506 ## Immutable node tests ##
507 immutable.start()
508 wait_mattermost_up(immutable, "Patched Mattermost")
509
510 # Get the initial config
511 expect_config(immutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
512
513 # Edit the config and make a post
514 set_config(
515 immutable,
516 '.SupportSettings.AboutLink = "https://mattermost.com"',
517 '.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"'
518 )
519 ensure_post(immutable)
520 restart_mattermost(immutable, "Patched Mattermost")
521
522 # Our edits should be ignored on restart
523 expect_config(immutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
524
525 # No plugins.
526 expect_plugins(immutable, 'length == 0')
527
528 # Post should exist.
529 ensure_post(immutable, fail_if_not_found=True)
530
531 # Switch to the latest Mattermost version
532 switch_to_specialisation(immutable, immutableToplevel, "latest")
533 wait_mattermost_up(immutable)
534
535 # AboutLink and HelpLink should be changed, still, and the post should still exist
536 expect_config(immutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
537 ensure_post(immutable, fail_if_not_found=True)
538
539 shutdown_queue.put(immutable)
540
541 ## Environment File node tests ##
542 environmentFile.start()
543 wait_mattermost_up(environmentFile)
544 ensure_post(environmentFile)
545
546 # Settings in the environment file should override settings set otherwise, and the post should exist
547 expect_config(environmentFile, esr, '.AboutLink == "https://nixos.org"')
548 ensure_post(environmentFile, fail_if_not_found=True)
549
550 # Switch to the latest Mattermost version
551 switch_to_specialisation(environmentFile, environmentFileToplevel, "latest")
552 wait_mattermost_up(environmentFile)
553
554 # AboutLink should be changed still, and the post should still exist
555 expect_config(environmentFile, latest, '.AboutLink == "https://nixos.org"')
556 ensure_post(environmentFile, fail_if_not_found=True)
557
558 shutdown_queue.put(environmentFile)
559
560 # Run shutdowns asynchronously so we can pipeline them.
561 shutdown_queue: queue.Queue = queue.Queue()
562 def shutdown_worker():
563 while True:
564 node = shutdown_queue.get()
565 print(f"Shutting down node {node.name!r} asynchronously", file=sys.stderr)
566 node.shutdown()
567 shutdown_queue.task_done()
568 threading.Thread(target=shutdown_worker, daemon=True).start()
569
570 ${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isx86_64 ''
571 # Only run the MySQL tests on x86_64 so we don't have to debug MySQL ARM issues.
572 run_mattermost_tests(
573 shutdown_queue,
574 "${nodes.mysqlMutable.system.build.toplevel}",
575 mysqlMutable,
576 "${nodes.mysqlMostlyMutable.system.build.toplevel}",
577 "${nodes.mysqlMostlyMutable.services.mattermost.pluginsBundle}",
578 mysqlMostlyMutable,
579 "${nodes.mysqlImmutable.system.build.toplevel}",
580 mysqlImmutable,
581 "${nodes.mysqlEnvironmentFile.system.build.toplevel}",
582 mysqlEnvironmentFile
583 )
584 ''}
585
586 run_mattermost_tests(
587 shutdown_queue,
588 "${nodes.postgresMutable.system.build.toplevel}",
589 postgresMutable,
590 "${nodes.postgresMostlyMutable.system.build.toplevel}",
591 "${nodes.postgresMostlyMutable.services.mattermost.pluginsBundle}",
592 postgresMostlyMutable,
593 "${nodes.postgresImmutable.system.build.toplevel}",
594 postgresImmutable,
595 "${nodes.postgresEnvironmentFile.system.build.toplevel}",
596 postgresEnvironmentFile
597 )
598
599 # Drain the queue
600 shutdown_queue.join()
601 '';
602 }
603)