1from typing import Generator, Tuple, Union
2
3from abstract_tests import EGRPC, AmbassadorTest, Node
4from kat.harness import Query
5
6
7class AcceptanceGrpcStatsTest(AmbassadorTest):
8 def init(self):
9 self.target = EGRPC()
10
11 def config(self) -> Generator[Union[str, Tuple[Node, str]], None, None]:
12 yield self, self.format(
13 """
14---
15apiVersion: getambassador.io/v3alpha1
16kind: Module
17name: ambassador
18config:
19 grpc_stats:
20 all_methods: true
21 upstream_stats: true
22"""
23 )
24
25 yield self, self.format(
26 """
27---
28apiVersion: getambassador.io/v3alpha1
29kind: Mapping
30grpc: True
31hostname: "*"
32prefix: /echo.EchoService/
33rewrite: /echo.EchoService/
34name: {self.target.path.k8s}
35service: {self.target.path.k8s}
36"""
37 )
38
39 yield self, self.format(
40 """
41apiVersion: getambassador.io/v3alpha1
42kind: Mapping
43name: metrics
44hostname: "*"
45prefix: /metrics
46rewrite: /metrics
47service: http://127.0.0.1:8877
48"""
49 )
50
51 def queries(self):
52 # [0]
53 for i in range(10):
54 yield Query(
55 self.url("echo.EchoService/Echo"),
56 headers={"content-type": "application/grpc", "kat-req-echo-requested-status": "0"},
57 grpc_type="real",
58 phase=1,
59 )
60
61 for i in range(10):
62 yield Query(
63 self.url("echo.EchoService/Echo"),
64 headers={"content-type": "application/grpc", "kat-req-echo-requested-status": "13"},
65 grpc_type="real",
66 phase=1,
67 )
68
69 # [1]
70 yield Query(self.url("metrics"), phase=2)
71
72 def check(self):
73 # [0]
74 stats = self.results[-1].text
75
76 metrics = [
77 "envoy_cluster_grpc_Echo_0",
78 "envoy_cluster_grpc_Echo_13",
79 "envoy_cluster_grpc_Echo_request_message_count",
80 "envoy_cluster_grpc_Echo_response_message_count",
81 "envoy_cluster_grpc_Echo_success",
82 "envoy_cluster_grpc_Echo_total",
83 # present only when enable_upstream_stats is true
84 "envoy_cluster_grpc_Echo_upstream_rq_time",
85 ]
86
87 # these metrics SHOULD NOT be there based on the filter config
88 absent_metrics = [
89 # since all_methods is true, we should not see the generic metrics
90 "envoy_cluster_grpc_0" "envoy_cluster_grpc_13",
91 "envoy_cluster_grpc_request_message_count",
92 "envoy_cluster_grpc_response_message_count",
93 "envoy_cluster_grpc_success",
94 "envoy_cluster_grpc_total",
95 ]
96
97 # check if the metrics are there
98 for metric in metrics:
99 assert metric in stats, f"coult not find metric: {metric}"
100
101 for absent_metric in absent_metrics:
102 assert absent_metric not in stats, f"metric {metric} should not be present"
103
104 # check if the metrics are there
105 for metric in metrics:
106 assert metric in stats, f"coult not find metric: {metric}"
107
108
109class GrpcStatsTestOnlySelectedServices(AmbassadorTest):
110 def init(self):
111 self.target = EGRPC()
112
113 def config(self) -> Generator[Union[str, Tuple[Node, str]], None, None]:
114 yield self, self.format(
115 """
116---
117apiVersion: getambassador.io/v3alpha1
118kind: Module
119name: ambassador
120config:
121 grpc_stats:
122 # this will be ignored
123 all_methods: true
124 services:
125 - name: echo.EchoService
126 method_names: [Echo]
127"""
128 )
129
130 yield self, self.format(
131 """
132---
133apiVersion: getambassador.io/v3alpha1
134kind: Mapping
135grpc: True
136hostname: "*"
137prefix: /echo.EchoService/
138rewrite: /echo.EchoService/
139name: {self.target.path.k8s}
140service: {self.target.path.k8s}
141"""
142 )
143
144 yield self, self.format(
145 """
146apiVersion: getambassador.io/v3alpha1
147kind: Mapping
148name: metrics
149hostname: "*"
150prefix: /metrics
151rewrite: /metrics
152service: http://127.0.0.1:8877
153"""
154 )
155
156 def queries(self):
157 # [0]
158 for i in range(10):
159 yield Query(
160 self.url("echo.EchoService/Echo"),
161 headers={"content-type": "application/grpc", "kat-req-echo-requested-status": "0"},
162 grpc_type="real",
163 phase=1,
164 )
165
166 for i in range(10):
167 yield Query(
168 self.url("echo.EchoService/Echo"),
169 headers={"content-type": "application/grpc", "kat-req-echo-requested-status": "13"},
170 grpc_type="real",
171 phase=1,
172 )
173
174 # [1]
175 yield Query(self.url("metrics"), phase=2)
176
177 def check(self):
178 # [0]
179 stats = self.results[-1].text
180
181 metrics = [
182 "envoy_cluster_grpc_Echo_0",
183 "envoy_cluster_grpc_Echo_13",
184 "envoy_cluster_grpc_Echo_request_message_count",
185 "envoy_cluster_grpc_Echo_response_message_count",
186 "envoy_cluster_grpc_Echo_success",
187 "envoy_cluster_grpc_Echo_total",
188 ]
189
190 # these metrics SHOULD NOT be there based on the filter config
191 absent_metrics = [
192 # upstream stats is disabled
193 "envoy_cluster_grpc_upstream_rq_time",
194 # the generic metrics shouldn't be present since all the methods being called are on the allowed list
195 "envoy_cluster_grpc_0" "envoy_cluster_grpc_13",
196 "envoy_cluster_grpc_request_message_count",
197 "envoy_cluster_grpc_response_message_count",
198 "envoy_cluster_grpc_success",
199 "envoy_cluster_grpc_total",
200 ]
201
202 # check if the metrics are there
203 for metric in metrics:
204 assert metric in stats, f"coult not find metric: {metric}"
205
206 for absent_metric in absent_metrics:
207 assert absent_metric not in stats, f"metric {metric} should not be present"
208
209
210class GrpcStatsTestNoUpstreamAllMethodsFalseInvalidKeys(AmbassadorTest):
211 def init(self):
212 self.target = EGRPC()
213
214 def config(self) -> Generator[Union[str, Tuple[Node, str]], None, None]:
215 yield self, self.format(
216 """
217---
218apiVersion: getambassador.io/v3alpha1
219kind: Module
220name: ambassador
221config:
222 grpc_stats:
223 all_methods: false
224 upstream_stats: false
225 i_will_not_break_envoy: true
226"""
227 )
228
229 yield self, self.format(
230 """
231---
232apiVersion: getambassador.io/v3alpha1
233kind: Mapping
234grpc: True
235hostname: "*"
236prefix: /echo.EchoService/
237rewrite: /echo.EchoService/
238name: {self.target.path.k8s}
239service: {self.target.path.k8s}
240"""
241 )
242
243 yield self, self.format(
244 """
245apiVersion: getambassador.io/v3alpha1
246kind: Mapping
247name: metrics
248hostname: "*"
249prefix: /metrics
250rewrite: /metrics
251service: http://127.0.0.1:8877
252"""
253 )
254
255 def queries(self):
256 # [0]
257 for i in range(10):
258 yield Query(
259 self.url("echo.EchoService/Echo"),
260 headers={"content-type": "application/grpc", "kat-req-echo-requested-status": "0"},
261 grpc_type="real",
262 phase=1,
263 )
264
265 for i in range(10):
266 yield Query(
267 self.url("echo.EchoService/Echo"),
268 headers={"content-type": "application/grpc", "kat-req-echo-requested-status": "13"},
269 grpc_type="real",
270 phase=1,
271 )
272
273 # [1]
274 yield Query(self.url("metrics"), phase=2)
275
276 def check(self):
277 # [0]
278 stats = self.results[-1].text
279
280 # stat_all_methods is disabled and the list of services is empty, so we should only see generic metrics
281 metrics = [
282 "envoy_cluster_grpc_0",
283 "envoy_cluster_grpc_13",
284 "envoy_cluster_grpc_request_message_count",
285 "envoy_cluster_grpc_response_message_count",
286 "envoy_cluster_grpc_success",
287 "envoy_cluster_grpc_total",
288 ]
289
290 # these metrics SHOULD NOT be there based on the filter config
291 absent_metrics = ["envoy_cluster_grpc_upstream_rq_time", "envoy_cluster_grpc_EchoService_0"]
292
293 # check if the metrics are there
294 for metric in metrics:
295 assert metric in stats, f"coult not find metric: {metric}"
296
297 for absent_metric in absent_metrics:
298 assert absent_metric not in stats, f"metric {metric} should not be present"
View as plain text