python312Packages.millheater: 0.11.8 -> 0.12.0
[NixPkgs.git] / nixos / tests / matrix / mautrix-meta-postgres.nix
blobc9a45788afaf6483f95a068c12d638ed0303f826
1 import ../make-test-python.nix ({ pkgs, ... }:
2   let
3     homeserverDomain = "server";
4     homeserverUrl = "http://server:8008";
5     userName = "alice";
6     botUserName = "instagrambot";
8     asToken = "this-is-my-totally-randomly-generated-as-token";
9     hsToken = "this-is-my-totally-randomly-generated-hs-token";
10   in
11   {
12     name = "mautrix-meta-postgres";
13     meta.maintainers = pkgs.mautrix-meta.meta.maintainers;
15     nodes = {
16       server = { config, pkgs, ... }: {
17         services.postgresql = {
18           enable = true;
20           ensureUsers = [
21             {
22               name = "mautrix-meta-instagram";
23               ensureDBOwnership = true;
24             }
25           ];
27           ensureDatabases = [
28             "mautrix-meta-instagram"
29           ];
30         };
32         systemd.services.mautrix-meta-instagram = {
33           wants = [ "postgres.service" ];
34           after = [ "postgres.service" ];
35         };
37         services.matrix-synapse = {
38           enable = true;
39           settings = {
40             database.name = "sqlite3";
42             enable_registration = true;
44             # don't use this in production, always use some form of verification
45             enable_registration_without_verification = true;
47             listeners = [ {
48               # The default but tls=false
49               bind_addresses = [
50                 "0.0.0.0"
51               ];
52               port = 8008;
53               resources = [ {
54                 "compress" = true;
55                 "names" = [ "client" ];
56               } {
57                 "compress" = false;
58                 "names" = [ "federation" ];
59               } ];
60               tls = false;
61               type = "http";
62             } ];
63           };
64         };
66         services.mautrix-meta.instances.instagram = {
67           enable = true;
69           environmentFile = pkgs.writeText ''my-secrets'' ''
70             AS_TOKEN=${asToken}
71             HS_TOKEN=${hsToken}
72           '';
74           settings = {
75             homeserver = {
76               address = homeserverUrl;
77               domain = homeserverDomain;
78             };
80             appservice = {
81               port = 8009;
83               as_token = "$AS_TOKEN";
84               hs_token = "$HS_TOKEN";
86               database = {
87                 type = "postgres";
88                 uri = "postgres:///mautrix-meta-instagram?host=/var/run/postgresql";
89               };
91               bot.username = botUserName;
92             };
94             bridge.permissions."@${userName}:server" = "user";
95           };
96         };
98         networking.firewall.allowedTCPPorts = [ 8008 8009 ];
99       };
101       client = { pkgs, ... }: {
102         environment.systemPackages = [
103           (pkgs.writers.writePython3Bin "do_test"
104           {
105             libraries = [ pkgs.python3Packages.matrix-nio ];
106             flakeIgnore = [
107               # We don't live in the dark ages anymore.
108               # Languages like Python that are whitespace heavy will overrun
109               # 79 characters..
110               "E501"
111             ];
112           } ''
113               import sys
114               import functools
115               import asyncio
117               from nio import AsyncClient, RoomMessageNotice, RoomCreateResponse, RoomInviteResponse
120               async def message_callback(matrix: AsyncClient, msg: str, _r, e):
121                   print("Received matrix text message: ", e)
122                   assert msg in e.body
123                   exit(0)  # Success!
126               async def run(homeserver: str):
127                   matrix = AsyncClient(homeserver)
128                   response = await matrix.register("${userName}", "foobar")
129                   print("Matrix register response: ", response)
131                   # Open a DM with the bridge bot
132                   response = await matrix.room_create()
133                   print("Matrix create room response:", response)
134                   assert isinstance(response, RoomCreateResponse)
135                   room_id = response.room_id
137                   response = await matrix.room_invite(room_id, "@${botUserName}:${homeserverDomain}")
138                   assert isinstance(response, RoomInviteResponse)
140                   callback = functools.partial(
141                       message_callback, matrix, "Hello, I'm an Instagram bridge bot."
142                   )
143                   matrix.add_event_callback(callback, RoomMessageNotice)
145                   print("Waiting for matrix message...")
146                   await matrix.sync_forever(timeout=30000)
149               if __name__ == "__main__":
150                   asyncio.run(run(sys.argv[1]))
151             ''
152           )
153         ];
154       };
155     };
157     testScript = ''
158       def extract_token(data):
159           stdout = data[1]
160           stdout = stdout.strip()
161           line = stdout.split('\n')[-1]
162           return line.split(':')[-1].strip("\" '\n")
164       def get_token_from(token, file):
165           data = server.execute(f"cat {file} | grep {token}")
166           return extract_token(data)
168       def get_as_token_from(file):
169           return get_token_from("as_token", file)
171       def get_hs_token_from(file):
172           return get_token_from("hs_token", file)
174       config_yaml = "/var/lib/mautrix-meta-instagram/config.yaml"
175       registration_yaml = "/var/lib/mautrix-meta-instagram/meta-registration.yaml"
177       expected_as_token = "${asToken}"
178       expected_hs_token = "${hsToken}"
180       start_all()
182       with subtest("start the server"):
183           # bridge
184           server.wait_for_unit("mautrix-meta-instagram.service")
186           # homeserver
187           server.wait_for_unit("matrix-synapse.service")
189           server.wait_for_open_port(8008)
190           # Bridge only opens the port after it contacts the homeserver
191           server.wait_for_open_port(8009)
193       with subtest("ensure messages can be exchanged"):
194           client.succeed("do_test ${homeserverUrl} >&2")
196       with subtest("ensure as_token, hs_token match from environment file"):
197           as_token = get_as_token_from(config_yaml)
198           hs_token = get_hs_token_from(config_yaml)
199           as_token_registration = get_as_token_from(registration_yaml)
200           hs_token_registration = get_hs_token_from(registration_yaml)
202           assert as_token == expected_as_token, f"as_token in config should match the one specified (is: {as_token}, expected: {expected_as_token})"
203           assert hs_token == expected_hs_token, f"hs_token in config should match the one specified (is: {hs_token}, expected: {expected_hs_token})"
204           assert as_token_registration == expected_as_token, f"as_token in registration should match the one specified (is: {as_token_registration}, expected: {expected_as_token})"
205           assert hs_token_registration == expected_hs_token, f"hs_token in registration should match the one specified (is: {hs_token_registration}, expected: {expected_hs_token})"
207       with subtest("ensure as_token and hs_token stays same after restart"):
208           server.systemctl("restart mautrix-meta-instagram")
209           server.wait_for_open_port(8009)
211           as_token = get_as_token_from(config_yaml)
212           hs_token = get_hs_token_from(config_yaml)
213           as_token_registration = get_as_token_from(registration_yaml)
214           hs_token_registration = get_hs_token_from(registration_yaml)
216           assert as_token == expected_as_token, f"as_token in config should match the one specified (is: {as_token}, expected: {expected_as_token})"
217           assert hs_token == expected_hs_token, f"hs_token in config should match the one specified (is: {hs_token}, expected: {expected_hs_token})"
218           assert as_token_registration == expected_as_token, f"as_token in registration should match the one specified (is: {as_token_registration}, expected: {expected_as_token})"
219           assert hs_token_registration == expected_hs_token, f"hs_token in registration should match the one specified (is: {hs_token_registration}, expected: {expected_hs_token})"
220     '';
221   })