cloudflare/cloudflared
Publicmirrored from https://github.com/cloudflare/cloudflaredAvailable
component-tests/test_reconnect.py
54lines · modecode
| 1 | #!/usr/bin/env python |
| 2 | import copy |
| 3 | from time import sleep |
| 4 | |
| 5 | from flaky import flaky |
| 6 | |
| 7 | from util import start_cloudflared, wait_tunnel_ready, check_tunnel_not_connected |
| 8 | |
| 9 | |
| 10 | @flaky(max_runs=3, min_passes=1) |
| 11 | class TestReconnect(): |
| 12 | default_ha_conns = 4 |
| 13 | default_reconnect_secs = 5 |
| 14 | extra_config = { |
| 15 | "stdin-control": True, |
| 16 | } |
| 17 | |
| 18 | def test_named_reconnect(self, tmp_path, component_tests_config): |
| 19 | config = component_tests_config(self.extra_config) |
| 20 | with start_cloudflared(tmp_path, config, new_process=True, allow_input=True, capture_output=False) as cloudflared: |
| 21 | # Repeat the test multiple times because some issues only occur after multiple reconnects |
| 22 | self.assert_reconnect(config, cloudflared, 5) |
| 23 | |
| 24 | def test_classic_reconnect(self, tmp_path, component_tests_config): |
| 25 | extra_config = copy.copy(self.extra_config) |
| 26 | extra_config["hello-world"] = True |
| 27 | config = component_tests_config( |
| 28 | additional_config=extra_config, named_tunnel=False) |
| 29 | with start_cloudflared(tmp_path, config, cfd_args=[], new_process=True, allow_input=True, capture_output=False) as cloudflared: |
| 30 | self.assert_reconnect(config, cloudflared, 1) |
| 31 | |
| 32 | def send_reconnect(self, cloudflared, secs): |
| 33 | # Although it is recommended to use the Popen.communicate method, we cannot |
| 34 | # use it because it blocks on reading stdout and stderr until EOF is reached |
| 35 | cloudflared.stdin.write(f"reconnect {secs}s\n".encode()) |
| 36 | cloudflared.stdin.flush() |
| 37 | |
| 38 | def assert_reconnect(self, config, cloudflared, repeat): |
| 39 | wait_tunnel_ready(tunnel_url=config.get_url()) |
| 40 | for _ in range(repeat): |
| 41 | for i in range(self.default_ha_conns): |
| 42 | self.send_reconnect(cloudflared, self.default_reconnect_secs) |
| 43 | expect_connections = self.default_ha_conns-i-1 |
| 44 | if expect_connections > 0: |
| 45 | # Don't check if tunnel returns 200 here because there is a race condition between wait_tunnel_ready |
| 46 | # retrying to get 200 response and reconnecting |
| 47 | wait_tunnel_ready( |
| 48 | require_min_connections=expect_connections) |
| 49 | else: |
| 50 | check_tunnel_not_connected() |
| 51 | |
| 52 | sleep(self.default_reconnect_secs + 10) |
| 53 | wait_tunnel_ready(tunnel_url=config.get_url(), |
| 54 | require_min_connections=self.default_ha_conns) |
| 55 | |