1 //
2 //
3 // Copyright 2017 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include <memory>
20
21 #include "absl/types/optional.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24
25 #include <grpc/grpc.h>
26 #include <grpc/impl/channel_arg_names.h>
27 #include <grpc/status.h>
28
29 #include "src/core/lib/channel/channel_args.h"
30 #include "src/core/lib/gprpp/time.h"
31 #include "test/core/end2end/end2end_tests.h"
32
33 namespace grpc_core {
34 namespace {
35
SimpleRequestBody(CoreEnd2endTest & test)36 bool SimpleRequestBody(CoreEnd2endTest& test) {
37 auto c = test.NewClientCall("/foo").Timeout(Duration::Minutes(1)).Create();
38 EXPECT_NE(c.GetPeer(), absl::nullopt);
39 CoreEnd2endTest::IncomingMetadata server_initial_metadata;
40 CoreEnd2endTest::IncomingStatusOnClient server_status;
41 c.NewBatch(1)
42 .SendInitialMetadata(
43 {}, GRPC_INITIAL_METADATA_WAIT_FOR_READY |
44 GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)
45 .SendCloseFromClient()
46 .RecvInitialMetadata(server_initial_metadata)
47 .RecvStatusOnClient(server_status);
48 auto s = test.RequestCall(101);
49 // Connection timeout may expire before we receive the request at the server,
50 // in which case we'll complete the client call but not the incoming call
51 // request from the server.
52 bool saw_request_at_server = false;
53 bool finished_client = false;
54 test.Expect(101, CoreEnd2endTest::Maybe{&saw_request_at_server});
55 test.Expect(1, CoreEnd2endTest::Maybe{&finished_client});
56 test.Step();
57 if (finished_client) {
58 EXPECT_FALSE(saw_request_at_server);
59 EXPECT_EQ(server_status.status(), GRPC_STATUS_UNAVAILABLE);
60 test.ShutdownServerAndNotify(1000);
61 test.Expect(1000, true);
62 test.Expect(101, false);
63 test.Step();
64 return false;
65 }
66 EXPECT_FALSE(finished_client);
67 EXPECT_TRUE(saw_request_at_server);
68 EXPECT_NE(s.GetPeer(), absl::nullopt);
69 EXPECT_NE(c.GetPeer(), absl::nullopt);
70 CoreEnd2endTest::IncomingCloseOnServer client_close;
71 s.NewBatch(102)
72 .SendInitialMetadata({})
73 .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
74 .RecvCloseOnServer(client_close);
75 test.Expect(102, true);
76 test.Expect(1, true);
77 test.Step();
78 EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
79 EXPECT_EQ(server_status.message(), "xyz");
80 EXPECT_EQ(s.method(), "/foo");
81 EXPECT_FALSE(client_close.was_cancelled());
82 return true;
83 }
84
CORE_END2END_TEST(RetryHttp2Test,MaxConnectionIdle)85 CORE_END2END_TEST(RetryHttp2Test, MaxConnectionIdle) {
86 const auto kMaxConnectionIdle = Duration::Seconds(2);
87 const auto kMaxConnectionAge = Duration::Seconds(10);
88 InitClient(
89 ChannelArgs()
90 .Set(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS,
91 Duration::Seconds(1).millis())
92 .Set(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, Duration::Seconds(1).millis())
93 .Set(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, Duration::Seconds(5).millis())
94 // Avoid transparent retries for this test.
95 .Set(GRPC_ARG_ENABLE_RETRIES, false));
96 InitServer(
97 ChannelArgs()
98 .Set(GRPC_ARG_MAX_CONNECTION_IDLE_MS, kMaxConnectionIdle.millis())
99 .Set(GRPC_ARG_MAX_CONNECTION_AGE_MS, kMaxConnectionAge.millis()));
100 // check that we're still in idle, and start connecting
101 grpc_connectivity_state state = CheckConnectivityState(true);
102 EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
103 // we'll go through some set of transitions (some might be missed), until
104 // READY is reached
105 while (state != GRPC_CHANNEL_READY) {
106 WatchConnectivityState(state, Duration::Seconds(10), 99);
107 Expect(99, true);
108 Step();
109 state = CheckConnectivityState(false);
110 EXPECT_THAT(state,
111 ::testing::AnyOf(GRPC_CHANNEL_READY, GRPC_CHANNEL_CONNECTING,
112 GRPC_CHANNEL_TRANSIENT_FAILURE));
113 }
114 // Use a simple request to cancel and reset the max idle timer
115 if (SimpleRequestBody(*this)) {
116 // wait for the channel to reach its maximum idle time
117 WatchConnectivityState(GRPC_CHANNEL_READY,
118 Duration::Seconds(3) + kMaxConnectionIdle, 99);
119 Expect(99, true);
120 Step();
121 state = CheckConnectivityState(false);
122 EXPECT_THAT(state,
123 ::testing::AnyOf(GRPC_CHANNEL_IDLE, GRPC_CHANNEL_CONNECTING,
124 GRPC_CHANNEL_TRANSIENT_FAILURE));
125 ShutdownServerAndNotify(1000);
126 Expect(1000, true);
127 Step();
128 }
129 }
130
131 } // namespace
132 } // namespace grpc_core
133