at 25.11-pre 9.9 kB view raw
1import ../make-test-python.nix ( 2 { pkgs, ... }: 3 let 4 homeserverDomain = "server"; 5 homeserverUrl = "http://server:8008"; 6 username = "alice"; 7 instagramBotUsername = "instagrambot"; 8 facebookBotUsername = "facebookbot"; 9 in 10 { 11 name = "mautrix-meta-sqlite"; 12 meta.maintainers = pkgs.mautrix-meta.meta.maintainers; 13 14 nodes = { 15 server = 16 { config, pkgs, ... }: 17 { 18 services.matrix-synapse = { 19 enable = true; 20 settings = { 21 database.name = "sqlite3"; 22 23 enable_registration = true; 24 25 # don't use this in production, always use some form of verification 26 enable_registration_without_verification = true; 27 28 listeners = [ 29 { 30 # The default but tls=false 31 bind_addresses = [ 32 "0.0.0.0" 33 ]; 34 port = 8008; 35 resources = [ 36 { 37 "compress" = true; 38 "names" = [ "client" ]; 39 } 40 { 41 "compress" = false; 42 "names" = [ "federation" ]; 43 } 44 ]; 45 tls = false; 46 type = "http"; 47 } 48 ]; 49 }; 50 }; 51 52 services.mautrix-meta.instances.facebook = { 53 enable = true; 54 55 settings = { 56 homeserver = { 57 address = homeserverUrl; 58 domain = homeserverDomain; 59 }; 60 61 appservice = { 62 port = 8009; 63 64 bot.username = facebookBotUsername; 65 }; 66 67 bridge.permissions."@${username}:server" = "user"; 68 }; 69 }; 70 71 services.mautrix-meta.instances.instagram = { 72 enable = true; 73 74 settings = { 75 homeserver = { 76 address = homeserverUrl; 77 domain = homeserverDomain; 78 }; 79 80 appservice = { 81 port = 8010; 82 83 bot.username = instagramBotUsername; 84 }; 85 86 bridge.permissions."@${username}:server" = "user"; 87 }; 88 }; 89 90 networking.firewall.allowedTCPPorts = [ 8008 ]; 91 }; 92 93 client = 94 { pkgs, ... }: 95 { 96 environment.systemPackages = [ 97 (pkgs.writers.writePython3Bin "register_user" 98 { 99 libraries = [ pkgs.python3Packages.matrix-nio ]; 100 flakeIgnore = [ 101 # We don't live in the dark ages anymore. 102 # Languages like Python that are whitespace heavy will overrun 103 # 79 characters.. 104 "E501" 105 ]; 106 } 107 '' 108 import sys 109 import asyncio 110 111 from nio import AsyncClient 112 113 114 async def run(username: str, homeserver: str): 115 matrix = AsyncClient(homeserver) 116 117 response = await matrix.register(username, "foobar") 118 print("Matrix register response: ", response) 119 120 121 if __name__ == "__main__": 122 asyncio.run(run(sys.argv[1], sys.argv[2])) 123 '' 124 ) 125 (pkgs.writers.writePython3Bin "do_test" 126 { 127 libraries = [ pkgs.python3Packages.matrix-nio ]; 128 flakeIgnore = [ 129 # We don't live in the dark ages anymore. 130 # Languages like Python that are whitespace heavy will overrun 131 # 79 characters.. 132 "E501" 133 ]; 134 } 135 '' 136 import sys 137 import functools 138 import asyncio 139 140 from nio import AsyncClient, RoomMessageNotice, RoomCreateResponse, RoomInviteResponse 141 142 143 async def message_callback(matrix: AsyncClient, msg: str, _r, e): 144 print("Received matrix text message: ", e) 145 assert msg in e.body 146 exit(0) # Success! 147 148 149 async def run(username: str, bot_username: str, homeserver: str): 150 matrix = AsyncClient(homeserver, f"@{username}:${homeserverDomain}") 151 152 response = await matrix.login("foobar") 153 print("Matrix login response: ", response) 154 155 # Open a DM with the bridge bot 156 response = await matrix.room_create() 157 print("Matrix create room response:", response) 158 assert isinstance(response, RoomCreateResponse) 159 room_id = response.room_id 160 161 response = await matrix.room_invite(room_id, f"@{bot_username}:${homeserverDomain}") 162 assert isinstance(response, RoomInviteResponse) 163 164 callback = functools.partial( 165 message_callback, matrix, "Hello, I'm an Instagram bridge bot." 166 ) 167 matrix.add_event_callback(callback, RoomMessageNotice) 168 169 print("Waiting for matrix message...") 170 await matrix.sync_forever(timeout=30000) 171 172 173 if __name__ == "__main__": 174 asyncio.run(run(sys.argv[1], sys.argv[2], sys.argv[3])) 175 '' 176 ) 177 ]; 178 }; 179 }; 180 181 testScript = '' 182 def extract_token(data): 183 stdout = data[1] 184 stdout = stdout.strip() 185 line = stdout.split('\n')[-1] 186 return line.split(':')[-1].strip("\" '\n") 187 188 def get_token_from(token, file): 189 data = server.execute(f"cat {file} | grep {token}") 190 return extract_token(data) 191 192 def get_as_token_from(file): 193 return get_token_from("as_token", file) 194 195 def get_hs_token_from(file): 196 return get_token_from("hs_token", file) 197 198 config_yaml = "/var/lib/mautrix-meta-facebook/config.yaml" 199 registration_yaml = "/var/lib/mautrix-meta-facebook/meta-registration.yaml" 200 201 start_all() 202 203 with subtest("wait for bridges and homeserver"): 204 # bridge 205 server.wait_for_unit("mautrix-meta-facebook.service") 206 server.wait_for_unit("mautrix-meta-instagram.service") 207 208 # homeserver 209 server.wait_for_unit("matrix-synapse.service") 210 211 server.wait_for_open_port(8008) 212 # Bridges only open the port after they contact the homeserver 213 server.wait_for_open_port(8009) 214 server.wait_for_open_port(8010) 215 216 with subtest("register user"): 217 client.succeed("register_user ${username} ${homeserverUrl} >&2") 218 219 with subtest("ensure messages can be exchanged"): 220 client.succeed("do_test ${username} ${facebookBotUsername} ${homeserverUrl} >&2") 221 client.succeed("do_test ${username} ${instagramBotUsername} ${homeserverUrl} >&2") 222 223 with subtest("ensure as_token and hs_token stays same after restart"): 224 generated_as_token_facebook = get_as_token_from(config_yaml) 225 generated_hs_token_facebook = get_hs_token_from(config_yaml) 226 227 generated_as_token_facebook_registration = get_as_token_from(registration_yaml) 228 generated_hs_token_facebook_registration = get_hs_token_from(registration_yaml) 229 230 # Indirectly checks the as token is not set to something like empty string or "null" 231 assert len(generated_as_token_facebook) > 20, f"as_token ({generated_as_token_facebook}) is too short, something went wrong" 232 assert len(generated_hs_token_facebook) > 20, f"hs_token ({generated_hs_token_facebook}) is too short, something went wrong" 233 234 assert generated_as_token_facebook == generated_as_token_facebook_registration, f"as_token should be the same in registration ({generated_as_token_facebook_registration}) and configuration ({generated_as_token_facebook}) files" 235 assert generated_hs_token_facebook == generated_hs_token_facebook_registration, f"hs_token should be the same in registration ({generated_hs_token_facebook_registration}) and configuration ({generated_hs_token_facebook}) files" 236 237 server.systemctl("restart mautrix-meta-facebook") 238 server.systemctl("restart mautrix-meta-instagram") 239 240 server.wait_for_open_port(8009) 241 server.wait_for_open_port(8010) 242 243 new_as_token_facebook = get_as_token_from(config_yaml) 244 new_hs_token_facebook = get_hs_token_from(config_yaml) 245 246 assert generated_as_token_facebook == new_as_token_facebook, f"as_token should stay the same after restart inside the configuration file (is: {new_as_token_facebook}, was: {generated_as_token_facebook})" 247 assert generated_hs_token_facebook == new_hs_token_facebook, f"hs_token should stay the same after restart inside the configuration file (is: {new_hs_token_facebook}, was: {generated_hs_token_facebook})" 248 249 new_as_token_facebook = get_as_token_from(registration_yaml) 250 new_hs_token_facebook = get_hs_token_from(registration_yaml) 251 252 assert generated_as_token_facebook == new_as_token_facebook, f"as_token should stay the same after restart inside the registration file (is: {new_as_token_facebook}, was: {generated_as_token_facebook})" 253 assert generated_hs_token_facebook == new_hs_token_facebook, f"hs_token should stay the same after restart inside the registration file (is: {new_hs_token_facebook}, was: {generated_hs_token_facebook})" 254 255 with subtest("ensure messages can be exchanged after restart"): 256 client.succeed("do_test ${username} ${instagramBotUsername} ${homeserverUrl} >&2") 257 client.succeed("do_test ${username} ${facebookBotUsername} ${homeserverUrl} >&2") 258 ''; 259 } 260)