cq_verifier.cc
Go to the documentation of this file.
1 //
2 //
3 // Copyright 2015 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 
20 
21 #include <inttypes.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
25 
26 #include <list>
27 #include <string>
28 #include <vector>
29 
30 #include "absl/strings/str_format.h"
31 #include "absl/strings/str_join.h"
32 
33 #include <grpc/byte_buffer.h>
35 #include <grpc/support/alloc.h>
36 #include <grpc/support/log.h>
38 #include <grpc/support/time.h>
39 
44 
45 #define ROOT_EXPECTATION 1000
46 
47 // a set of metadata we expect to find on an event
48 typedef struct metadata {
49  size_t count;
50  size_t cap;
51  char** keys;
52  char** values;
53 } metadata;
54 
55 // details what we expect to find on a single event
56 struct Expectation {
57  Expectation(const char* f, int l, grpc_completion_type t, void* tag_arg,
58  bool check_success_arg, int success_arg, bool* seen_arg)
59  : file(f),
60  line(l),
61  type(t),
62  tag(tag_arg),
63  check_success(check_success_arg),
64  success(success_arg),
65  seen(seen_arg) {}
66  const char* file;
67  int line;
69  void* tag;
71  int success;
72  bool* seen;
73 };
74 
75 // the verifier itself
76 struct cq_verifier {
77  // bound completion queue
79  // expectation list
80  std::list<Expectation> expectations;
81  // maybe expectation list
82  std::list<Expectation> maybe_expectations;
83 };
84 
85 // TODO(yashykt): Convert this to constructor/destructor pair
87  cq_verifier* v = new cq_verifier;
88  v->cq = cq;
89  return v;
90 }
91 
93  cq_verify(v);
94  delete v;
95 }
96 
97 static int has_metadata(const grpc_metadata* md, size_t count, const char* key,
98  const char* value) {
99  size_t i;
100  for (i = 0; i < count; i++) {
101  if (0 == grpc_slice_str_cmp(md[i].key, key) &&
102  0 == grpc_slice_str_cmp(md[i].value, value)) {
103  return 1;
104  }
105  }
106  return 0;
107 }
108 
110  const char* value) {
111  return has_metadata(array->metadata, array->count, key, value);
112 }
113 
114 static int has_metadata_slices(const grpc_metadata* md, size_t count,
116  size_t i;
117  for (i = 0; i < count; i++) {
118  if (grpc_slice_eq(md[i].key, key) && grpc_slice_eq(md[i].value, value)) {
119  return 1;
120  }
121  }
122  return 0;
123 }
124 
126  grpc_slice value) {
127  return has_metadata_slices(array->metadata, array->count, key, value);
128 }
129 
130 static grpc_slice merge_slices(grpc_slice* slices, size_t nslices) {
131  size_t i;
132  size_t len = 0;
133  uint8_t* cursor;
134  grpc_slice out;
135 
136  for (i = 0; i < nslices; i++) {
138  }
139 
141  cursor = GRPC_SLICE_START_PTR(out);
142 
143  for (i = 0; i < nslices; i++) {
146  cursor += GRPC_SLICE_LENGTH(slices[i]);
147  }
148 
149  return out;
150 }
151 
153  grpc_slice a;
154  int ok;
155 
156  if (!rbb) return 0;
157 
159  rbb->data.raw.slice_buffer.count);
165  return ok;
166 }
167 
169  if (bb == nullptr) return 0;
171  grpc_slice_buffer decompressed_buffer;
172  grpc_slice_buffer_init(&decompressed_buffer);
174  &bb->data.raw.slice_buffer,
175  &decompressed_buffer));
177  decompressed_buffer.slices, decompressed_buffer.count);
178  int ret_val = raw_byte_buffer_eq_slice(rbb, b);
180  grpc_slice_buffer_destroy(&decompressed_buffer);
181  return ret_val;
182  }
183  return raw_byte_buffer_eq_slice(bb, b);
184 }
185 
188 }
189 
190 static bool is_probably_integer(void* p) {
191  return reinterpret_cast<uintptr_t>(p) < 1000000;
192 }
193 
194 namespace {
195 
196 std::string ExpectationString(const Expectation& e) {
198  if (is_probably_integer(e.tag)) {
199  out = absl::StrFormat("tag(%" PRIdPTR ") ",
200  reinterpret_cast<intptr_t>(e.tag));
201  } else {
202  out = absl::StrFormat("%p ", e.tag);
203  }
204  switch (e.type) {
205  case GRPC_OP_COMPLETE:
206  absl::StrAppendFormat(&out, "GRPC_OP_COMPLETE success=%d %s:%d",
207  e.success, e.file, e.line);
208  break;
209  case GRPC_QUEUE_TIMEOUT:
210  case GRPC_QUEUE_SHUTDOWN:
211  gpr_log(GPR_ERROR, "not implemented");
212  abort();
213  }
214  return out;
215 }
216 
217 std::string ExpectationsString(const cq_verifier& v) {
218  std::vector<std::string> expectations;
219  for (const auto& e : v.expectations) {
220  expectations.push_back(ExpectationString(e));
221  }
222  return absl::StrJoin(expectations, "\n");
223 }
224 
225 } // namespace
226 
228  gpr_log(GPR_ERROR, "no event received, but expected:%s",
229  ExpectationsString(*v).c_str());
230  abort();
231 }
232 
233 static void verify_matches(const Expectation& e, const grpc_event& ev) {
234  GPR_ASSERT(e.type == ev.type);
235  switch (e.type) {
236  case GRPC_OP_COMPLETE:
237  if (e.check_success && e.success != ev.success) {
238  gpr_log(GPR_ERROR, "actual success does not match expected: %s",
239  ExpectationString(e).c_str());
240  abort();
241  }
242  break;
243  case GRPC_QUEUE_SHUTDOWN:
244  gpr_log(GPR_ERROR, "premature queue shutdown");
245  abort();
246  case GRPC_QUEUE_TIMEOUT:
247  gpr_log(GPR_ERROR, "not implemented");
248  abort();
249  }
250 }
251 
252 // Try to find the event in the expectations list
253 bool FindExpectations(std::list<Expectation>* expectations,
254  const grpc_event& ev) {
255  for (auto e = expectations->begin(); e != expectations->end(); ++e) {
256  if (e->tag == ev.tag) {
257  verify_matches(*e, ev);
258  if (e->seen != nullptr) {
259  *(e->seen) = true;
260  }
261  expectations->erase(e);
262  return true;
263  }
264  }
265  return false;
266 }
267 
270  while (!v->expectations.empty()) {
271  grpc_event ev = grpc_completion_queue_next(v->cq, deadline, nullptr);
272  if (ev.type == GRPC_QUEUE_TIMEOUT) {
274  break;
275  }
276  if (FindExpectations(&v->expectations, ev)) continue;
277  if (FindExpectations(&v->maybe_expectations, ev)) continue;
278  gpr_log(GPR_ERROR, "cq returned unexpected event: %s",
279  grpc_event_string(&ev).c_str());
280  gpr_log(GPR_ERROR, "expected tags:\n%s", ExpectationsString(*v).c_str());
281  abort();
282  }
283  v->maybe_expectations.clear();
284 }
285 
287  gpr_timespec deadline =
290  grpc_event ev;
291 
292  GPR_ASSERT(v->expectations.empty() && "expectation queue must be empty");
293 
294  ev = grpc_completion_queue_next(v->cq, deadline, nullptr);
295  if (ev.type != GRPC_QUEUE_TIMEOUT) {
296  gpr_log(GPR_ERROR, "unexpected event (expected nothing): %s",
297  grpc_event_string(&ev).c_str());
298  abort();
299  }
300 }
301 
303 
305  void* tag, bool success, bool* seen) {
306  v->maybe_expectations.emplace_back(file, line, GRPC_OP_COMPLETE, tag,
307  true /* check_success */, success, seen);
308 }
309 
310 static void add(cq_verifier* v, const char* file, int line,
311  grpc_completion_type type, void* tag, bool check_success,
312  bool success) {
313  v->expectations.emplace_back(file, line, type, tag, check_success, success,
314  nullptr);
315 }
316 
317 void cq_expect_completion(cq_verifier* v, const char* file, int line, void* tag,
318  bool success) {
319  add(v, file, line, GRPC_OP_COMPLETE, tag, true, success);
320 }
321 
323  void* tag) {
324  add(v, file, line, GRPC_OP_COMPLETE, tag, false, false);
325 }
absl::StrAppendFormat
std::string & StrAppendFormat(std::string *dst, const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:356
xds_interop_client.str
str
Definition: xds_interop_client.py:487
GPR_TIMESPAN
@ GPR_TIMESPAN
Definition: gpr_types.h:45
grpc_slice_unref
GPRAPI void grpc_slice_unref(grpc_slice s)
Definition: slice_api.cc:32
grpc_slice_buffer_destroy
GPRAPI void grpc_slice_buffer_destroy(grpc_slice_buffer *sb)
Definition: slice_buffer_api.cc:27
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
Expectation::type
grpc_completion_type type
Definition: cq_verifier.cc:68
grpc_timeout_seconds_to_deadline
gpr_timespec grpc_timeout_seconds_to_deadline(int64_t time_s)
Definition: test/core/util/test_config.cc:81
grpc_completion_type
grpc_completion_type
Definition: grpc_types.h:552
log.h
grpc_raw_byte_buffer_create
GRPCAPI grpc_byte_buffer * grpc_raw_byte_buffer_create(grpc_slice *slices, size_t nslices)
Definition: byte_buffer.cc:34
metadata
Definition: cq_verifier.cc:48
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
grpc_slice_from_copied_string
GPRAPI grpc_slice grpc_slice_from_copied_string(const char *source)
Definition: slice/slice.cc:177
raw_byte_buffer_eq_slice
int raw_byte_buffer_eq_slice(grpc_byte_buffer *rbb, grpc_slice b)
Definition: cq_verifier.cc:152
Expectation::Expectation
Expectation(const char *f, int l, grpc_completion_type t, void *tag_arg, bool check_success_arg, int success_arg, bool *seen_arg)
Definition: cq_verifier.cc:57
grpc_metadata_array
Definition: grpc_types.h:579
grpc_byte_buffer::grpc_byte_buffer_data::raw
struct grpc_byte_buffer::grpc_byte_buffer_data::grpc_compressed_buffer raw
string.h
Expectation::success
int success
Definition: cq_verifier.cc:71
grpc_slice_buffer::slices
grpc_slice * slices
Definition: include/grpc/impl/codegen/slice.h:89
metadata
struct metadata metadata
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
GRPC_QUEUE_SHUTDOWN
@ GRPC_QUEUE_SHUTDOWN
Definition: grpc_types.h:554
GRPC_OP_COMPLETE
@ GRPC_OP_COMPLETE
Definition: grpc_types.h:558
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
cq_expect_completion_any_status
void cq_expect_completion_any_status(cq_verifier *v, const char *file, int line, void *tag)
Definition: cq_verifier.cc:322
time.h
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
add
static void add(cq_verifier *v, const char *file, int line, grpc_completion_type type, void *tag, bool check_success, bool success)
Definition: cq_verifier.cc:310
xds_manager.p
p
Definition: xds_manager.py:60
byte_buffer_eq_string
int byte_buffer_eq_string(grpc_byte_buffer *bb, const char *str)
Definition: cq_verifier.cc:186
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
has_metadata_slices
static int has_metadata_slices(const grpc_metadata *md, size_t count, grpc_slice key, grpc_slice value)
Definition: cq_verifier.cc:114
GRPC_COMPRESS_NONE
@ GRPC_COMPRESS_NONE
Definition: compression_types.h:61
grpc_slice_malloc
GPRAPI grpc_slice grpc_slice_malloc(size_t length)
Definition: slice/slice.cc:227
verify_matches
static void verify_matches(const Expectation &e, const grpc_event &ev)
Definition: cq_verifier.cc:233
cq_maybe_expect_completion
void cq_maybe_expect_completion(cq_verifier *v, const char *file, int line, void *tag, bool success, bool *seen)
Definition: cq_verifier.cc:304
byte_buffer_reader.h
metadata::cap
size_t cap
Definition: cq_verifier.cc:50
contains_metadata_slices
int contains_metadata_slices(grpc_metadata_array *array, grpc_slice key, grpc_slice value)
Definition: cq_verifier.cc:125
string_util.h
grpc_metadata
Definition: grpc_types.h:537
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
absl::FormatConversionChar::e
@ e
cq_expect_completion
void cq_expect_completion(cq_verifier *v, const char *file, int line, void *tag, bool success)
Definition: cq_verifier.cc:317
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
cq_verify_empty
void cq_verify_empty(cq_verifier *v)
Definition: cq_verifier.cc:302
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
absl::StrJoin
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep, Formatter &&fmt)
Definition: abseil-cpp/absl/strings/str_join.h:239
array
Definition: undname.c:101
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
grpc_slice_buffer::count
size_t count
Definition: include/grpc/impl/codegen/slice.h:91
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
grpc_event
Definition: grpc_types.h:564
grpc_completion_queue
Definition: completion_queue.cc:347
cq_verifier_destroy
void cq_verifier_destroy(cq_verifier *v)
Definition: cq_verifier.cc:92
grpc_byte_buffer
Definition: grpc_types.h:43
xds_manager.timeout_sec
timeout_sec
Definition: xds_manager.py:58
GRPC_SLICE_START_PTR
#define GRPC_SLICE_START_PTR(slice)
Definition: include/grpc/impl/codegen/slice.h:101
cq_verifier_create
cq_verifier * cq_verifier_create(grpc_completion_queue *cq)
Definition: cq_verifier.cc:86
cq_verifier::cq
grpc_completion_queue * cq
Definition: cq_verifier.cc:78
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
GPR_CLOCK_MONOTONIC
@ GPR_CLOCK_MONOTONIC
Definition: gpr_types.h:36
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
cq_verifier
Definition: cq_verifier.cc:76
Expectation::seen
bool * seen
Definition: cq_verifier.cc:72
metadata::count
size_t count
Definition: cq_verifier.cc:49
event_string.h
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
grpc_msg_decompress
int grpc_msg_decompress(grpc_compression_algorithm algorithm, grpc_slice_buffer *input, grpc_slice_buffer *output)
Definition: message_compress.cc:180
contains_metadata
int contains_metadata(grpc_metadata_array *array, const char *key, const char *value)
Definition: cq_verifier.cc:109
gpr_now
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock)
grpc_slice_buffer_init
GPRAPI void grpc_slice_buffer_init(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:116
Expectation::line
int line
Definition: cq_verifier.cc:67
GRPC_SLICE_LENGTH
#define GRPC_SLICE_LENGTH(slice)
Definition: include/grpc/impl/codegen/slice.h:104
grpc_byte_buffer::data
union grpc_byte_buffer::grpc_byte_buffer_data data
value
const char * value
Definition: hpack_parser_table.cc:165
compression_internal.h
metadata::values
char ** values
Definition: cq_verifier.cc:52
benchmark.md
md
Definition: benchmark.py:86
key
const char * key
Definition: hpack_parser_table.cc:164
cq_verifier.h
cq_verifier::expectations
std::list< Expectation > expectations
Definition: cq_verifier.cc:80
gpr_time_add
GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:135
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
has_metadata
static int has_metadata(const grpc_metadata *md, size_t count, const char *key, const char *value)
Definition: cq_verifier.cc:97
grpc_byte_buffer::grpc_byte_buffer_data::grpc_compressed_buffer::compression
grpc_compression_algorithm compression
Definition: grpc_types.h:51
alloc.h
slices
SliceBuffer * slices
Definition: retry_filter.cc:631
Expectation
Definition: cq_verifier.cc:56
grpc_byte_buffer_destroy
GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer *bb)
Definition: byte_buffer.cc:81
regen-readme.line
line
Definition: regen-readme.py:30
grpc_completion_queue_next
GRPCAPI grpc_event grpc_completion_queue_next(grpc_completion_queue *cq, gpr_timespec deadline, void *reserved)
Definition: completion_queue.cc:1133
cq_verify
void cq_verify(cq_verifier *v, int timeout_sec)
Definition: cq_verifier.cc:268
cq_verifier::maybe_expectations
std::list< Expectation > maybe_expectations
Definition: cq_verifier.cc:82
cq_verifier
struct cq_verifier cq_verifier
Definition: cq_verifier.h:31
ok
bool ok
Definition: async_end2end_test.cc:197
Expectation::check_success
bool check_success
Definition: cq_verifier.cc:70
FindExpectations
bool FindExpectations(std::list< Expectation > *expectations, const grpc_event &ev)
Definition: cq_verifier.cc:253
fail_no_event_received
static void fail_no_event_received(cq_verifier *v)
Definition: cq_verifier.cc:227
grpc_byte_buffer::grpc_byte_buffer_data::grpc_compressed_buffer::slice_buffer
grpc_slice_buffer slice_buffer
Definition: grpc_types.h:52
grpc_event_string
std::string grpc_event_string(grpc_event *ev)
Definition: event_string.cc:39
is_probably_integer
static bool is_probably_integer(void *p)
Definition: cq_verifier.cc:190
grpc_slice_buffer
Definition: include/grpc/impl/codegen/slice.h:83
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
gpr_timespec
Definition: gpr_types.h:50
grpc_event::type
grpc_completion_type type
Definition: grpc_types.h:566
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
message_compress.h
cq_verify_empty_timeout
void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec)
Definition: cq_verifier.cc:286
merge_slices
static grpc_slice merge_slices(grpc_slice *slices, size_t nslices)
Definition: cq_verifier.cc:130
grpc_slice_str_cmp
GPRAPI int grpc_slice_str_cmp(grpc_slice a, const char *b)
Definition: slice/slice.cc:426
seen
bool * seen
Definition: async_end2end_test.cc:198
byte_buffer_eq_slice
int byte_buffer_eq_slice(grpc_byte_buffer *bb, grpc_slice b)
Definition: cq_verifier.cc:168
metadata::keys
char ** keys
Definition: cq_verifier.cc:51
grpc_event::success
int success
Definition: grpc_types.h:572
GRPC_QUEUE_TIMEOUT
@ GRPC_QUEUE_TIMEOUT
Definition: grpc_types.h:556
grpc_slice_eq
GPRAPI int grpc_slice_eq(grpc_slice a, grpc_slice b)
Definition: slice/slice.cc:387
Expectation::tag
void * tag
Definition: cq_verifier.cc:69
grpc_event::tag
void * tag
Definition: grpc_types.h:576
cq
static grpc_completion_queue * cq
Definition: test/core/fling/client.cc:37
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
Expectation::file
const char * file
Definition: cq_verifier.cc:66
gpr_time_from_seconds
GPRAPI gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:123


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:06