Converted some cancellation tests

pull/381/head
Craig Tiller 10 years ago
parent aa2ac59b5c
commit fee91b49ff
  1. 1
      src/core/surface/byte_buffer.c
  2. 70
      test/core/end2end/tests/cancel_after_invoke.c
  3. 69
      test/core/end2end/tests/cancel_before_invoke.c
  4. 2
      test/core/end2end/tests/cancel_in_a_vacuum.c
  5. 2
      test/core/end2end/tests/cancel_test_helpers.h
  6. 191
      test/core/end2end/tests/generate.py

@ -61,6 +61,7 @@ grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) {
}
void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) {
if (!bb) return;
switch (bb->type) {
case GRPC_BB_SLICE_BUFFER:
gpr_slice_buffer_destroy(&bb->data.slice_buffer);

@ -105,26 +105,74 @@ static void end_test(grpc_end2end_test_fixture *f) {
/* Cancel after invoke, no payload */
static void test_cancel_after_invoke(grpc_end2end_test_config config,
cancellation_mode mode) {
cancellation_mode mode, int test_ops) {
grpc_op ops[6];
grpc_op *op;
grpc_call *c;
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
gpr_timespec deadline = five_seconds_time();
cq_verifier *v_client = cq_verifier_create(f.client_cq);
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
grpc_byte_buffer *response_payload_recv = NULL;
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
grpc_byte_buffer *request_payload =
grpc_byte_buffer_create(&request_payload_slice, 1);
c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
deadline);
GPR_ASSERT(c);
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = request_payload;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &response_payload_recv;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, test_ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));
cq_expect_client_metadata_read(v_client, tag(2), NULL);
cq_expect_finished_with_status(v_client, tag(3), mode.expect_status,
mode.expect_details, NULL);
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_verify(v_client);
GPR_ASSERT(status == mode.expect_status);
GPR_ASSERT(0 == strcmp(details, mode.expect_details));
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload_recv);
gpr_free(details);
grpc_call_destroy(c);
cq_verifier_destroy(v_client);
@ -133,9 +181,11 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
}
void grpc_end2end_tests(grpc_end2end_test_config config) {
unsigned i;
unsigned i, j;
for (j = 1; j < 6; j++) {
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
test_cancel_after_invoke(config, cancellation_modes[i]);
test_cancel_after_invoke(config, cancellation_modes[i], j);
}
}
}

@ -103,25 +103,73 @@ static void end_test(grpc_end2end_test_fixture *f) {
}
/* Cancel before invoke */
static void test_cancel_before_invoke(grpc_end2end_test_config config) {
static void test_cancel_before_invoke(grpc_end2end_test_config config, int test_ops) {
grpc_op ops[6];
grpc_op *op;
grpc_call *c;
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
gpr_timespec deadline = five_seconds_time();
cq_verifier *v_client = cq_verifier_create(f.client_cq);
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
grpc_byte_buffer *response_payload_recv = NULL;
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
grpc_byte_buffer *request_payload =
grpc_byte_buffer_create(&request_payload_slice, 1);
c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
deadline);
GPR_ASSERT(c);
GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c));
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
cq_expect_client_metadata_read(v_client, tag(2), NULL);
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_CANCELLED, NULL,
NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = request_payload;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &response_payload_recv;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, test_ops, tag(1)));
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_verify(v_client);
GPR_ASSERT(status == GRPC_STATUS_CANCELLED);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload_recv);
gpr_free(details);
grpc_call_destroy(c);
cq_verifier_destroy(v_client);
@ -130,5 +178,8 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config) {
}
void grpc_end2end_tests(grpc_end2end_test_config config) {
test_cancel_before_invoke(config);
int i;
for (i = 1; i <= 6; i++) {
test_cancel_before_invoke(config, i);
}
}

@ -109,7 +109,7 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
gpr_timespec deadline = five_seconds_time();
cq_verifier *v_client = cq_verifier_create(f.client_cq);
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
deadline);
GPR_ASSERT(c);

@ -45,7 +45,7 @@ static grpc_call_error wait_for_deadline(grpc_call *call) {
}
static const cancellation_mode cancellation_modes[] = {
{grpc_call_cancel, GRPC_STATUS_CANCELLED, NULL},
{grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
{wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"}, };
#endif

@ -0,0 +1,191 @@
#!/usr/bin/python2.7
from copy import deepcopy
def create(state, name):
me = getattr(state, name)
if not me.created:
new = me.copy()
new.created = True
cg = state.codegen.copy()
cg.lines.extend([
'config.init_%s(f, %s_args)' % (name, name)])
s = State(state.client, state.server, cg)
setattr(s, name, new)
yield s
def start_client(state):
if state.client.created and not state.client.started:
cg = state.codegen.copy()
cg.lines.extend([
'client_call = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com", deadline);'
])
client = state.client.copy()
client.started = True
yield State(client, state.server, cg)
def request_server(state):
if state.server.created and not state.server.requested:
cg = state.codegen.copy()
tag = cg.make_tag('request_server')
cg.lines.extend([
'GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &server_call, &call_details, &request_metadata_recv, f.server_cq, tag(%d)))' % tag])
server = state.server.copy()
server.requested = True
yield State(state.client, server, cg)
def start_op(state, l, r):
local = getattr(state, l)
remote = getattr(state, r)
if not local.started:
return
for send_initial_metadata in [True, False]:
for send_message in [True, False]:
for send_close in [True, False]:
for receive_initial_metadata in [True, False]:
for receive_message in [True, False]:
for receive_close in [True, False]:
if ((not send_initial_metadata) and (not send_message) and (not send_close) and
(not receive_initial_metadata) and (not receive_message) and (not receive_close)):
continue
if local.sending_initial_metadata and send_initial_metadata: continue
if local.sending_message and send_message: continue
if local.sending_close and send_close: continue
if l == 'server' and receive_initial_metadata: continue
if local.receiving_initial_metadata and receive_initial_metadata: continue
if local.receiving_message and receive_message: continue
if local.receiving_close and receive_close: continue
local2 = local.copy()
cg = state.codegen.copy()
cg.lines.extend(['op = ops']);
tag = cg.make_tag('start_op_%s' % l)
if send_initial_metadata:
cg.lines.extend([
'op->type = GRPC_OP_SEND_INITIAL_METADATA;',
'op->data.send_initial_metadata.count = 0;',
'op++;'])
local2.sending_initial_metadata = tag
if send_message:
cg.lines.extend([
'op->type = GRPC_OP_SEND_MESSAGE;',
'op->data.send_message = %s_payload;' % l,
'op++;'])
local2.sending_message = tag
if send_close:
if l == 'client':
cg.lines.extend([
'op->type = GRPC_OP_SEND_CLOSE_FROM_CLIENT;',
'op++'])
else:
cg.lines.extend([
'op->type = GRPC_OP_SEND_STATUS_FROM_SERVER;',
'op++'])
local2.sending_close = tag
if receive_initial_metadata:
cg.lines.extend([
'op->type = GRPC_OP_RECV_INITIAL_METADATA;',
'op++'])
local2.receiving_initial_metadata = tag
if receive_message:
cg.lines.extend([
'op->type = GRPC_OP_RECV_MESSAGE;',
'op++'])
local2.receiving_message = tag
if receive_close:
if l == 'client':
cg.lines.extend([
'op->type = GRPC_OP_RECV_STATUS_ON_CLIENT;',
'op++'])
else:
cg.lines.extend([
'op->type = GRPC_OP_RECV_CLOSE_ON_SERVER;',
'op++'])
local2.receiving_close = tag
cg.lines.extend([
'GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(%s_call, ops, op - ops, tag(%d)));' % (l, tag)])
s = State(state.client, state.server, cg)
setattr(s, l, local2)
yield s
def wrap(f, *a):
def g(state):
for x in f(state, *a):
yield x
return g
MUTATORS = [
wrap(create, 'client'),
wrap(create, 'server'),
wrap(start_op, 'client', 'server'),
wrap(start_op, 'server', 'client'),
start_client,
request_server,
]
class Codegen(object):
lines = []
next_tag = 1
last_tag_creator = 'nobody'
def generate(self):
print '{'
print '\n'.join(self.lines)
print '}'
def copy(self):
cg = deepcopy(self)
cg.lines = self.lines[:]
return cg
def make_tag(self, name):
self.last_tag_creator = name
tag = self.next_tag
self.next_tag += 1
return tag
class Endpoint(object):
created = False
started = False
requested = False
sent_initial_metadata = False
sent_messages = 0
sent_close = False
sending_initial_metadata = False
sending_message = False
sending_close = False
received_initial_metadata = False
received_messages = 0
received_close = False
receiving_initial_metadata = False
receiving_message = False
receiving_close = False
def copy(self):
return deepcopy(self)
class State(object):
def __init__(self, client, server, codegen):
self.client = client
self.server = server
self.codegen = codegen
def as_dict(self):
return {'client': self.client.as_dict(), 'server': self.server.as_dict()}
def mutations(self):
for mutator in MUTATORS:
for new_state in mutator(self):
yield new_state
count = 0
def generate(state, depth):
global count
n = 0
#print ' '*depth, state.as_dict()
for state2 in state.mutations():
n += 1
generate(state2, depth+1)
if n == 0:
count += 1
#state.codegen.generate()
generate(State(Endpoint(), Endpoint(), Codegen()), 0)
print count
Loading…
Cancel
Save