...

Text file src/github.com/datawire/ambassador/v2/python/tests/kat/t_retrypolicy.py

Documentation: github.com/datawire/ambassador/v2/python/tests/kat

     1import re
     2from datetime import datetime
     3from typing import Generator, Tuple, Union
     4
     5from abstract_tests import HTTP, AmbassadorTest, Node, ServiceType
     6from kat.harness import Query
     7
     8
     9class RetryPolicyTest(AmbassadorTest):
    10    target: ServiceType
    11
    12    def init(self) -> None:
    13        self.target = HTTP()
    14
    15    def config(self) -> Generator[Union[str, Tuple[Node, str]], None, None]:
    16        yield self, self.format(
    17            """
    18---
    19apiVersion: getambassador.io/v3alpha1
    20kind: Mapping
    21name:  {self.name}-normal
    22hostname: "*"
    23prefix: /{self.name}-normal/
    24service: {self.target.path.fqdn}
    25timeout_ms: 3000
    26"""
    27        )
    28
    29        yield self, self.format(
    30            """
    31---
    32apiVersion: getambassador.io/v3alpha1
    33kind: Mapping
    34name:  {self.name}-target
    35hostname: "*"
    36prefix: /{self.name}-retry/
    37service: {self.target.path.fqdn}
    38timeout_ms: 3000
    39retry_policy:
    40  retry_on: "5xx"
    41  num_retries: 4
    42"""
    43        )
    44
    45        yield self, self.format(
    46            """
    47---
    48apiVersion: getambassador.io/v3alpha1
    49kind:  Module
    50name:  ambassador
    51config:
    52  retry_policy:
    53    retry_on: "retriable-4xx"
    54    num_retries: 4
    55"""
    56        )
    57
    58    def queries(self):
    59        yield Query(
    60            self.url(self.name + "-normal/"), headers={"Requested-Backend-Delay": "0"}, expected=200
    61        )
    62        yield Query(
    63            self.url(self.name + "-normal/"), headers={"Requested-Status": "500"}, expected=500
    64        )
    65        yield Query(
    66            self.url(self.name + "-retry/"),
    67            headers={"Requested-Status": "500", "Requested-Backend-Delay": "2000"},
    68            expected=504,
    69        )
    70        yield Query(
    71            self.url(self.name + "-normal/"),
    72            headers={"Requested-Status": "409", "Requested-Backend-Delay": "2000"},
    73            expected=504,
    74        )
    75
    76    def get_timestamp(self, hdr):
    77        m = re.match(r"^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{1,6})", hdr)
    78
    79        if m:
    80            return datetime.strptime(m.group(1), "%Y-%m-%dT%H:%M:%S.%f").timestamp()
    81        else:
    82            assert False, f'header timestamp "{hdr}" is not parseable'
    83            return None
    84
    85    def get_duration(self, result):
    86        start_time = self.get_timestamp(result.headers["Client-Start-Date"][0])
    87        end_time = self.get_timestamp(result.headers["Client-End-Date"][0])
    88
    89        return end_time - start_time
    90
    91    def check(self):
    92        ok_result = self.results[0]
    93        normal_result = self.results[1]
    94        retry_result = self.results[2]
    95        conflict_result = self.results[3]
    96
    97        ok_duration = self.get_duration(ok_result)
    98        normal_duration = self.get_duration(normal_result)
    99        retry_duration = self.get_duration(retry_result)
   100        conflict_duration = self.get_duration(conflict_result)
   101
   102        assert retry_duration >= 2, f"retry time {retry_duration} must be at least 2 seconds"
   103        assert (
   104            conflict_duration >= 2
   105        ), f"conflict time {conflict_duration} must be at least 2 seconds"
   106
   107        ok_vs_normal = abs(ok_duration - normal_duration)
   108
   109        assert (
   110            ok_vs_normal <= 1
   111        ), f"time to 200 OK {ok_duration} is more than 1 second different from time to 500 {normal_duration}"
   112
   113        retry_vs_normal = retry_duration - normal_duration
   114
   115        assert (
   116            retry_vs_normal >= 2
   117        ), f"retry time {retry_duration} is not at least 2 seconds slower than normal time {normal_duration}"
   118
   119        conflict_vs_ok = conflict_duration - ok_duration
   120
   121        assert (
   122            conflict_vs_ok >= 2
   123        ), f"conflict time {conflict_duration} is not at least 2 seconds slower than ok time {ok_duration}"

View as plain text