From fa813ababda04dbec78350475c4c14eec2e006c6 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Fri, 22 May 2026 00:25:27 +0200 Subject: [PATCH 1/3] rust-federation-tester: init at 0.5.2 --- .../ru/rust-federation-tester/package.nix | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 pkgs/by-name/ru/rust-federation-tester/package.nix diff --git a/pkgs/by-name/ru/rust-federation-tester/package.nix b/pkgs/by-name/ru/rust-federation-tester/package.nix new file mode 100644 index 000000000000..d56faf639fd9 --- /dev/null +++ b/pkgs/by-name/ru/rust-federation-tester/package.nix @@ -0,0 +1,66 @@ +{ + rustPlatform, + fetchFromGitHub, + lib, + nixosTests, + cacert, +}: + +rustPlatform.buildRustPackage (finalAttrs: { + pname = "rust-federation-tester"; + version = "0.5.2"; + + src = fetchFromGitHub { + owner = "MTRNord"; + repo = "rust-federation-tester"; + rev = "v${finalAttrs.version}"; + hash = "sha256-KHRG+5AeK7h7k7LoTtcIjGmPYlVcV2ZwpJN8iDsBfHg="; + }; + + __structuredAttrs = true; + strictDeps = true; + + cargoHash = "sha256-nTcE8eqQO0CFdeH0jjT6m1fd4qhG7e/CDpdZHkBq9f8="; + cargoTestFlags = finalAttrs.cargoBuildFlags; + cargoBuildFlags = [ + "-p" + "rust-federation-tester" + "-p" + "migration" + ]; + + nativeCheckInputs = [ cacert ]; + + checkFlags = map (test: "--skip=${test}") [ + # Tests depending on network access + "test_generate_json_report_ipv4_only_server" + "test_generate_json_report_known_bad_servers" + "test_generate_json_report_known_good_servers" + "test_generate_json_report_valid_domain" + "test_generate_json_report_with_port" + "test_lookup_server_well_known_valid" + "test_matrix_fed_srv_resolution_4msc4040" + "test_matrix_srv_resolution_4s" + "test_step2_explicit_port" + "test_step3b_wellknown_explicit_port" + "test_step3c_wellknown_matrix_fed_srv" + "test_step3c_wellknown_matrix_srv" + "test_step3d_wellknown_default_port" + "test_step6_wellknown_fails_default_port" + "test_generate_report" + "test_concurrent_requests" + ]; + + passthru.tests = { + inherit (nixosTests) matrix-synapse; + }; + + meta = { + description = "Matrix-Federation-Tester in Rust"; + homepage = "https://connectivity-tester.mtrnord.blog/"; + license = lib.licenses.agpl3Only; + maintainers = with lib.maintainers; [ ma27 ]; + platforms = lib.platforms.linux; + mainProgram = "rust-federation-tester"; + }; +}) From 988d274a1cb5179ae45001fe31110f1946a6686a Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Fri, 22 May 2026 00:25:40 +0200 Subject: [PATCH 2/3] nixos/rust-federation-tester: init --- nixos/modules/module-list.nix | 1 + .../matrix/rust-federation-tester.nix | 153 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 nixos/modules/services/matrix/rust-federation-tester.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 9c52ee7c52a6..185b063dd037 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -821,6 +821,7 @@ ./services/matrix/mautrix-whatsapp.nix ./services/matrix/mjolnir.nix ./services/matrix/pantalaimon.nix + ./services/matrix/rust-federation-tester.nix ./services/matrix/synapse-auto-compressor.nix ./services/matrix/synapse.nix ./services/matrix/tuwunel.nix diff --git a/nixos/modules/services/matrix/rust-federation-tester.nix b/nixos/modules/services/matrix/rust-federation-tester.nix new file mode 100644 index 000000000000..4b7a3420d2e0 --- /dev/null +++ b/nixos/modules/services/matrix/rust-federation-tester.nix @@ -0,0 +1,153 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: + +let + cfg = config.services.rust-federation-tester; + + configFile = "/run/rust-federation-tester/config.yaml"; + commonServiceConfig = { + DynamicUser = true; + RuntimeDirectory = "rust-federation-tester"; + RuntimeDirectoryPreserve = true; + StateDirectory = "rust-federation-tester"; + User = "rust-federation-tester"; + WorkingDirectory = "%t/rust-federation-tester"; + + # Hardening + UMask = "0077"; + CapabilityBoundingSet = [ "" ]; + DevicePolicy = "closed"; + PrivateTmp = true; + ProtectHome = true; + ProtectSystem = "strict"; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + LockPersonality = true; + PrivateDevices = true; + PrivateMounts = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RemoveIPC = true; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + ]; + }; + + secretsInjection = utils.genJqSecretsReplacement { + loadCredential = true; + } cfg.settings configFile; +in +{ + options.services.rust-federation-tester = { + enable = lib.mkEnableOption "rust-federation-tester"; + + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = lib.types.json; + options = { + frontend_url = lib.mkOption { + type = lib.types.str; + example = "federation-tester.example.org"; + description = '' + URL of the service's frontend. + ''; + }; + + database_url = lib.mkOption { + type = lib.types.str; + default = "sqlite:///var/lib/rust-federation-tester/db?mode=rwc"; + example = "postgres://localhost/db?currentSchema=schema"; + description = '' + The database to store accounts and statistics. + ''; + }; + + smtp = { + enabled = lib.mkEnableOption "mail delivery for configured alerts"; + }; + + listen_addr = lib.mkOption { + type = lib.types.str; + default = "[::]:8080"; + example = "unix:/run/rust-federation-tester/rust-federation-tester.sock"; + description = '' + Address the API server should listen on. + ''; + }; + }; + }; + + description = '' + Settings representing the values in {file}`config.yaml` of the service. + + Refer to [`config.yaml.example`] for supported values. + + [`config.yaml.example`]: https://github.com/MTRNord/rust-federation-tester/blob/main/config.yaml.example + ''; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.sockets.rust-federation-tester = { + description = "Matrix-Federation-Tester in Rust socket"; + wantedBy = [ "sockets.target" ]; + listenStreams = [ (lib.removePrefix "unix:" cfg.settings.listen_addr) ]; + }; + + systemd.services.rust-federation-tester-setup = { + description = "Matrix-Federation-Tester in Rust"; + path = [ pkgs.rust-federation-tester ]; + + serviceConfig = lib.mkMerge [ + commonServiceConfig + { + Type = "oneshot"; + RemainAfterExit = true; + LoadCredential = secretsInjection.credentials; + ExecStart = "${pkgs.writeShellScript "rust-federation-tester-setup" '' + ${secretsInjection.script} + + migration up + ''}"; + } + ]; + }; + + systemd.services.rust-federation-tester = { + description = "Matrix-Federation-Tester in Rust"; + wantedBy = [ "multi-user.target" ]; + documentation = [ "https://github.com/MTRNord/rust-federation-tester" ]; + after = [ "rust-federation-tester-setup.service" ]; + requires = [ "rust-federation-tester-setup.service" ]; + + serviceConfig = lib.mkMerge [ + commonServiceConfig + { + ExecSearchPath = lib.makeBinPath [ pkgs.rust-federation-tester ]; + ExecStart = "rust-federation-tester"; + Restart = "on-failure"; + } + ]; + }; + }; +} From 923421ea3f8fd20b50b9df1295ce129511c87e23 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 22 Apr 2025 15:03:58 +0200 Subject: [PATCH 3/3] nixos/synapse: implement more advanced integration test This is an attempt to make better assertions on federation and basic functionality: so far we had a test that was essentially a regression-test for email-based authentication. This change adds the following things: * uses matrix-federation-tester to verify that federation is set up properly. * uses matrix-commander (a CLI client) to test basic operations (sending/receiving messages, invites). * merge basic synapse test & worker test: one of the federating servers uses postgresql and a single federation worker, the other one no workers and sqlite. Co-authored-by: Emily --- nixos/tests/all-tests.nix | 1 - nixos/tests/matrix/synapse-workers.nix | 53 -- nixos/tests/matrix/synapse.nix | 464 +++++++++++++----- .../ma/matrix-synapse-unwrapped/package.nix | 2 +- 4 files changed, 329 insertions(+), 191 deletions(-) delete mode 100644 nixos/tests/matrix/synapse-workers.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 5e7a1a12a29c..f09c4b473b53 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1005,7 +1005,6 @@ in matrix-conduit = runTest ./matrix/conduit.nix; matrix-continuwuity = runTest ./matrix/continuwuity.nix; matrix-synapse = runTest ./matrix/synapse.nix; - matrix-synapse-workers = runTest ./matrix/synapse-workers.nix; matrix-tuwunel = runTest ./matrix/tuwunel.nix; matter-server = runTest ./matter-server.nix; matterjs-server = runTest ./matterjs-server.nix; diff --git a/nixos/tests/matrix/synapse-workers.nix b/nixos/tests/matrix/synapse-workers.nix deleted file mode 100644 index 949658caac47..000000000000 --- a/nixos/tests/matrix/synapse-workers.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ pkgs, ... }: -{ - name = "matrix-synapse-workers"; - meta = { - inherit (pkgs.matrix-synapse.meta) maintainers; - }; - - nodes = { - homeserver = - { - pkgs, - nodes, - ... - }: - { - services.postgresql = { - enable = true; - initialScript = pkgs.writeText "synapse-init.sql" '' - CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; - CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" - TEMPLATE template0 - LC_COLLATE = "C" - LC_CTYPE = "C"; - ''; - }; - - services.matrix-synapse = { - enable = true; - settings = { - database = { - name = "psycopg2"; - args.password = "synapse"; - }; - enable_registration = true; - enable_registration_without_verification = true; - - federation_sender_instances = [ "federation_sender" ]; - }; - configureRedisLocally = true; - workers = { - "federation_sender" = { }; - }; - }; - }; - }; - - testScript = '' - start_all() - - homeserver.wait_for_unit("matrix-synapse.service"); - homeserver.wait_for_unit("matrix-synapse-worker-federation_sender.service"); - ''; -} diff --git a/nixos/tests/matrix/synapse.nix b/nixos/tests/matrix/synapse.nix index 7827705ffe21..961c0506ed9d 100644 --- a/nixos/tests/matrix/synapse.nix +++ b/nixos/tests/matrix/synapse.nix @@ -1,101 +1,194 @@ { pkgs, ... }: let - ca_key = mailerCerts.ca.key; ca_pem = mailerCerts.ca.cert; - bundle = - pkgs.runCommand "bundle" + aliceName = "alice"; + alicePassword = "alicealice"; + aliceEmail = "alice@example.com"; + + bobName = "bob"; + bobPassword = "hunter2"; + + mkBundle = + domain: + pkgs.runCommand "bundle-${domain}" { nativeBuildInputs = [ pkgs.minica ]; } '' minica -ca-cert ${ca_pem} -ca-key ${ca_key} \ - -domains localhost - install -Dm444 -t $out localhost/{key,cert}.pem + -domains ${domain} + install -Dm444 -t $out ${domain}/{key,cert}.pem ''; mailerCerts = import ../common/acme/server/snakeoil-certs.nix; mailerDomain = mailerCerts.domain; registrationSharedSecret = "unsecure123"; - testUser = "alice"; - testPassword = "alicealice"; - testEmail = "alice@example.com"; - listeners = [ + anonHash = "hunter2hunter2hunter2"; + anonHashF = pkgs.writeText "hash" anonHash; + + mkHomeserverBase = + domain: nodes: + let + bundle = mkBundle domain; + in + { lib, ... }: { - port = 8448; - bind_addresses = [ - "127.0.0.1" - "::1" + security.pki.certificateFiles = [ + mailerCerts.ca.cert ]; - type = "http"; - tls = true; - x_forwarded = false; - resources = [ - { - names = [ - "client" - ]; - compress = true; - } - { - names = [ - "federation" - ]; - compress = false; - } - ]; - } - ]; + networking = { + hostName = lib.head (lib.strings.splitString "." domain); + domain = lib.last (lib.strings.splitString "." domain); + firewall.allowedTCPPorts = [ + 80 + 443 + 8448 + ]; + }; + + services.nginx = { + enable = true; + virtualHosts."${domain}" = { + sslCertificate = "${bundle}/cert.pem"; + sslCertificateKey = "${bundle}/key.pem"; + addSSL = true; + locations."/.well-known/matrix/server".extraConfig = '' + default_type application/json; + return 200 '${ + builtins.toJSON { + "m.server" = "${domain}:8448"; + } + }'; + ''; + }; + }; + }; + + mkSynapseConfig = + domain: primaryIP: + let + bundle = mkBundle domain; + in + { + enable = true; + settings = { + # We're in a test environment with local machines, so + # we actually _want_ to use RFC1918 addresses. + ip_range_blacklist = [ ]; + + trusted_key_servers = [ + { server_name = "hs1.test"; } + { server_name = "hs2.test"; } + ]; + + registration_shared_secret = registrationSharedSecret; + public_baseurl = "https://${domain}"; + tls_certificate_path = "${bundle}/cert.pem"; + tls_private_key_path = "${bundle}/key.pem"; + listeners = [ + # Using a local listener, otherwise matrix-synapse-register_new_matrix_user will + # fail because it'll try to connect to the first bind address, but via TLS resulting + # in a signature verification failure. + { + port = 8008; + type = "http"; + tls = false; + resources = [ + { + names = [ "client" ]; + compress = true; + } + ]; + bind_addresses = [ "::1" ]; + } + { + port = 8448; + bind_addresses = [ + primaryIP + ]; + type = "http"; + tls = true; + x_forwarded = false; + resources = [ + { + names = [ + "client" + ]; + compress = true; + } + { + names = [ + "federation" + ]; + compress = false; + } + ]; + } + ]; + }; + }; in { - name = "matrix-synapse"; meta = { inherit (pkgs.matrix-synapse.meta) maintainers; }; nodes = { - # Since 0.33.0, matrix-synapse doesn't allow underscores in server names - serverpostgres = + synapse-with-workers = { + lib, + config, pkgs, nodes, - config, ... }: - let - mailserverIP = nodes.mailserver.networking.primaryIPAddress; - in { - services.matrix-synapse = { - enable = true; - settings = { - inherit listeners; - database = { - name = "psycopg2"; - args.password = "synapse"; + imports = [ + (mkHomeserverBase "hs1.test" nodes) + ]; + + services.matrix-synapse = lib.mkMerge [ + (mkSynapseConfig "hs1.test" config.networking.primaryIPAddress) + { + settings = { + server_name = "hs1.test"; + email = { + smtp_host = mailerDomain; + smtp_port = 25; + require_transport_security = true; + notif_from = "matrix "; + app_name = "Matrix"; + }; + listeners = [ + { + path = "/run/matrix-synapse/main_replication.sock"; + type = "http"; + resources = [ + { + names = [ "replication" ]; + compress = false; + } + ]; + } + ]; + database = { + name = "psycopg2"; + args.password = "synapse"; + }; + federation_sender_instances = [ "federation_sender" ]; }; - redis = { - enabled = true; - host = "localhost"; - port = config.services.redis.servers.matrix-synapse.port; + configureRedisLocally = true; + workers = { + "federation_sender" = { }; }; - tls_certificate_path = "${bundle}/cert.pem"; - tls_private_key_path = "${bundle}/key.pem"; - registration_shared_secret = registrationSharedSecret; - public_baseurl = "https://example.com"; - email = { - smtp_host = mailerDomain; - smtp_port = 25; - require_transport_security = true; - notif_from = "matrix "; - app_name = "Matrix"; - }; - }; - }; + } + ]; + services.postgresql = { enable = true; @@ -113,20 +206,6 @@ in ''; }; - services.redis.servers.matrix-synapse = { - enable = true; - port = 6380; - }; - - networking.extraHosts = '' - ${mailserverIP} ${mailerDomain} - ''; - - security.pki.certificateFiles = [ - mailerCerts.ca.cert - ca_pem - ]; - environment.systemPackages = let sendTestMailStarttls = pkgs.writeScriptBin "send-testmail-starttls" '' @@ -140,7 +219,7 @@ in smtp.ehlo() smtp.starttls(context=ctx) smtp.ehlo() - smtp.sendmail('matrix@${mailerDomain}', '${testEmail}', 'Subject: Test STARTTLS\n\nTest data.') + smtp.sendmail('matrix@${mailerDomain}', '${aliceEmail}', 'Subject: Test STARTTLS\n\nTest data.') smtp.quit() ''; @@ -149,16 +228,14 @@ in # adding the email through the API is quite complicated as it involves more than one step and some # client-side calculation insertEmailForAlice = pkgs.writeText "alice-email.sql" '' - INSERT INTO user_threepids (user_id, medium, address, validated_at, added_at) VALUES ('${testUser}@serverpostgres', 'email', '${testEmail}', '1629149927271', '1629149927270'); + INSERT INTO user_threepids (user_id, medium, address, validated_at, added_at) VALUES ('${aliceName}@serverpostgres', 'email', '${aliceEmail}', '1629149927271', '1629149927270'); ''; in pkgs.writeScriptBin "obtain-token-and-register-email" '' #!${pkgs.runtimeShell} - set -o errexit - set -o pipefail - set -o nounset + set -euxo pipefail su postgres -c "psql -d matrix-synapse -f ${insertEmailForAlice}" - curl --fail -XPOST 'https://localhost:8448/_matrix/client/r0/account/password/email/requestToken' -d '{"email":"${testEmail}","client_secret":"foobar","send_attempt":1}' -v + curl --fail -XPOST 'https://hs1.test:8448/_matrix/client/r0/account/password/email/requestToken' -d '{"email":"${aliceEmail}","client_secret":"foobar","send_attempt":1}' -v ''; in [ @@ -168,74 +245,189 @@ in ]; }; - # test mail delivery - mailserver = args: { - security.pki.certificateFiles = [ - mailerCerts.ca.cert - ]; + mailserver = + { lib, ... }: + { + security.pki.certificateFiles = [ + mailerCerts.ca.cert + ]; - networking.firewall.enable = false; + networking = { + hostName = lib.head (lib.strings.splitString "." mailerDomain); + domain = lib.last (lib.strings.splitString "." mailerDomain); + firewall.enable = false; + }; - services.postfix = { - enable = true; - enableSubmission = true; + services.postfix = { + enable = true; + enableSubmission = true; - # blackhole transport - transport = "example.com discard:silently"; + # blackhole transport + transport = "example.com discard:silently"; - settings.main = { - myhostname = "${mailerDomain}"; - # open relay for subnet - mynetworks_style = "subnet"; - debug_peer_level = "10"; - smtpd_relay_restrictions = [ - "permit_mynetworks" - "reject_unauth_destination" - ]; + settings.main = { + myhostname = "${mailerDomain}"; + # open relay for subnet + mynetworks_style = "subnet"; + debug_peer_level = "10"; + smtpd_relay_restrictions = [ + "permit_mynetworks" + "reject_unauth_destination" + ]; - # disable obsolete protocols, something old versions of twisted are still using - smtpd_tls_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3"; - smtpd_tls_mandatory_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3"; - smtpd_tls_chain_files = [ - "${mailerCerts.${mailerDomain}.key}" - "${mailerCerts.${mailerDomain}.cert}" - ]; + # disable obsolete protocols, something old versions of twisted are still using + smtpd_tls_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3"; + smtpd_tls_mandatory_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3"; + smtpd_tls_chain_files = [ + "${mailerCerts.${mailerDomain}.key}" + "${mailerCerts.${mailerDomain}.cert}" + ]; + }; }; }; - }; - serversqlite = args: { - services.matrix-synapse = { - enable = true; - settings = { - inherit listeners; - database.name = "sqlite3"; - tls_certificate_path = "${bundle}/cert.pem"; - tls_private_key_path = "${bundle}/key.pem"; + synapse-minimal = + { + nodes, + config, + lib, + ... + }: + { + imports = [ + (mkHomeserverBase "hs2.test" nodes) + ]; + + services.matrix-synapse = lib.mkMerge [ + (mkSynapseConfig "hs2.test" config.networking.primaryIPAddress) + { + settings = { + database.name = "sqlite3"; + server_name = "hs2.test"; + }; + } + ]; + }; + + client = + { pkgs, ... }: + { + environment.systemPackages = [ + # `pkgs.olm` is cached on c.n.o, even if this test isn't built due + # to it being allow-listed in `pkgs/top-level/release.nix`. + (import pkgs.path { + config = pkgs.config // { + permittedInsecurePackages = [ "olm-3.2.16" ]; + }; + }).matrix-commander + pkgs.jq + ]; + + security.pki.certificateFiles = [ mailerCerts.ca.cert ]; + + users.users = { + alice.isNormalUser = true; + bob.isNormalUser = true; + }; + + networking.useNetworkd = true; + services.rust-federation-tester = { + enable = true; + settings = { + listen_addr = "unix:/run/rust-federation-tester/rust-federation-tester.sock"; + frontend_url = "http://localhost:8080"; + database_url = "sqlite:///var/lib/rust-federation-tester/db?mode=rwc"; + magic_token_secret = "foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar"; + statistics = { + enabled = true; + prometheus_enabled = true; + anonymization_salt._secret = "${anonHashF}"; + raw_retention_days = 30; + }; + }; }; }; - }; }; testScript = '' + import json + from pprint import pprint + start_all() - mailserver.wait_for_unit("postfix.service") - serverpostgres.succeed("send-testmail-starttls") - serverpostgres.wait_for_unit("matrix-synapse.service") - serverpostgres.wait_until_succeeds( - "curl --fail -L --cacert ${ca_pem} https://localhost:8448/" - ) - serverpostgres.wait_until_succeeds( + + synapse_with_workers.wait_for_unit("multi-user.target") + synapse_minimal.wait_for_unit("multi-user.target") + mailserver.wait_for_unit("multi-user.target") + + synapse_with_workers.wait_until_succeeds( "journalctl -u matrix-synapse.service | grep -q 'Connected to redis'" ) - serverpostgres.require_unit_state("postgresql.target") - serverpostgres.succeed("REQUESTS_CA_BUNDLE=${ca_pem} register_new_matrix_user -u ${testUser} -p ${testPassword} -a -k ${registrationSharedSecret} https://localhost:8448/") - serverpostgres.succeed("obtain-token-and-register-email") - serversqlite.wait_for_unit("matrix-synapse.service") - serversqlite.wait_until_succeeds( - "curl --fail -L --cacert ${ca_pem} https://localhost:8448/" - ) - serversqlite.succeed("[ -e /var/lib/matrix-synapse/homeserver.db ]") - ''; + synapse_with_workers.wait_for_unit("matrix-synapse-worker-federation_sender.service"); + with subtest("register user with email confirmation"): + synapse_with_workers.succeed("send-testmail-starttls") + synapse_with_workers.succeed("REQUESTS_CA_BUNDLE=${mailerCerts.ca.cert} register_new_matrix_user -u ${aliceName} -p ${alicePassword} -a -k ${registrationSharedSecret} https://hs1.test:8448/") + synapse_with_workers.succeed("obtain-token-and-register-email") + + with subtest("matrix-synapse-register_new_matrix_user"): + synapse_minimal.succeed("matrix-synapse-register_new_matrix_user -u ${bobName} -p ${bobPassword} --no-admin") + synapse_minimal.succeed("[ -e /var/lib/matrix-synapse/homeserver.db ]") + + with subtest("Federation tester"): + expected_anonymization_hashes = { + "hs1.test": "0558582846d6e2d90612900d449871dfcbf9878ba78de4a8469d8aba2d9c037b", + "hs2.test": "d3d88c2033c03b74ec1e086e15c0251514de060de5e51cb381e896f892a5b0cd", + } + + # /metrics are cached for up to 30 seconds + for n, domain in enumerate(["hs2.test", "hs1.test"], start=3): + result = json.loads( + client.succeed( + f"curl --fail --unix-socket /run/rust-federation-tester/rust-federation-tester.sock 'http://localhost:8080/api/federation/report?server_name={domain}&stats_opt_in=true'" + ) + ) + pprint(result) + t.assertTrue(result["FederationOK"]) + t.assertTrue(result["ConnectionReports"][f"192.168.1.{n}:8448"]["Checks"]["AllChecksOK"]) + t.assertEqual(f"{domain}:8448", result["WellKnownResult"][f"192.168.1.{n}:443"]["m.server"]) + + client.sleep(30) + # /metrics are cached for up to 30 seconds + for domain in ["hs2.test", "hs1.test"]: + metrics = client.succeed("curl --unix-socket /run/rust-federation-tester/rust-federation-tester.sock http://localhost:8080/metrics --fail") + t.assertRegex( + metrics, + f'federation_request_total\\{{server=\\"{expected_anonymization_hashes[domain]}\\",result=\\"success\\",[^}}]+\\}} 1' + ) + + def run_as_alice(cmd): + return client.succeed(f"sudo -u alice matrix-commander -c /home/alice/credentials.json -s /home/alice/matrix {cmd}") + + def run_as_bob(cmd): + return client.succeed(f"sudo -u bob matrix-commander -c /home/bob/credentials.json -s /home/bob/matrix {cmd}") + + with subtest("Login"): + run_as_alice("--login password --homeserver https://hs1.test:8448 --user-login @${aliceName}:hs1.test --password ${alicePassword} --device commander --room-default '#welcome:hs1.test'") + run_as_bob("--login password --homeserver https://hs2.test:8448 --user-login @${bobName}:hs2.test --password ${bobPassword} --device commander --room-default '#welcome:hs1.test'") + + with subtest("Create/Invite/Join"): + run_as_alice("--room-create '#welcome:hs1.test'") + + run_as_alice("--room-invite '#welcome:hs1.test' -u @${bobName}:hs2.test") + run_as_bob("--listen once --room-invites 'list+join'") + + with subtest("Send/receive messages"): + senders = { + "alice": ("hs1", run_as_alice), + "bob": ("hs2", run_as_bob), + } + + for name, (hs, fn) in senders.items(): + fn(f"-m 'hello, I am {name}'") + for _, run in senders.values(): + msg_data = json.loads(run("--listen once --listen-self --output json")) + pprint(msg_data) + t.assertEqual(msg_data["source"]["content"]["body"], f"hello, I am {name}") + t.assertEqual(msg_data["source"]["sender"], f"@{name}:{hs}.test") + ''; } diff --git a/pkgs/by-name/ma/matrix-synapse-unwrapped/package.nix b/pkgs/by-name/ma/matrix-synapse-unwrapped/package.nix index c4cce0f2767e..58f90acb7b68 100644 --- a/pkgs/by-name/ma/matrix-synapse-unwrapped/package.nix +++ b/pkgs/by-name/ma/matrix-synapse-unwrapped/package.nix @@ -157,7 +157,7 @@ python3Packages.buildPythonApplication rec { ''; passthru = { - tests = { inherit (nixosTests) matrix-synapse matrix-synapse-workers; }; + tests = { inherit (nixosTests) matrix-synapse; }; plugins = python3Packages.callPackage ./plugins { }; inherit (python3Packages) python; updateScript = nix-update-script { };