cq_verifier.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. #include "test/core/end2end/cq_verifier.h"
  19. #include <inttypes.h>
  20. #include <stdarg.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <list>
  24. #include <string>
  25. #include <vector>
  26. #include "absl/strings/str_format.h"
  27. #include "absl/strings/str_join.h"
  28. #include <grpc/byte_buffer.h>
  29. #include <grpc/byte_buffer_reader.h>
  30. #include <grpc/support/alloc.h>
  31. #include <grpc/support/log.h>
  32. #include <grpc/support/string_util.h>
  33. #include <grpc/support/time.h>
  34. #include "src/core/lib/compression/compression_internal.h"
  35. #include "src/core/lib/compression/message_compress.h"
  36. #include "src/core/lib/gpr/string.h"
  37. #include "src/core/lib/surface/event_string.h"
  38. #define ROOT_EXPECTATION 1000
  39. // a set of metadata we expect to find on an event
  40. typedef struct metadata {
  41. size_t count;
  42. size_t cap;
  43. char** keys;
  44. char** values;
  45. } metadata;
  46. // details what we expect to find on a single event
  47. struct Expectation {
  48. Expectation(const char* f, int l, grpc_completion_type t, void* tag_arg,
  49. bool check_success_arg, int success_arg, bool* seen_arg)
  50. : file(f),
  51. line(l),
  52. type(t),
  53. tag(tag_arg),
  54. check_success(check_success_arg),
  55. success(success_arg),
  56. seen(seen_arg) {}
  57. const char* file;
  58. int line;
  59. grpc_completion_type type;
  60. void* tag;
  61. bool check_success;
  62. int success;
  63. bool* seen;
  64. };
  65. // the verifier itself
  66. struct cq_verifier {
  67. // bound completion queue
  68. grpc_completion_queue* cq;
  69. // expectation list
  70. std::list<Expectation> expectations;
  71. // maybe expectation list
  72. std::list<Expectation> maybe_expectations;
  73. };
  74. // TODO(yashykt): Convert this to constructor/destructor pair
  75. cq_verifier* cq_verifier_create(grpc_completion_queue* cq) {
  76. cq_verifier* v = new cq_verifier;
  77. v->cq = cq;
  78. return v;
  79. }
  80. void cq_verifier_destroy(cq_verifier* v) {
  81. cq_verify(v);
  82. delete v;
  83. }
  84. static int has_metadata(const grpc_metadata* md, size_t count, const char* key,
  85. const char* value) {
  86. size_t i;
  87. for (i = 0; i < count; i++) {
  88. if (0 == grpc_slice_str_cmp(md[i].key, key) &&
  89. 0 == grpc_slice_str_cmp(md[i].value, value)) {
  90. return 1;
  91. }
  92. }
  93. return 0;
  94. }
  95. int contains_metadata(grpc_metadata_array* array, const char* key,
  96. const char* value) {
  97. return has_metadata(array->metadata, array->count, key, value);
  98. }
  99. static int has_metadata_slices(const grpc_metadata* md, size_t count,
  100. grpc_slice key, grpc_slice value) {
  101. size_t i;
  102. for (i = 0; i < count; i++) {
  103. if (grpc_slice_eq(md[i].key, key) && grpc_slice_eq(md[i].value, value)) {
  104. return 1;
  105. }
  106. }
  107. return 0;
  108. }
  109. int contains_metadata_slices(grpc_metadata_array* array, grpc_slice key,
  110. grpc_slice value) {
  111. return has_metadata_slices(array->metadata, array->count, key, value);
  112. }
  113. static grpc_slice merge_slices(grpc_slice* slices, size_t nslices) {
  114. size_t i;
  115. size_t len = 0;
  116. uint8_t* cursor;
  117. grpc_slice out;
  118. for (i = 0; i < nslices; i++) {
  119. len += GRPC_SLICE_LENGTH(slices[i]);
  120. }
  121. out = grpc_slice_malloc(len);
  122. cursor = GRPC_SLICE_START_PTR(out);
  123. for (i = 0; i < nslices; i++) {
  124. memcpy(cursor, GRPC_SLICE_START_PTR(slices[i]),
  125. GRPC_SLICE_LENGTH(slices[i]));
  126. cursor += GRPC_SLICE_LENGTH(slices[i]);
  127. }
  128. return out;
  129. }
  130. int raw_byte_buffer_eq_slice(grpc_byte_buffer* rbb, grpc_slice b) {
  131. grpc_slice a;
  132. int ok;
  133. if (!rbb) return 0;
  134. a = merge_slices(rbb->data.raw.slice_buffer.slices,
  135. rbb->data.raw.slice_buffer.count);
  136. ok = GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b) &&
  137. 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
  138. GRPC_SLICE_LENGTH(a));
  139. grpc_slice_unref(a);
  140. grpc_slice_unref(b);
  141. return ok;
  142. }
  143. int byte_buffer_eq_slice(grpc_byte_buffer* bb, grpc_slice b) {
  144. if (bb == nullptr) return 0;
  145. if (bb->data.raw.compression > GRPC_COMPRESS_NONE) {
  146. grpc_slice_buffer decompressed_buffer;
  147. grpc_slice_buffer_init(&decompressed_buffer);
  148. GPR_ASSERT(grpc_msg_decompress(bb->data.raw.compression,
  149. &bb->data.raw.slice_buffer,
  150. &decompressed_buffer));
  151. grpc_byte_buffer* rbb = grpc_raw_byte_buffer_create(
  152. decompressed_buffer.slices, decompressed_buffer.count);
  153. int ret_val = raw_byte_buffer_eq_slice(rbb, b);
  154. grpc_byte_buffer_destroy(rbb);
  155. grpc_slice_buffer_destroy(&decompressed_buffer);
  156. return ret_val;
  157. }
  158. return raw_byte_buffer_eq_slice(bb, b);
  159. }
  160. int byte_buffer_eq_string(grpc_byte_buffer* bb, const char* str) {
  161. return byte_buffer_eq_slice(bb, grpc_slice_from_copied_string(str));
  162. }
  163. static bool is_probably_integer(void* p) {
  164. return reinterpret_cast<uintptr_t>(p) < 1000000;
  165. }
  166. namespace {
  167. std::string ExpectationString(const Expectation& e) {
  168. std::string out;
  169. if (is_probably_integer(e.tag)) {
  170. out = absl::StrFormat("tag(%" PRIdPTR ") ",
  171. reinterpret_cast<intptr_t>(e.tag));
  172. } else {
  173. out = absl::StrFormat("%p ", e.tag);
  174. }
  175. switch (e.type) {
  176. case GRPC_OP_COMPLETE:
  177. absl::StrAppendFormat(&out, "GRPC_OP_COMPLETE success=%d %s:%d",
  178. e.success, e.file, e.line);
  179. break;
  180. case GRPC_QUEUE_TIMEOUT:
  181. case GRPC_QUEUE_SHUTDOWN:
  182. gpr_log(GPR_ERROR, "not implemented");
  183. abort();
  184. }
  185. return out;
  186. }
  187. std::string ExpectationsString(const cq_verifier& v) {
  188. std::vector<std::string> expectations;
  189. for (const auto& e : v.expectations) {
  190. expectations.push_back(ExpectationString(e));
  191. }
  192. return absl::StrJoin(expectations, "\n");
  193. }
  194. } // namespace
  195. static void fail_no_event_received(cq_verifier* v) {
  196. gpr_log(GPR_ERROR, "no event received, but expected:%s",
  197. ExpectationsString(*v).c_str());
  198. abort();
  199. }
  200. static void verify_matches(const Expectation& e, const grpc_event& ev) {
  201. GPR_ASSERT(e.type == ev.type);
  202. switch (e.type) {
  203. case GRPC_OP_COMPLETE:
  204. if (e.check_success && e.success != ev.success) {
  205. gpr_log(GPR_ERROR, "actual success does not match expected: %s",
  206. ExpectationString(e).c_str());
  207. abort();
  208. }
  209. break;
  210. case GRPC_QUEUE_SHUTDOWN:
  211. gpr_log(GPR_ERROR, "premature queue shutdown");
  212. abort();
  213. case GRPC_QUEUE_TIMEOUT:
  214. gpr_log(GPR_ERROR, "not implemented");
  215. abort();
  216. }
  217. }
  218. // Try to find the event in the expectations list
  219. bool FindExpectations(std::list<Expectation>* expectations,
  220. const grpc_event& ev) {
  221. for (auto e = expectations->begin(); e != expectations->end(); ++e) {
  222. if (e->tag == ev.tag) {
  223. verify_matches(*e, ev);
  224. if (e->seen != nullptr) {
  225. *(e->seen) = true;
  226. }
  227. expectations->erase(e);
  228. return true;
  229. }
  230. }
  231. return false;
  232. }
  233. void cq_verify(cq_verifier* v, int timeout_sec) {
  234. const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(timeout_sec);
  235. while (!v->expectations.empty()) {
  236. grpc_event ev = grpc_completion_queue_next(v->cq, deadline, nullptr);
  237. if (ev.type == GRPC_QUEUE_TIMEOUT) {
  238. fail_no_event_received(v);
  239. break;
  240. }
  241. if (FindExpectations(&v->expectations, ev)) continue;
  242. if (FindExpectations(&v->maybe_expectations, ev)) continue;
  243. gpr_log(GPR_ERROR, "cq returned unexpected event: %s",
  244. grpc_event_string(&ev).c_str());
  245. gpr_log(GPR_ERROR, "expected tags:\n%s", ExpectationsString(*v).c_str());
  246. abort();
  247. }
  248. v->maybe_expectations.clear();
  249. }
  250. void cq_verify_empty_timeout(cq_verifier* v, int timeout_sec) {
  251. gpr_timespec deadline =
  252. gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
  253. gpr_time_from_seconds(timeout_sec, GPR_TIMESPAN));
  254. grpc_event ev;
  255. GPR_ASSERT(v->expectations.empty() && "expectation queue must be empty");
  256. ev = grpc_completion_queue_next(v->cq, deadline, nullptr);
  257. if (ev.type != GRPC_QUEUE_TIMEOUT) {
  258. gpr_log(GPR_ERROR, "unexpected event (expected nothing): %s",
  259. grpc_event_string(&ev).c_str());
  260. abort();
  261. }
  262. }
  263. void cq_verify_empty(cq_verifier* v) { cq_verify_empty_timeout(v, 1); }
  264. void cq_maybe_expect_completion(cq_verifier* v, const char* file, int line,
  265. void* tag, bool success, bool* seen) {
  266. v->maybe_expectations.emplace_back(file, line, GRPC_OP_COMPLETE, tag,
  267. true /* check_success */, success, seen);
  268. }
  269. static void add(cq_verifier* v, const char* file, int line,
  270. grpc_completion_type type, void* tag, bool check_success,
  271. bool success) {
  272. v->expectations.emplace_back(file, line, type, tag, check_success, success,
  273. nullptr);
  274. }
  275. void cq_expect_completion(cq_verifier* v, const char* file, int line, void* tag,
  276. bool success) {
  277. add(v, file, line, GRPC_OP_COMPLETE, tag, true, success);
  278. }
  279. void cq_expect_completion_any_status(cq_verifier* v, const char* file, int line,
  280. void* tag) {
  281. add(v, file, line, GRPC_OP_COMPLETE, tag, false, false);
  282. }