test_management.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/env python
  2. import requests
  3. from conftest import CfdModes
  4. from constants import METRICS_PORT, MAX_RETRIES, BACKOFF_SECS
  5. from retrying import retry
  6. from cli import CloudflaredCli
  7. from util import LOGGER, write_config, start_cloudflared, wait_tunnel_ready, send_requests
  8. import platform
  9. """
  10. Each test in TestManagement will:
  11. 1. Acquire a management token from Cloudflare public API
  12. 2. Make a request against the management service for the running tunnel
  13. """
  14. class TestManagement:
  15. """
  16. test_get_host_details does the following:
  17. 1. It gets a management token from Tunnelstore using cloudflared tail token <tunnel_id>
  18. 2. It gets the connector_id after starting a cloudflare tunnel
  19. 3. It sends a request to the management host with the connector_id and management token
  20. 4. Asserts that the response has a hostname and ip.
  21. """
  22. def test_get_host_details(self, tmp_path, component_tests_config):
  23. # TUN-7377 : wait_tunnel_ready does not work properly in windows.
  24. # Skipping this test for windows for now and will address it as part of tun-7377
  25. if platform.system() == "Windows":
  26. return
  27. config = component_tests_config(cfd_mode=CfdModes.NAMED, run_proxy_dns=False, provide_ingress=False)
  28. LOGGER.debug(config)
  29. headers = {}
  30. headers["Content-Type"] = "application/json"
  31. config_path = write_config(tmp_path, config.full_config)
  32. with start_cloudflared(tmp_path, config, cfd_pre_args=["tunnel", "--ha-connections", "1", "--label" , "test"], cfd_args=["run", "--hello-world"], new_process=True):
  33. wait_tunnel_ready(tunnel_url=config.get_url(),
  34. require_min_connections=1)
  35. cfd_cli = CloudflaredCli(config, config_path, LOGGER)
  36. connector_id = cfd_cli.get_connector_id(config)[0]
  37. url = cfd_cli.get_management_url("host_details", config, config_path)
  38. resp = send_request(url, headers=headers)
  39. # Assert response json.
  40. assert resp.status_code == 200, "Expected cloudflared to return 200 for host details"
  41. assert resp.json()["hostname"] == "custom:test", "Expected cloudflared to return hostname"
  42. assert resp.json()["ip"] != "", "Expected cloudflared to return ip"
  43. assert resp.json()["connector_id"] == connector_id, "Expected cloudflared to return connector_id"
  44. """
  45. test_get_metrics will verify that the /metrics endpoint returns the prometheus metrics dump
  46. """
  47. def test_get_metrics(self, tmp_path, component_tests_config):
  48. # TUN-7377 : wait_tunnel_ready does not work properly in windows.
  49. # Skipping this test for windows for now and will address it as part of tun-7377
  50. if platform.system() == "Windows":
  51. return
  52. config = component_tests_config(cfd_mode=CfdModes.NAMED, run_proxy_dns=False, provide_ingress=False)
  53. LOGGER.debug(config)
  54. config_path = write_config(tmp_path, config.full_config)
  55. with start_cloudflared(tmp_path, config, cfd_pre_args=["tunnel", "--ha-connections", "1"], new_process=True):
  56. wait_tunnel_ready(require_min_connections=1)
  57. cfd_cli = CloudflaredCli(config, config_path, LOGGER)
  58. url = cfd_cli.get_management_url("metrics", config, config_path)
  59. resp = send_request(url)
  60. # Assert response.
  61. assert resp.status_code == 200, "Expected cloudflared to return 200 for /metrics"
  62. assert "# HELP build_info Build and version information" in resp.text, "Expected /metrics to have with the build_info details"
  63. """
  64. test_get_pprof_heap will verify that the /debug/pprof/heap endpoint returns a pprof/heap dump response
  65. """
  66. def test_get_pprof_heap(self, tmp_path, component_tests_config):
  67. # TUN-7377 : wait_tunnel_ready does not work properly in windows.
  68. # Skipping this test for windows for now and will address it as part of tun-7377
  69. if platform.system() == "Windows":
  70. return
  71. config = component_tests_config(cfd_mode=CfdModes.NAMED, run_proxy_dns=False, provide_ingress=False)
  72. LOGGER.debug(config)
  73. config_path = write_config(tmp_path, config.full_config)
  74. with start_cloudflared(tmp_path, config, cfd_pre_args=["tunnel", "--ha-connections", "1"], new_process=True):
  75. wait_tunnel_ready(require_min_connections=1)
  76. cfd_cli = CloudflaredCli(config, config_path, LOGGER)
  77. url = cfd_cli.get_management_url("debug/pprof/heap", config, config_path)
  78. resp = send_request(url)
  79. # Assert response.
  80. assert resp.status_code == 200, "Expected cloudflared to return 200 for /debug/pprof/heap"
  81. assert resp.headers["Content-Type"] == "application/octet-stream", "Expected /debug/pprof/heap to have return a binary response"
  82. """
  83. test_get_metrics_when_disabled will verify that diagnostic endpoints (such as /metrics) return 404 and are unmounted.
  84. """
  85. def test_get_metrics_when_disabled(self, tmp_path, component_tests_config):
  86. # TUN-7377 : wait_tunnel_ready does not work properly in windows.
  87. # Skipping this test for windows for now and will address it as part of tun-7377
  88. if platform.system() == "Windows":
  89. return
  90. config = component_tests_config(cfd_mode=CfdModes.NAMED, run_proxy_dns=False, provide_ingress=False)
  91. LOGGER.debug(config)
  92. config_path = write_config(tmp_path, config.full_config)
  93. with start_cloudflared(tmp_path, config, cfd_pre_args=["tunnel", "--ha-connections", "1", "--management-diagnostics=false"], new_process=True):
  94. wait_tunnel_ready(require_min_connections=1)
  95. cfd_cli = CloudflaredCli(config, config_path, LOGGER)
  96. url = cfd_cli.get_management_url("metrics", config, config_path)
  97. resp = send_request(url)
  98. # Assert response.
  99. assert resp.status_code == 404, "Expected cloudflared to return 404 for /metrics"
  100. @retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)
  101. def send_request(url, headers={}):
  102. with requests.Session() as s:
  103. return s.get(url, timeout=BACKOFF_SECS, headers=headers)