LCOV - code coverage report
Current view: top level - test/core/end2end - cq_verifier.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 87 129 67.4 %
Date: 2015-10-10 Functions: 12 15 80.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : #include "test/core/end2end/cq_verifier.h"
      35             : 
      36             : #include <stdarg.h>
      37             : #include <stdio.h>
      38             : #include <string.h>
      39             : 
      40             : #include "src/core/surface/event_string.h"
      41             : #include "src/core/support/string.h"
      42             : #include <grpc/byte_buffer.h>
      43             : #include <grpc/byte_buffer_reader.h>
      44             : #include <grpc/support/alloc.h>
      45             : #include <grpc/support/log.h>
      46             : #include <grpc/support/string_util.h>
      47             : #include <grpc/support/time.h>
      48             : #include <grpc/support/useful.h>
      49             : 
      50             : #define ROOT_EXPECTATION 1000
      51             : 
      52             : /* a set of metadata we expect to find on an event */
      53             : typedef struct metadata {
      54             :   size_t count;
      55             :   size_t cap;
      56             :   char **keys;
      57             :   char **values;
      58             : } metadata;
      59             : 
      60             : /* details what we expect to find on a single event - and forms a linked
      61             :    list to detail other expectations */
      62             : typedef struct expectation {
      63             :   struct expectation *next;
      64             :   struct expectation *prev;
      65             :   grpc_completion_type type;
      66             :   void *tag;
      67             :   int success;
      68             : } expectation;
      69             : 
      70             : /* the verifier itself */
      71             : struct cq_verifier {
      72             :   /* bound completion queue */
      73             :   grpc_completion_queue *cq;
      74             :   /* the root/sentinal expectation */
      75             :   expectation expect;
      76             : };
      77             : 
      78        2867 : cq_verifier *cq_verifier_create(grpc_completion_queue *cq) {
      79        2867 :   cq_verifier *v = gpr_malloc(sizeof(cq_verifier));
      80        2867 :   v->expect.type = ROOT_EXPECTATION;
      81        2867 :   v->expect.tag = NULL;
      82        2867 :   v->expect.next = &v->expect;
      83        2867 :   v->expect.prev = &v->expect;
      84        2867 :   v->cq = cq;
      85        2867 :   return v;
      86             : }
      87             : 
      88        2867 : void cq_verifier_destroy(cq_verifier *v) {
      89        2867 :   cq_verify(v);
      90        2867 :   gpr_free(v);
      91        2867 : }
      92             : 
      93         385 : static int has_metadata(const grpc_metadata *md, size_t count, const char *key,
      94             :                         const char *value) {
      95             :   size_t i;
      96         592 :   for (i = 0; i < count; i++) {
      97         937 :     if (0 == strcmp(key, md[i].key) && strlen(value) == md[i].value_length &&
      98         365 :         0 == memcmp(md[i].value, value, md[i].value_length)) {
      99         365 :       return 1;
     100             :     }
     101             :   }
     102          20 :   return 0;
     103             : }
     104             : 
     105         385 : int contains_metadata(grpc_metadata_array *array, const char *key,
     106             :                       const char *value) {
     107         385 :   return has_metadata(array->metadata, array->count, key, value);
     108             : }
     109             : 
     110         840 : static gpr_slice merge_slices(gpr_slice *slices, size_t nslices) {
     111             :   size_t i;
     112         840 :   size_t len = 0;
     113             :   gpr_uint8 *cursor;
     114             :   gpr_slice out;
     115             : 
     116        2088 :   for (i = 0; i < nslices; i++) {
     117        1248 :     len += GPR_SLICE_LENGTH(slices[i]);
     118             :   }
     119             : 
     120         840 :   out = gpr_slice_malloc(len);
     121         840 :   cursor = GPR_SLICE_START_PTR(out);
     122             : 
     123        2088 :   for (i = 0; i < nslices; i++) {
     124        1248 :     memcpy(cursor, GPR_SLICE_START_PTR(slices[i]), GPR_SLICE_LENGTH(slices[i]));
     125        1248 :     cursor += GPR_SLICE_LENGTH(slices[i]);
     126             :   }
     127             : 
     128         840 :   return out;
     129             : }
     130             : 
     131         840 : static int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b) {
     132             :   gpr_slice a;
     133             :   int ok;
     134             : 
     135         840 :   if (!bb) return 0;
     136             : 
     137         840 :   a = merge_slices(bb->data.raw.slice_buffer.slices,
     138             :                    bb->data.raw.slice_buffer.count);
     139        1680 :   ok = GPR_SLICE_LENGTH(a) == GPR_SLICE_LENGTH(b) &&
     140        1560 :        0 == memcmp(GPR_SLICE_START_PTR(a), GPR_SLICE_START_PTR(b),
     141        1560 :                    GPR_SLICE_LENGTH(a));
     142         840 :   gpr_slice_unref(a);
     143         840 :   gpr_slice_unref(b);
     144         840 :   return ok;
     145             : }
     146             : 
     147         840 : int byte_buffer_eq_string(grpc_byte_buffer *bb, const char *str) {
     148             :   grpc_byte_buffer_reader reader;
     149             :   grpc_byte_buffer *rbb;
     150             :   int res;
     151             : 
     152         840 :   grpc_byte_buffer_reader_init(&reader, bb);
     153         840 :   rbb = grpc_raw_byte_buffer_from_reader(&reader);
     154         840 :   res = byte_buffer_eq_slice(rbb, gpr_slice_from_copied_string(str));
     155         840 :   grpc_byte_buffer_reader_destroy(&reader);
     156         840 :   grpc_byte_buffer_destroy(rbb);
     157             : 
     158         840 :   return res;
     159             : }
     160             : 
     161       11480 : static void verify_matches(expectation *e, grpc_event *ev) {
     162       11480 :   GPR_ASSERT(e->type == ev->type);
     163       11480 :   switch (e->type) {
     164             :     case GRPC_QUEUE_SHUTDOWN:
     165           0 :       gpr_log(GPR_ERROR, "premature queue shutdown");
     166           0 :       abort();
     167             :       break;
     168             :     case GRPC_OP_COMPLETE:
     169       11480 :       GPR_ASSERT(e->success == ev->success);
     170       11480 :       break;
     171             :     case GRPC_QUEUE_TIMEOUT:
     172           0 :       gpr_log(GPR_ERROR, "not implemented");
     173           0 :       abort();
     174             :       break;
     175             :   }
     176       11480 : }
     177             : 
     178           0 : static void expectation_to_strvec(gpr_strvec *buf, expectation *e) {
     179             :   char *tmp;
     180             : 
     181           0 :   gpr_asprintf(&tmp, "%p ", e->tag);
     182           0 :   gpr_strvec_add(buf, tmp);
     183             : 
     184           0 :   switch (e->type) {
     185             :     case GRPC_OP_COMPLETE:
     186           0 :       gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d", e->success);
     187           0 :       gpr_strvec_add(buf, tmp);
     188           0 :       break;
     189             :     case GRPC_QUEUE_TIMEOUT:
     190             :     case GRPC_QUEUE_SHUTDOWN:
     191           0 :       gpr_log(GPR_ERROR, "not implemented");
     192           0 :       abort();
     193             :       break;
     194             :   }
     195           0 : }
     196             : 
     197           0 : static void expectations_to_strvec(gpr_strvec *buf, cq_verifier *v) {
     198             :   expectation *e;
     199             : 
     200           0 :   for (e = v->expect.next; e != &v->expect; e = e->next) {
     201           0 :     expectation_to_strvec(buf, e);
     202           0 :     gpr_strvec_add(buf, gpr_strdup("\n"));
     203             :   }
     204           0 : }
     205             : 
     206           0 : static void fail_no_event_received(cq_verifier *v) {
     207             :   gpr_strvec buf;
     208             :   char *msg;
     209           0 :   gpr_strvec_init(&buf);
     210           0 :   gpr_strvec_add(&buf, gpr_strdup("no event received, but expected:\n"));
     211           0 :   expectations_to_strvec(&buf, v);
     212           0 :   msg = gpr_strvec_flatten(&buf, NULL);
     213           0 :   gpr_log(GPR_ERROR, "%s", msg);
     214           0 :   gpr_strvec_destroy(&buf);
     215           0 :   gpr_free(msg);
     216           0 :   abort();
     217             : }
     218             : 
     219       10482 : void cq_verify(cq_verifier *v) {
     220       10482 :   gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
     221             :   grpc_event ev;
     222             :   expectation *e;
     223             :   char *s;
     224             :   gpr_strvec have_tags;
     225             : 
     226       10482 :   gpr_strvec_init(&have_tags);
     227             : 
     228       10482 :   while (v->expect.next != &v->expect) {
     229       11480 :     ev = grpc_completion_queue_next(v->cq, deadline, NULL);
     230       11480 :     if (ev.type == GRPC_QUEUE_TIMEOUT) {
     231           0 :       fail_no_event_received(v);
     232           0 :       break;
     233             :     }
     234             : 
     235       12523 :     for (e = v->expect.next; e != &v->expect; e = e->next) {
     236       12523 :       gpr_asprintf(&s, " %p", e->tag);
     237       12523 :       gpr_strvec_add(&have_tags, s);
     238       12523 :       if (e->tag == ev.tag) {
     239       11480 :         verify_matches(e, &ev);
     240       11480 :         e->next->prev = e->prev;
     241       11480 :         e->prev->next = e->next;
     242       11480 :         gpr_free(e);
     243       11480 :         break;
     244             :       }
     245             :     }
     246       11480 :     if (e == &v->expect) {
     247           0 :       s = grpc_event_string(&ev);
     248           0 :       gpr_log(GPR_ERROR, "event not found: %s", s);
     249           0 :       gpr_free(s);
     250           0 :       s = gpr_strvec_flatten(&have_tags, NULL);
     251           0 :       gpr_log(GPR_ERROR, "have tags:%s", s);
     252           0 :       gpr_free(s);
     253           0 :       gpr_strvec_destroy(&have_tags);
     254           0 :       abort();
     255             :     }
     256             :   }
     257             : 
     258       10482 :   gpr_strvec_destroy(&have_tags);
     259       10482 : }
     260             : 
     261          23 : void cq_verify_empty(cq_verifier *v) {
     262          23 :   gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
     263             :                                        gpr_time_from_seconds(1, GPR_TIMESPAN));
     264             :   grpc_event ev;
     265             : 
     266          23 :   GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty");
     267             : 
     268          23 :   ev = grpc_completion_queue_next(v->cq, deadline, NULL);
     269          23 :   if (ev.type != GRPC_QUEUE_TIMEOUT) {
     270           0 :     char *s = grpc_event_string(&ev);
     271           0 :     gpr_log(GPR_ERROR, "unexpected event (expected nothing): %s", s);
     272           0 :     gpr_free(s);
     273           0 :     abort();
     274             :   }
     275          23 : }
     276             : 
     277       11480 : static expectation *add(cq_verifier *v, grpc_completion_type type, void *tag) {
     278       11480 :   expectation *e = gpr_malloc(sizeof(expectation));
     279       11480 :   e->type = type;
     280       11480 :   e->tag = tag;
     281       11480 :   e->next = &v->expect;
     282       11480 :   e->prev = e->next->prev;
     283       11480 :   e->next->prev = e->prev->next = e;
     284       11480 :   return e;
     285             : }
     286             : 
     287       11480 : void cq_expect_completion(cq_verifier *v, void *tag, int success) {
     288       11480 :   add(v, GRPC_OP_COMPLETE, tag)->success = success;
     289       11480 : }

Generated by: LCOV version 1.10