static void test_similar(void) { GPR_ASSERT(1 == gpr_time_similar(gpr_inf_future(GPR_TIMESPAN), gpr_inf_future(GPR_TIMESPAN), gpr_time_0(GPR_TIMESPAN))); GPR_ASSERT(1 == gpr_time_similar(gpr_inf_past(GPR_TIMESPAN), gpr_inf_past(GPR_TIMESPAN), gpr_time_0(GPR_TIMESPAN))); GPR_ASSERT(0 == gpr_time_similar(gpr_inf_past(GPR_TIMESPAN), gpr_inf_future(GPR_TIMESPAN), gpr_time_0(GPR_TIMESPAN))); GPR_ASSERT(0 == gpr_time_similar(gpr_inf_future(GPR_TIMESPAN), gpr_inf_past(GPR_TIMESPAN), gpr_time_0(GPR_TIMESPAN))); GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(10, GPR_TIMESPAN), gpr_time_from_micros(10, GPR_TIMESPAN), gpr_time_0(GPR_TIMESPAN))); GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(10, GPR_TIMESPAN), gpr_time_from_micros(15, GPR_TIMESPAN), gpr_time_from_micros(10, GPR_TIMESPAN))); GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(15, GPR_TIMESPAN), gpr_time_from_micros(10, GPR_TIMESPAN), gpr_time_from_micros(10, GPR_TIMESPAN))); GPR_ASSERT(0 == gpr_time_similar(gpr_time_from_micros(10, GPR_TIMESPAN), gpr_time_from_micros(25, GPR_TIMESPAN), gpr_time_from_micros(10, GPR_TIMESPAN))); GPR_ASSERT(0 == gpr_time_similar(gpr_time_from_micros(25, GPR_TIMESPAN), gpr_time_from_micros(10, GPR_TIMESPAN), gpr_time_from_micros(10, GPR_TIMESPAN))); }
static void actually_poll(void *argsp) { args_struct *args = argsp; gpr_timespec deadline = n_sec_deadline(10); while (true) { bool done = gpr_atm_acq_load(&args->done_atm) != 0; if (done) { break; } gpr_timespec time_left = gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)); gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done, time_left.tv_sec, time_left.tv_nsec); GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0); grpc_pollset_worker *worker = NULL; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_mu_lock(args->mu); GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, args->pollset, &worker, gpr_now(GPR_CLOCK_REALTIME), n_sec_deadline(1))); gpr_mu_unlock(args->mu); grpc_exec_ctx_finish(&exec_ctx); } gpr_event_set(&args->ev, (void *)1); }
/* Adds a module with constants that map to gpr's static timeval structs. */ static void Init_grpc_time_consts() { VALUE grpc_rb_mTimeConsts = rb_define_module_under(grpc_rb_mGrpcCore, "TimeConsts"); grpc_rb_cTimeVal = rb_define_class_under(grpc_rb_mGrpcCore, "TimeSpec", rb_cObject); zero_realtime = gpr_time_0(GPR_CLOCK_REALTIME); inf_future_realtime = gpr_inf_future(GPR_CLOCK_REALTIME); inf_past_realtime = gpr_inf_past(GPR_CLOCK_REALTIME); rb_define_const( grpc_rb_mTimeConsts, "ZERO", TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type, (void *)&zero_realtime)); rb_define_const( grpc_rb_mTimeConsts, "INFINITE_FUTURE", TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type, (void *)&inf_future_realtime)); rb_define_const( grpc_rb_mTimeConsts, "INFINITE_PAST", TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type, (void *)&inf_past_realtime)); rb_define_method(grpc_rb_cTimeVal, "to_time", grpc_rb_time_val_to_time, 0); rb_define_method(grpc_rb_cTimeVal, "inspect", grpc_rb_time_val_inspect, 0); rb_define_method(grpc_rb_cTimeVal, "to_s", grpc_rb_time_val_to_s, 0); id_at = rb_intern("at"); id_inspect = rb_intern("inspect"); id_to_s = rb_intern("to_s"); id_tv_sec = rb_intern("tv_sec"); id_tv_nsec = rb_intern("tv_nsec"); }
static void test_sticky_infinities(void) { int i; int j; int k; gpr_timespec infinity[2]; gpr_timespec addend[3]; infinity[0] = gpr_inf_future(GPR_TIMESPAN); infinity[1] = gpr_inf_past(GPR_TIMESPAN); addend[0] = gpr_inf_future(GPR_TIMESPAN); addend[1] = gpr_inf_past(GPR_TIMESPAN); addend[2] = gpr_time_0(GPR_TIMESPAN); /* Infinities are sticky */ for (i = 0; i != sizeof(infinity) / sizeof(infinity[0]); i++) { for (j = 0; j != sizeof(addend) / sizeof(addend[0]); j++) { gpr_timespec x = gpr_time_add(infinity[i], addend[j]); GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0); x = gpr_time_sub(infinity[i], addend[j]); GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0); } for (k = -200; k <= 200; k++) { gpr_timespec y = gpr_time_from_micros(k * 100000, GPR_TIMESPAN); gpr_timespec x = gpr_time_add(infinity[i], y); GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0); x = gpr_time_sub(infinity[i], y); GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0); } } }
static void test_values(void) { int i; gpr_timespec x = gpr_time_0(GPR_CLOCK_REALTIME); GPR_ASSERT(x.tv_sec == 0 && x.tv_nsec == 0); x = gpr_inf_future(GPR_CLOCK_REALTIME); fprintf(stderr, "far future "); i_to_s(x.tv_sec, 16, 16, &to_fp, stderr); fprintf(stderr, "\n"); GPR_ASSERT(x.tv_sec == INT64_MAX); fprintf(stderr, "far future "); ts_to_s(x, &to_fp, stderr); fprintf(stderr, "\n"); x = gpr_inf_past(GPR_CLOCK_REALTIME); fprintf(stderr, "far past "); i_to_s(x.tv_sec, 16, 16, &to_fp, stderr); fprintf(stderr, "\n"); GPR_ASSERT(x.tv_sec == INT64_MIN); fprintf(stderr, "far past "); ts_to_s(x, &to_fp, stderr); fprintf(stderr, "\n"); for (i = 1; i != 1000 * 1000 * 1000; i *= 10) { x = gpr_time_from_micros(i, GPR_TIMESPAN); GPR_ASSERT(x.tv_sec == i / GPR_US_PER_SEC && x.tv_nsec == (i % GPR_US_PER_SEC) * GPR_NS_PER_US); x = gpr_time_from_nanos(i, GPR_TIMESPAN); GPR_ASSERT(x.tv_sec == i / GPR_NS_PER_SEC && x.tv_nsec == (i % GPR_NS_PER_SEC)); x = gpr_time_from_millis(i, GPR_TIMESPAN); GPR_ASSERT(x.tv_sec == i / GPR_MS_PER_SEC && x.tv_nsec == (i % GPR_MS_PER_SEC) * GPR_NS_PER_MS); } /* Test possible overflow in conversion of -ve values. */ x = gpr_time_from_micros(-(LONG_MAX - 999997), GPR_TIMESPAN); GPR_ASSERT(x.tv_sec < 0); GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC); x = gpr_time_from_nanos(-(LONG_MAX - 999999997), GPR_TIMESPAN); GPR_ASSERT(x.tv_sec < 0); GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC); x = gpr_time_from_millis(-(LONG_MAX - 997), GPR_TIMESPAN); GPR_ASSERT(x.tv_sec < 0); GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC); /* Test general -ve values. */ for (i = -1; i > -1000 * 1000 * 1000; i *= 7) { x = gpr_time_from_micros(i, GPR_TIMESPAN); GPR_ASSERT(x.tv_sec * GPR_US_PER_SEC + x.tv_nsec / GPR_NS_PER_US == i); x = gpr_time_from_nanos(i, GPR_TIMESPAN); GPR_ASSERT(x.tv_sec * GPR_NS_PER_SEC + x.tv_nsec == i); x = gpr_time_from_millis(i, GPR_TIMESPAN); GPR_ASSERT(x.tv_sec * GPR_MS_PER_SEC + x.tv_nsec / GPR_NS_PER_MS == i); } }
static void write_log(gpr_timer_log *log) { size_t i; if (output_file == NULL) { output_file = fopen(output_filename(), "w"); } for (i = 0; i < log->num_entries; i++) { gpr_timer_entry *entry = &(log->log[i]); if (gpr_time_cmp(entry->tm, gpr_time_0(entry->tm.clock_type)) < 0) { entry->tm = gpr_time_0(entry->tm.clock_type); } fprintf(output_file, "{\"t\": %" PRId64 ".%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": " "\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n", entry->tm.tv_sec, entry->tm.tv_nsec, entry->thd, entry->type, entry->tagstr, entry->file, entry->line, entry->important); } }
/* Takes ownership of json and buffer even in case of failure. */ grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer) { grpc_json *cur; grpc_jwt_claims *claims = gpr_malloc(sizeof(grpc_jwt_claims)); memset(claims, 0, sizeof(grpc_jwt_claims)); claims->json = json; claims->buffer = buffer; claims->iat = gpr_inf_past(GPR_CLOCK_REALTIME); claims->nbf = gpr_inf_past(GPR_CLOCK_REALTIME); claims->exp = gpr_inf_future(GPR_CLOCK_REALTIME); /* Per the spec, all fields are optional. */ for (cur = json->child; cur != NULL; cur = cur->next) { if (strcmp(cur->key, "sub") == 0) { claims->sub = validate_string_field(cur, "sub"); if (claims->sub == NULL) goto error; } else if (strcmp(cur->key, "iss") == 0) { claims->iss = validate_string_field(cur, "iss"); if (claims->iss == NULL) goto error; } else if (strcmp(cur->key, "aud") == 0) { claims->aud = validate_string_field(cur, "aud"); if (claims->aud == NULL) goto error; } else if (strcmp(cur->key, "jti") == 0) { claims->jti = validate_string_field(cur, "jti"); if (claims->jti == NULL) goto error; } else if (strcmp(cur->key, "iat") == 0) { claims->iat = validate_time_field(cur, "iat"); if (gpr_time_cmp(claims->iat, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) goto error; } else if (strcmp(cur->key, "exp") == 0) { claims->exp = validate_time_field(cur, "exp"); if (gpr_time_cmp(claims->exp, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) goto error; } else if (strcmp(cur->key, "nbf") == 0) { claims->nbf = validate_time_field(cur, "nbf"); if (gpr_time_cmp(claims->nbf, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) goto error; } } return claims; error: grpc_jwt_claims_destroy(claims); return NULL; }
static gpr_timespec validate_time_field(const grpc_json *json, const char *key) { gpr_timespec result = gpr_time_0(GPR_CLOCK_REALTIME); if (json->type != GRPC_JSON_NUMBER) { gpr_log(GPR_ERROR, "Invalid %s field [%s]", key, json->value); return result; } result.tv_sec = strtol(json->value, NULL, 10); return result; }
/* Cleaning up a list with pending alarms. */ void destruction_test(void) { grpc_alarm alarms[5]; grpc_alarm_list_init(gpr_time_0(GPR_CLOCK_REALTIME)); memset(cb_called, 0, sizeof(cb_called)); grpc_alarm_init(&alarms[0], tfm(100), cb, (void *)(gpr_intptr)0, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_alarm_init(&alarms[1], tfm(3), cb, (void *)(gpr_intptr)1, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_alarm_init(&alarms[2], tfm(100), cb, (void *)(gpr_intptr)2, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_alarm_init(&alarms[3], tfm(3), cb, (void *)(gpr_intptr)3, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_alarm_init(&alarms[4], tfm(1), cb, (void *)(gpr_intptr)4, gpr_time_0(GPR_CLOCK_REALTIME)); GPR_ASSERT(1 == grpc_alarm_check(NULL, tfm(2), NULL)); GPR_ASSERT(1 == cb_called[4][1]); grpc_alarm_cancel(&alarms[0]); grpc_alarm_cancel(&alarms[3]); GPR_ASSERT(1 == cb_called[0][0]); GPR_ASSERT(1 == cb_called[3][0]); grpc_alarm_list_shutdown(); GPR_ASSERT(1 == cb_called[1][0]); GPR_ASSERT(1 == cb_called[2][0]); }
/* Cleaning up a list with pending timers. */ void destruction_test(void) { grpc_timer timers[5]; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_timer_list_init(gpr_time_0(GPR_CLOCK_REALTIME)); memset(cb_called, 0, sizeof(cb_called)); grpc_timer_init(&exec_ctx, &timers[0], tfm(100), cb, (void *)(intptr_t)0, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_timer_init(&exec_ctx, &timers[1], tfm(3), cb, (void *)(intptr_t)1, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_timer_init(&exec_ctx, &timers[2], tfm(100), cb, (void *)(intptr_t)2, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_timer_init(&exec_ctx, &timers[3], tfm(3), cb, (void *)(intptr_t)3, gpr_time_0(GPR_CLOCK_REALTIME)); grpc_timer_init(&exec_ctx, &timers[4], tfm(1), cb, (void *)(intptr_t)4, gpr_time_0(GPR_CLOCK_REALTIME)); GPR_ASSERT(1 == grpc_timer_check(&exec_ctx, tfm(2), NULL)); grpc_exec_ctx_finish(&exec_ctx); GPR_ASSERT(1 == cb_called[4][1]); grpc_timer_cancel(&exec_ctx, &timers[0]); grpc_timer_cancel(&exec_ctx, &timers[3]); grpc_exec_ctx_finish(&exec_ctx); GPR_ASSERT(1 == cb_called[0][0]); GPR_ASSERT(1 == cb_called[3][0]); grpc_timer_list_shutdown(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx); GPR_ASSERT(1 == cb_called[1][0]); GPR_ASSERT(1 == cb_called[2][0]); }
static void test_constant_backoff(void) { gpr_backoff backoff; gpr_backoff_init(&backoff, 1.0, 0.0, 1000, 1000); gpr_timespec now = gpr_time_0(GPR_TIMESPAN); gpr_timespec next = gpr_backoff_begin(&backoff, now); GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 1000); for (int i = 0; i < 10000; i++) { next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 1000); now = next; } }
static void *method_config_convert_value( const grpc_method_config *method_config) { method_parameters *value = gpr_malloc(sizeof(method_parameters)); const gpr_timespec *timeout = grpc_method_config_get_timeout(method_config); value->timeout = timeout != NULL ? *timeout : gpr_time_0(GPR_TIMESPAN); const bool *wait_for_ready = grpc_method_config_get_wait_for_ready(method_config); value->wait_for_ready = wait_for_ready == NULL ? WAIT_FOR_READY_UNSET : (wait_for_ready ? WAIT_FOR_READY_TRUE : WAIT_FOR_READY_FALSE); return value; }
static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { dns_resolver *r = arg; grpc_channel_args *result = NULL; gpr_mu_lock(&r->mu); GPR_ASSERT(r->resolving); r->resolving = false; if (r->addresses != NULL) { grpc_lb_addresses *addresses = grpc_lb_addresses_create( r->addresses->naddrs, NULL /* user_data_vtable */); for (size_t i = 0; i < r->addresses->naddrs; ++i) { grpc_lb_addresses_set_address( addresses, i, &r->addresses->addrs[i].addr, r->addresses->addrs[i].len, false /* is_balancer */, NULL /* balancer_name */, NULL /* user_data */); } grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses); result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1); grpc_resolved_addresses_destroy(r->addresses); grpc_lb_addresses_destroy(addresses); } else { gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now); gpr_timespec timeout = gpr_time_sub(next_try, now); const char *msg = grpc_error_string(error); gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg); grpc_error_free_string(msg); GPR_ASSERT(!r->have_retry_timer); r->have_retry_timer = true; GRPC_RESOLVER_REF(&r->base, "retry-timer"); if (gpr_time_cmp(timeout, gpr_time_0(timeout.clock_type)) > 0) { gpr_log(GPR_DEBUG, "retrying in %" PRId64 ".%09d seconds", timeout.tv_sec, timeout.tv_nsec); } else { gpr_log(GPR_DEBUG, "retrying immediately"); } grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r, now); } if (r->resolved_result != NULL) { grpc_channel_args_destroy(r->resolved_result); } r->resolved_result = result; r->resolved_version++; dns_maybe_finish_next_locked(exec_ctx, r); gpr_mu_unlock(&r->mu); GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving"); }
// Gets data from the service config. Invoked when the resolver returns // its initial result. static void read_service_config(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_call_element *elem = arg; channel_data *chand = elem->channel_data; call_data *calld = elem->call_data; // If this is an error, there's no point in looking at the service config. if (error == GRPC_ERROR_NONE) { // Get the method config table from channel data. gpr_mu_lock(&chand->mu); grpc_mdstr_hash_table *method_params_table = NULL; if (chand->method_params_table != NULL) { method_params_table = grpc_mdstr_hash_table_ref(chand->method_params_table); } gpr_mu_unlock(&chand->mu); // If the method config table was present, use it. if (method_params_table != NULL) { const method_parameters *method_params = grpc_method_config_table_get(method_params_table, calld->path); if (method_params != NULL) { const bool have_method_timeout = gpr_time_cmp(method_params->timeout, gpr_time_0(GPR_TIMESPAN)) != 0; if (have_method_timeout || method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { gpr_mu_lock(&calld->mu); if (have_method_timeout) { const gpr_timespec per_method_deadline = gpr_time_add(calld->call_start_time, method_params->timeout); if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) { calld->deadline = per_method_deadline; // Reset deadline timer. grpc_deadline_state_reset(exec_ctx, elem, calld->deadline); } } if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { calld->wait_for_ready_from_service_config = method_params->wait_for_ready; } gpr_mu_unlock(&calld->mu); } } grpc_mdstr_hash_table_unref(method_params_table); } } GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config"); }
static void actually_poll_server(void *arg) { poll_args *pa = arg; gpr_timespec deadline = n_sec_deadline(10); while (true) { bool done = gpr_atm_acq_load(&state.done_atm) != 0; gpr_timespec time_left = gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)); gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done, time_left.tv_sec, time_left.tv_nsec); if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) { break; } test_tcp_server_poll(pa->server, 1); } gpr_event_set(pa->signal_when_done, (void *)1); gpr_free(pa); }
static void test_no_jitter_backoff(void) { gpr_backoff backoff; gpr_backoff_init(&backoff, 2.0, 0.0, 1, 513); gpr_timespec now = gpr_time_0(GPR_TIMESPAN); gpr_timespec next = gpr_backoff_begin(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(3, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(7, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(15, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(31, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(63, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(127, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(255, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(511, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1023, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1536, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2049, GPR_TIMESPAN), next) == 0); now = next; next = gpr_backoff_step(&backoff, now); GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2562, GPR_TIMESPAN), next) == 0); }
// Simple request via a server filter that saves the reported latency value. static void test_request(grpc_end2end_test_config config) { grpc_call *c; grpc_call *s; grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world"); grpc_byte_buffer *request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_end2end_test_fixture f = begin_test(config, "filter_latency", NULL, NULL); cq_verifier *cqv = cq_verifier_create(f.cq); grpc_op ops[6]; grpc_op *op; grpc_metadata_array initial_metadata_recv; grpc_metadata_array trailing_metadata_recv; grpc_metadata_array request_metadata_recv; grpc_byte_buffer *request_payload_recv = NULL; grpc_call_details call_details; grpc_status_code status; grpc_call_error error; grpc_slice details; int was_cancelled = 2; gpr_mu_lock(&g_mu); g_client_latency = gpr_time_0(GPR_TIMESPAN); g_server_latency = gpr_time_0(GPR_TIMESPAN); gpr_mu_unlock(&g_mu); const gpr_timespec start_time = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec deadline = five_seconds_from_now(); c = grpc_channel_create_call( f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, grpc_slice_from_static_string("/foo"), get_host_override_slice("foo.test.google.fr", config), deadline, NULL); GPR_ASSERT(c); 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); memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op->data.send_initial_metadata.metadata = NULL; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message.send_message = request_payload; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_RECV_INITIAL_METADATA; op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; op->flags = 0; op->reserved = NULL; op++; 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->flags = 0; op->reserved = NULL; op++; error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; op->data.send_status_from_server.trailing_metadata_count = 0; op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; grpc_slice status_string = grpc_slice_from_static_string("xyz"); op->data.send_status_from_server.status_details = &status_string; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; op->data.recv_close_on_server.cancelled = &was_cancelled; op->flags = 0; op->reserved = NULL; op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); grpc_slice_unref(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_call_unref(s); grpc_call_unref(c); cq_verifier_destroy(cqv); grpc_byte_buffer_destroy(request_payload); grpc_byte_buffer_destroy(request_payload_recv); end_test(&f); config.tear_down_data(&f); const gpr_timespec end_time = gpr_now(GPR_CLOCK_MONOTONIC); const gpr_timespec max_latency = gpr_time_sub(end_time, start_time); // Perform checks after test tear-down // Guards against the case that there's outstanding channel-related work on a // call prior to verification gpr_mu_lock(&g_mu); GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0); GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) <= 0); GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0); GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) <= 0); // Server latency should always be smaller than client latency, however since // we only calculate latency at destruction time, and that might mean that we // need to wait for outstanding channel-related work, this isn't verifiable // right now (the server MAY hold on to the call for longer than the client). // GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0); gpr_mu_unlock(&g_mu); }
/* Constructor for call_data */ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { channel_data *chand = elem->channel_data; call_data *calld = elem->call_data; // Initialize data members. grpc_deadline_state_init(exec_ctx, elem, args->call_stack); calld->path = GRPC_MDSTR_REF(args->path); calld->call_start_time = args->start_time; calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC); calld->wait_for_ready_from_service_config = WAIT_FOR_READY_UNSET; calld->cancel_error = GRPC_ERROR_NONE; gpr_atm_rel_store(&calld->subchannel_call, 0); gpr_mu_init(&calld->mu); calld->connected_subchannel = NULL; calld->waiting_ops = NULL; calld->waiting_ops_count = 0; calld->waiting_ops_capacity = 0; calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; calld->owning_call = args->call_stack; calld->pollent = NULL; // If the resolver has already returned results, then we can access // the service config parameters immediately. Otherwise, we need to // defer that work until the resolver returns an initial result. // TODO(roth): This code is almost but not quite identical to the code // in read_service_config() above. It would be nice to find a way to // combine them, to avoid having to maintain it twice. gpr_mu_lock(&chand->mu); if (chand->lb_policy != NULL) { // We already have a resolver result, so check for service config. if (chand->method_params_table != NULL) { grpc_mdstr_hash_table *method_params_table = grpc_mdstr_hash_table_ref(chand->method_params_table); gpr_mu_unlock(&chand->mu); method_parameters *method_params = grpc_method_config_table_get(method_params_table, args->path); if (method_params != NULL) { if (gpr_time_cmp(method_params->timeout, gpr_time_0(GPR_CLOCK_MONOTONIC)) != 0) { gpr_timespec per_method_deadline = gpr_time_add(calld->call_start_time, method_params->timeout); calld->deadline = gpr_time_min(calld->deadline, per_method_deadline); } if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { calld->wait_for_ready_from_service_config = method_params->wait_for_ready; } } grpc_mdstr_hash_table_unref(method_params_table); } else { gpr_mu_unlock(&chand->mu); } } else { // We don't yet have a resolver result, so register a callback to // get the service config data once the resolver returns. // Take a reference to the call stack to be owned by the callback. GRPC_CALL_STACK_REF(calld->owning_call, "read_service_config"); grpc_closure_init(&calld->read_service_config, read_service_config, elem); grpc_closure_list_append(&chand->waiting_for_config_closures, &calld->read_service_config, GRPC_ERROR_NONE); gpr_mu_unlock(&chand->mu); } // Start the deadline timer with the current deadline value. If we // do not yet have service config data, then the timer may be reset // later. grpc_deadline_state_start(exec_ctx, elem, calld->deadline); return GRPC_ERROR_NONE; }
static void check_jwt_claim(grpc_json *claim, const char *expected_audience, const char *expected_scope) { gpr_timespec expiration = gpr_time_0(GPR_CLOCK_REALTIME); gpr_timespec issue_time = gpr_time_0(GPR_CLOCK_REALTIME); gpr_timespec parsed_lifetime; grpc_json *iss = NULL; grpc_json *scope = NULL; grpc_json *aud = NULL; grpc_json *exp = NULL; grpc_json *iat = NULL; grpc_json *sub = NULL; grpc_json *ptr; for (ptr = claim->child; ptr; ptr = ptr->next) { if (strcmp(ptr->key, "iss") == 0) { iss = ptr; } else if (strcmp(ptr->key, "sub") == 0) { sub = ptr; } else if (strcmp(ptr->key, "scope") == 0) { scope = ptr; } else if (strcmp(ptr->key, "aud") == 0) { aud = ptr; } else if (strcmp(ptr->key, "exp") == 0) { exp = ptr; } else if (strcmp(ptr->key, "iat") == 0) { iat = ptr; } } GPR_ASSERT(iss != NULL); GPR_ASSERT(iss->type == GRPC_JSON_STRING); GPR_ASSERT( strcmp( iss->value, "*****@*****.**") == 0); if (expected_scope != NULL) { GPR_ASSERT(scope != NULL); GPR_ASSERT(sub == NULL); GPR_ASSERT(scope->type == GRPC_JSON_STRING); GPR_ASSERT(strcmp(scope->value, expected_scope) == 0); } else { /* Claims without scope must have a sub. */ GPR_ASSERT(scope == NULL); GPR_ASSERT(sub != NULL); GPR_ASSERT(sub->type == GRPC_JSON_STRING); GPR_ASSERT(strcmp(iss->value, sub->value) == 0); } GPR_ASSERT(aud != NULL); GPR_ASSERT(aud->type == GRPC_JSON_STRING); GPR_ASSERT(strcmp(aud->value, expected_audience) == 0); GPR_ASSERT(exp != NULL); GPR_ASSERT(exp->type == GRPC_JSON_NUMBER); expiration.tv_sec = strtol(exp->value, NULL, 10); GPR_ASSERT(iat != NULL); GPR_ASSERT(iat->type == GRPC_JSON_NUMBER); issue_time.tv_sec = strtol(iat->value, NULL, 10); parsed_lifetime = gpr_time_sub(expiration, issue_time); GPR_ASSERT(parsed_lifetime.tv_sec == grpc_max_auth_token_lifetime().tv_sec); }
/** * Returns the zero time interval as a timeval object * @return Timeval Zero length time interval */ PHP_METHOD(Timeval, zero) { grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME), return_value); RETURN_ZVAL(return_value, false, /* Copy original before returning? */ true /* Destroy original before returning */); }