/* grpc_rb_call_add_metadata_hash_cb is the hash iteration callback used by grpc_rb_call_add_metadata. */ int grpc_rb_call_add_metadata_hash_cb(VALUE key, VALUE val, VALUE call_obj) { grpc_call *call = NULL; grpc_metadata *md = NULL; VALUE md_obj = Qnil; VALUE md_obj_args[2]; VALUE flags = rb_ivar_get(call_obj, id_flags); grpc_call_error err; int array_length; int i; /* Construct a metadata object from key and value and add it */ Data_Get_Struct(call_obj, grpc_call, call); md_obj_args[0] = key; if (TYPE(val) == T_ARRAY) { /* If the value is an array, add each value in the array separately */ array_length = RARRAY_LEN(val); for (i = 0; i < array_length; i++) { md_obj_args[1] = rb_ary_entry(val, i); md_obj = rb_class_new_instance(2, md_obj_args, rb_cMetadata); md = grpc_rb_get_wrapped_metadata(md_obj); err = grpc_call_add_metadata_old(call, md, NUM2UINT(flags)); if (err != GRPC_CALL_OK) { rb_raise(rb_eCallError, "add metadata failed: %s (code=%d)", grpc_call_error_detail_of(err), err); return ST_STOP; } } } else { md_obj_args[1] = val; md_obj = rb_class_new_instance(2, md_obj_args, rb_cMetadata); md = grpc_rb_get_wrapped_metadata(md_obj); err = grpc_call_add_metadata_old(call, md, NUM2UINT(flags)); if (err != GRPC_CALL_OK) { rb_raise(rb_eCallError, "add metadata failed: %s (code=%d)", grpc_call_error_detail_of(err), err); return ST_STOP; } } return ST_CONTINUE; }
int main(int argc, char **argv) { grpc_channel *chan; grpc_call *call; grpc_metadata md = {"a", "b", 1, {{NULL, NULL, NULL}}}; grpc_completion_queue *cq; cq_verifier *cqv; grpc_test_init(argc, argv); grpc_init(); chan = grpc_lame_client_channel_create(); GPR_ASSERT(chan); call = grpc_channel_create_call_old(chan, "/Foo", "anywhere", GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100)); GPR_ASSERT(call); cq = grpc_completion_queue_create(); cqv = cq_verifier_create(cq); /* we should be able to add metadata */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(call, &md, 0)); /* and invoke the call */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(call, cq, tag(2), tag(3), 0)); /* the call should immediately fail */ cq_expect_client_metadata_read(cqv, tag(2), NULL); cq_expect_finished(cqv, tag(3), NULL); cq_verify(cqv); grpc_call_destroy(call); grpc_channel_destroy(chan); cq_verifier_destroy(cqv); grpc_completion_queue_destroy(cq); grpc_shutdown(); return 0; }
/* Request with a large amount of metadata.*/ static void test_request_with_large_metadata(grpc_end2end_test_config config) { grpc_call *c; grpc_call *s; gpr_timespec deadline = five_seconds_time(); grpc_metadata meta; grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); const int large_size = 64 * 1024; GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); meta.key = "key"; meta.value = gpr_malloc(large_size + 1); memset((char *)meta.value, 'a', large_size); ((char *)meta.value)[large_size] = 0; meta.value_length = large_size; c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); /* add the metadata */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta, 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, "key", meta.value, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_accept_old(s, f.server_cq, tag(102))); GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); /* fetch metadata.. */ cq_expect_client_metadata_read(v_client, tag(2), NULL); cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old(s, GRPC_STATUS_OK, NULL, tag(9))); cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_OK, NULL, NULL); cq_verify(v_client); cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); cq_expect_finished(v_server, tag(102), NULL); cq_verify(v_server); grpc_call_destroy(c); grpc_call_destroy(s); end_test(&f); config.tear_down_data(&f); cq_verifier_destroy(v_client); cq_verifier_destroy(v_server); gpr_free((char *)meta.value); }
/* Request/response with metadata and payload.*/ static void test_request_response_with_metadata_and_payload( grpc_end2end_test_config config) { grpc_call *c; grpc_call *s; gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); grpc_byte_buffer *request_payload = grpc_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer *response_payload = grpc_byte_buffer_create(&response_payload_slice, 1); gpr_timespec deadline = five_seconds_time(); grpc_metadata meta1 = {"key1", "val1", 4}; grpc_metadata meta2 = {"key2", "val2", 4}; grpc_metadata meta3 = {"key3", "val3", 4}; grpc_metadata meta4 = {"key4", "val4", 4}; grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); /* byte buffer holds the slice, we can unref it already */ gpr_slice_unref(request_payload_slice); gpr_slice_unref(response_payload_slice); c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); /* add multiple metadata */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta1, 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta2, 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_old(c, request_payload, tag(4), 0)); /* destroy byte buffer early to ensure async code keeps track of its contents correctly */ grpc_byte_buffer_destroy(request_payload); cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); cq_verify(v_client); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, "key1", "val1", "key2", "val2", NULL); cq_verify(v_server); grpc_call_server_accept_old(s, f.server_cq, tag(102)); /* add multiple metadata */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta3, 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta4, 0)); grpc_call_server_end_initial_metadata_old(s, 0); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(5))); cq_expect_read(v_server, tag(5), gpr_slice_from_copied_string("hello world")); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_old(s, response_payload, tag(6), 0)); /* destroy byte buffer early to ensure async code keeps track of its contents correctly */ grpc_byte_buffer_destroy(response_payload); cq_expect_write_accepted(v_server, tag(6), GRPC_OP_OK); cq_verify(v_server); /* fetch metadata.. */ cq_expect_client_metadata_read(v_client, tag(2), "key3", "val3", "key4", "val4", NULL); cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(c, tag(7))); cq_expect_read(v_client, tag(7), gpr_slice_from_copied_string("hello you")); cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(9))); cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL); cq_verify(v_client); cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); cq_expect_finished(v_server, tag(102), NULL); cq_verify(v_server); grpc_call_destroy(c); grpc_call_destroy(s); end_test(&f); config.tear_down_data(&f); cq_verifier_destroy(v_client); cq_verifier_destroy(v_server); }