TEST(RouterFilterUtilityTest, SetTimeoutHeaders) {
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(0);

    FilterUtility::setTimeoutHeaders(0, timeout, route, headers, true, false, false);
    EXPECT_EQ("200",
              headers.get_(
                  "x-envoy-expected-rq-timeout-ms")); // No per try configured, use global timeout
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(0);

    FilterUtility::setTimeoutHeaders(150, timeout, route, headers, true, false, false);
    EXPECT_EQ("50", headers.get_("x-envoy-expected-rq-timeout-ms")); // Remains of global timeout
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(0, timeout, route, headers, true, false, false);
    EXPECT_EQ("150", headers.get_("x-envoy-expected-rq-timeout-ms")); // Per try timeout
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(25, timeout, route, headers, true, false, false);
    EXPECT_EQ("150", headers.get_("x-envoy-expected-rq-timeout-ms")); // Per try timeout
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(150, timeout, route, headers, true, false, false);
    EXPECT_EQ("50", headers.get_("x-envoy-expected-rq-timeout-ms")); // Remains of global timeout
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(0);

    FilterUtility::setTimeoutHeaders(300, timeout, route, headers, true, false, false);
    EXPECT_EQ("1", headers.get_("x-envoy-expected-rq-timeout-ms")); // Over time
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(0, timeout, route, headers, true, false, true);
    EXPECT_EQ("200", headers.get_("x-envoy-expected-rq-timeout-ms")); // Global timeout as hedged
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(25, timeout, route, headers, true, false, true);
    EXPECT_EQ("175", headers.get_(
                         "x-envoy-expected-rq-timeout-ms")); // Remains of global timeout as hedged
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(150, timeout, route, headers, true, false, true);
    EXPECT_EQ("50", headers.get_(
                        "x-envoy-expected-rq-timeout-ms")); // Remains of global timeout as hedged
  }
}
TEST(RouterFilterUtilityTest, SetTimeoutHeaders) {
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(0);

    FilterUtility::setTimeoutHeaders(0, timeout, route, headers, true, false, false);
    EXPECT_EQ("200",
              headers.get_(
                  "x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(0);

    FilterUtility::setTimeoutHeaders(150, timeout, route, headers, true, false, false);
    EXPECT_EQ("50", headers.get_("x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(0, timeout, route, headers, true, false, false);
    EXPECT_EQ("150", headers.get_("x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(25, timeout, route, headers, true, false, false);
    EXPECT_EQ("150", headers.get_("x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(150, timeout, route, headers, true, false, false);
    EXPECT_EQ("50", headers.get_("x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(0);

    FilterUtility::setTimeoutHeaders(300, timeout, route, headers, true, false, false);
    EXPECT_EQ("1", headers.get_("x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(0, timeout, route, headers, true, false, true);
    EXPECT_EQ("200", headers.get_("x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(25, timeout, route, headers, true, false, true);
    EXPECT_EQ("175", headers.get_(
                         "x-envoy-expected-rq-timeout-ms"));  
  }
  {
    NiceMock<MockRouteEntry> route;
    Http::TestRequestHeaderMapImpl headers;
    FilterUtility::TimeoutData timeout;
    timeout.global_timeout_ = std::chrono::milliseconds(200);
    timeout.per_try_timeout_ = std::chrono::milliseconds(150);

    FilterUtility::setTimeoutHeaders(150, timeout, route, headers, true, false, true);
    EXPECT_EQ("50", headers.get_(
                        "x-envoy-expected-rq-timeout-ms"));  
  }
}