1 //
2 // Copyright 2022 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <grpc/grpc.h>
18
19 #include <memory>
20
21 #include "absl/status/status.h"
22 #include "absl/status/statusor.h"
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "src/core/lib/channel/channel_args.h"
26 #include "src/core/service_config/service_config.h"
27 #include "src/core/service_config/service_config_impl.h"
28 #include "src/core/util/ref_counted_ptr.h"
29 #include "test/core/test_util/test_config.h"
30
31 namespace grpc_core {
32 namespace testing {
33 namespace {
34
35 class OutlierDetectionConfigParsingTest : public ::testing::Test {
36 public:
SetUpTestSuite()37 static void SetUpTestSuite() { grpc_init(); }
38
TearDownTestSuite()39 static void TearDownTestSuite() { grpc_shutdown_blocking(); }
40 };
41
TEST_F(OutlierDetectionConfigParsingTest,ValidConfig)42 TEST_F(OutlierDetectionConfigParsingTest, ValidConfig) {
43 const char* service_config_json =
44 "{\n"
45 " \"loadBalancingConfig\":[{\n"
46 " \"outlier_detection_experimental\":{\n"
47 " \"interval\":\"1.2s\",\n"
48 " \"baseEjectionTime\":\"2.3s\",\n"
49 " \"maxEjectionTime\":\"3.4s\",\n"
50 " \"maxEjectionPercent\":3,\n"
51 " \"successRateEjection\":{\n"
52 " \"stdevFactor\":1,\n"
53 " \"enforcementPercentage\":2,\n"
54 " \"minimumHosts\":3,\n"
55 " \"requestVolume\":4\n"
56 " },\n"
57 " \"failurePercentageEjection\":{\n"
58 " \"threshold\":1,\n"
59 " \"enforcementPercentage\":2,\n"
60 " \"minimumHosts\":3,\n"
61 " \"requestVolume\":4\n"
62 " },\n"
63 " \"childPolicy\":[\n"
64 " {\"unknown\":{}},\n" // Okay, since the next one exists.
65 " {\"grpclb\":{}}\n"
66 " ]\n"
67 " }\n"
68 " }]\n"
69 "}\n";
70 auto service_config =
71 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
72 ASSERT_TRUE(service_config.ok()) << service_config.status();
73 EXPECT_NE(*service_config, nullptr);
74 }
75
TEST_F(OutlierDetectionConfigParsingTest,InvalidValues)76 TEST_F(OutlierDetectionConfigParsingTest, InvalidValues) {
77 const char* service_config_json =
78 "{\n"
79 " \"loadBalancingConfig\":[{\n"
80 " \"outlier_detection_experimental\":{\n"
81 " \"interval\":\"-1s\",\n"
82 " \"baseEjectionTime\":\"315576000001s\",\n"
83 " \"maxEjectionTime\":\"-3.4s\",\n"
84 " \"maxEjectionPercent\":101,\n"
85 " \"successRateEjection\":{\n"
86 " \"enforcementPercentage\":101\n"
87 " },\n"
88 " \"failurePercentageEjection\":{\n"
89 " \"threshold\":101,\n"
90 " \"enforcementPercentage\":101\n"
91 " },\n"
92 " \"childPolicy\":[\n"
93 " {\"unknown\":{}}\n"
94 " ]\n"
95 " }\n"
96 " }]\n"
97 "}\n";
98 auto service_config =
99 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
100 EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
101 EXPECT_THAT(service_config.status().message(),
102 ::testing::HasSubstr(
103 "errors validating outlier_detection LB policy config: ["
104 "field:baseEjectionTime "
105 "error:seconds must be in the range [0, 315576000000]; "
106 "field:childPolicy error:No known policies in list: unknown; "
107 "field:failurePercentageEjection.enforcement_percentage "
108 "error:value must be <= 100; "
109 "field:failurePercentageEjection.threshold "
110 "error:value must be <= 100; "
111 "field:interval "
112 "error:seconds must be in the range [0, 315576000000]; "
113 "field:maxEjectionTime "
114 "error:seconds must be in the range [0, 315576000000]; "
115 "field:max_ejection_percent error:value must be <= 100; "
116 "field:successRateEjection.enforcement_percentage "
117 "error:value must be <= 100]"))
118 << service_config.status();
119 }
120
TEST_F(OutlierDetectionConfigParsingTest,MissingChildPolicyField)121 TEST_F(OutlierDetectionConfigParsingTest, MissingChildPolicyField) {
122 const char* service_config_json =
123 "{\n"
124 " \"loadBalancingConfig\":[{\n"
125 " \"outlier_detection_experimental\":{\n"
126 " \"interval\":\"1.2s\",\n"
127 " \"baseEjectionTime\":\"2.3s\",\n"
128 " \"maxEjectionTime\":\"3.4s\",\n"
129 " \"maxEjectionPercent\":3,\n"
130 " \"successRateEjection\":{\n"
131 " \"stdevFactor\":1,\n"
132 " \"enforcementPercentage\":2,\n"
133 " \"minimumHosts\":3,\n"
134 " \"requestVolume\":4\n"
135 " },\n"
136 " \"failurePercentageEjection\":{\n"
137 " \"threshold\":1,\n"
138 " \"enforcementPercentage\":2,\n"
139 " \"minimumHosts\":3,\n"
140 " \"requestVolume\":4\n"
141 " }\n"
142 " }\n"
143 " }]\n"
144 "}\n";
145 auto service_config =
146 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
147 EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
148 EXPECT_THAT(service_config.status().message(),
149 ::testing::HasSubstr(
150 "errors validating outlier_detection LB policy config: ["
151 "field:childPolicy error:field not present]"))
152 << service_config.status();
153 }
154
155 } // namespace
156 } // namespace testing
157 } // namespace grpc_core
158
main(int argc,char ** argv)159 int main(int argc, char** argv) {
160 ::testing::InitGoogleTest(&argc, argv);
161 grpc::testing::TestEnvironment env(&argc, argv);
162 return RUN_ALL_TESTS();
163 }
164