failover_test.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. # Copyright 2021 gRPC authors.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import logging
  15. from typing import List
  16. from absl import flags
  17. from absl.testing import absltest
  18. from framework import xds_k8s_testcase
  19. from framework.infrastructure import k8s
  20. from framework.test_app import server_app
  21. logger = logging.getLogger(__name__)
  22. flags.adopt_module_key_flags(xds_k8s_testcase)
  23. # Type aliases
  24. _XdsTestServer = xds_k8s_testcase.XdsTestServer
  25. _XdsTestClient = xds_k8s_testcase.XdsTestClient
  26. class FailoverTest(xds_k8s_testcase.RegularXdsKubernetesTestCase):
  27. REPLICA_COUNT = 3
  28. MAX_RATE_PER_ENDPOINT = 100
  29. def setUp(self):
  30. super().setUp()
  31. self.secondary_server_runner = server_app.KubernetesServerRunner(
  32. k8s.KubernetesNamespace(self.secondary_k8s_api_manager,
  33. self.server_namespace),
  34. deployment_name=self.server_name + '-alt',
  35. image_name=self.server_image,
  36. gcp_service_account=self.gcp_service_account,
  37. td_bootstrap_image=self.td_bootstrap_image,
  38. gcp_project=self.project,
  39. gcp_api_manager=self.gcp_api_manager,
  40. xds_server_uri=self.xds_server_uri,
  41. network=self.network,
  42. debug_use_port_forwarding=self.debug_use_port_forwarding,
  43. reuse_namespace=True)
  44. def tearDown(self):
  45. if hasattr(self, 'secondary_server_runner'):
  46. self.secondary_server_runner.cleanup()
  47. super().tearDown()
  48. def test_failover(self) -> None:
  49. with self.subTest('00_create_health_check'):
  50. self.td.create_health_check()
  51. with self.subTest('01_create_backend_services'):
  52. self.td.create_backend_service()
  53. with self.subTest('02_create_url_map'):
  54. self.td.create_url_map(self.server_xds_host, self.server_xds_port)
  55. with self.subTest('03_create_target_proxy'):
  56. self.td.create_target_proxy()
  57. with self.subTest('04_create_forwarding_rule'):
  58. self.td.create_forwarding_rule(self.server_xds_port)
  59. with self.subTest('05_start_test_servers'):
  60. self.default_test_servers: List[
  61. _XdsTestServer] = self.startTestServers(
  62. replica_count=self.REPLICA_COUNT)
  63. self.alternate_test_servers: List[
  64. _XdsTestServer] = self.startTestServers(
  65. server_runner=self.secondary_server_runner)
  66. with self.subTest('06_add_server_backends_to_backend_services'):
  67. self.setupServerBackends(
  68. max_rate_per_endpoint=self.MAX_RATE_PER_ENDPOINT)
  69. self.setupServerBackends(
  70. server_runner=self.secondary_server_runner,
  71. max_rate_per_endpoint=self.MAX_RATE_PER_ENDPOINT)
  72. with self.subTest('07_start_test_client'):
  73. self.test_client: _XdsTestClient = self.startTestClient(
  74. self.default_test_servers[0])
  75. with self.subTest('08_test_client_xds_config_exists'):
  76. self.assertXdsConfigExists(self.test_client)
  77. with self.subTest('09_primary_locality_receives_requests'):
  78. self.assertRpcsEventuallyGoToGivenServers(self.test_client,
  79. self.default_test_servers)
  80. with self.subTest(
  81. '10_secondary_locality_receives_no_requests_on_partial_primary_failure'
  82. ):
  83. self.default_test_servers[0].set_not_serving()
  84. self.assertRpcsEventuallyGoToGivenServers(
  85. self.test_client, self.default_test_servers[1:])
  86. with self.subTest('11_gentle_failover'):
  87. self.default_test_servers[1].set_not_serving()
  88. self.assertRpcsEventuallyGoToGivenServers(
  89. self.test_client,
  90. self.default_test_servers[2:] + self.alternate_test_servers)
  91. with self.subTest(
  92. '12_secondary_locality_receives_requests_on_primary_failure'):
  93. self.default_test_servers[2].set_not_serving()
  94. self.assertRpcsEventuallyGoToGivenServers(
  95. self.test_client, self.alternate_test_servers)
  96. with self.subTest('13_traffic_resumes_to_healthy_backends'):
  97. for i in range(self.REPLICA_COUNT):
  98. self.default_test_servers[i].set_serving()
  99. self.assertRpcsEventuallyGoToGivenServers(self.test_client,
  100. self.default_test_servers)
  101. if __name__ == '__main__':
  102. absltest.main(failfast=True)