int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  struct grpc_memory_counters counters;
  grpc_memory_counters_init();
  grpc_slice input = grpc_slice_from_copied_buffer((const char *)data, size);
  grpc_slice output;
  if (grpc_strict_percent_decode_slice(
          input, grpc_url_percent_encoding_unreserved_bytes, &output)) {
    grpc_slice_unref(output);
  }
  if (grpc_strict_percent_decode_slice(
          input, grpc_compatible_percent_encoding_unreserved_bytes, &output)) {
    grpc_slice_unref(output);
  }
  grpc_slice_unref(grpc_permissive_percent_decode_slice(input));
  grpc_slice_unref(input);
  counters = grpc_memory_counters_snapshot();
  grpc_memory_counters_destroy();
  GPR_ASSERT(counters.total_size_relative == 0);
  return 0;
}
Exemple #2
0
static void test(const uint8_t *data, size_t size, const uint8_t *dict) {
  struct grpc_memory_counters counters;
  grpc_memory_counters_init();
  gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size);
  gpr_slice output = gpr_percent_encode_slice(input, dict);
  gpr_slice decoded_output;
  // encoder must always produce decodable output
  GPR_ASSERT(gpr_strict_percent_decode_slice(output, dict, &decoded_output));
  gpr_slice permissive_decoded_output =
      gpr_permissive_percent_decode_slice(output);
  // and decoded output must always match the input
  GPR_ASSERT(gpr_slice_cmp(input, decoded_output) == 0);
  GPR_ASSERT(gpr_slice_cmp(input, permissive_decoded_output) == 0);
  gpr_slice_unref(input);
  gpr_slice_unref(output);
  gpr_slice_unref(decoded_output);
  gpr_slice_unref(permissive_decoded_output);
  counters = grpc_memory_counters_snapshot();
  grpc_memory_counters_destroy();
  GPR_ASSERT(counters.total_size_relative == 0);
}
Exemple #3
0
int main(int argc, char **argv) {
  grpc_memory_counters_init();
  grpc_slice slice = grpc_slice_from_copied_string("x");
  char *fake_argv[1];

  char *target = "localhost:443";
  gpr_cmdline *cl;
  grpc_event event;

  grpc_init();

  GPR_ASSERT(argc >= 1);
  fake_argv[0] = argv[0];
  grpc_test_init(1, fake_argv);

  int warmup_iterations = 100;
  int benchmark_iterations = 1000;

  cl = gpr_cmdline_create("memory profiling client");
  gpr_cmdline_add_string(cl, "target", "Target host:port", &target);
  gpr_cmdline_add_int(cl, "warmup", "Warmup iterations", &warmup_iterations);
  gpr_cmdline_add_int(cl, "benchmark", "Benchmark iterations",
                      &benchmark_iterations);
  gpr_cmdline_parse(cl, argc, argv);
  gpr_cmdline_destroy(cl);

  for (size_t k = 0; k < GPR_ARRAY_SIZE(calls); k++) {
    calls[k].details = grpc_empty_slice();
  }

  cq = grpc_completion_queue_create(NULL);

  struct grpc_memory_counters client_channel_start =
      grpc_memory_counters_snapshot();
  channel = grpc_insecure_channel_create(target, NULL, NULL);

  int call_idx = 0;

  struct grpc_memory_counters before_server_create = send_snapshot_request(
      0, grpc_slice_from_static_string("Reflector/GetBeforeSvrCreation"));
  struct grpc_memory_counters after_server_create = send_snapshot_request(
      0, grpc_slice_from_static_string("Reflector/GetAfterSvrCreation"));

  // warmup period
  for (call_idx = 0; call_idx < warmup_iterations; ++call_idx) {
    init_ping_pong_request(call_idx + 1);
  }

  struct grpc_memory_counters server_benchmark_calls_start =
      send_snapshot_request(
          0, grpc_slice_from_static_string("Reflector/SimpleSnapshot"));

  struct grpc_memory_counters client_benchmark_calls_start =
      grpc_memory_counters_snapshot();

  // benchmark period
  for (; call_idx < warmup_iterations + benchmark_iterations; ++call_idx) {
    init_ping_pong_request(call_idx + 1);
  }

  struct grpc_memory_counters client_calls_inflight =
      grpc_memory_counters_snapshot();

  struct grpc_memory_counters server_calls_inflight = send_snapshot_request(
      0, grpc_slice_from_static_string("Reflector/DestroyCalls"));

  do {
    event = grpc_completion_queue_next(
        cq, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
                         gpr_time_from_micros(10000, GPR_TIMESPAN)),
        NULL);
  } while (event.type != GRPC_QUEUE_TIMEOUT);

  // second step - recv status and destroy call
  for (call_idx = 0; call_idx < warmup_iterations + benchmark_iterations;
       ++call_idx) {
    finish_ping_pong_request(call_idx + 1);
  }

  struct grpc_memory_counters server_calls_end = send_snapshot_request(
      0, grpc_slice_from_static_string("Reflector/SimpleSnapshot"));

  struct grpc_memory_counters client_channel_end =
      grpc_memory_counters_snapshot();

  grpc_channel_destroy(channel);
  grpc_completion_queue_shutdown(cq);

  do {
    event = grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
                                       NULL);
  } while (event.type != GRPC_QUEUE_SHUTDOWN);
  grpc_slice_unref(slice);

  grpc_completion_queue_destroy(cq);
  grpc_shutdown();

  gpr_log(GPR_INFO, "---------client stats--------");
  gpr_log(GPR_INFO, "client call memory usage: %f bytes per call",
          (double)(client_calls_inflight.total_size_relative -
                   client_benchmark_calls_start.total_size_relative) /
              benchmark_iterations);
  gpr_log(GPR_INFO, "client channel memory usage %zi bytes",
          client_channel_end.total_size_relative -
              client_channel_start.total_size_relative);

  gpr_log(GPR_INFO, "---------server stats--------");
  gpr_log(GPR_INFO, "server create: %zi bytes",
          after_server_create.total_size_relative -
              before_server_create.total_size_relative);
  gpr_log(GPR_INFO, "server call memory usage: %f bytes per call",
          (double)(server_calls_inflight.total_size_relative -
                   server_benchmark_calls_start.total_size_relative) /
              benchmark_iterations);
  gpr_log(GPR_INFO, "server channel memory usage %zi bytes",
          server_calls_end.total_size_relative -
              after_server_create.total_size_relative);

  grpc_memory_counters_destroy();
  return 0;
}
Exemple #4
0
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  grpc_test_only_set_metadata_hash_seed(0);
  struct grpc_memory_counters counters;
  if (squelch) gpr_set_log_function(dont_log);
  grpc_memory_counters_init();
  grpc_init();
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  grpc_endpoint *mock_endpoint = grpc_mock_endpoint_create(discard_write);

  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
  grpc_transport *transport =
      grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 1);
  grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);

  grpc_channel *channel = grpc_channel_create(
      &exec_ctx, "test-target", NULL, GRPC_CLIENT_DIRECT_CHANNEL, transport);
  grpc_call *call =
      grpc_channel_create_call(channel, NULL, 0, cq, "/foo", "localhost",
                               gpr_inf_future(GPR_CLOCK_REALTIME), NULL);

  grpc_metadata_array initial_metadata_recv;
  grpc_metadata_array_init(&initial_metadata_recv);
  grpc_byte_buffer *response_payload_recv = NULL;
  grpc_metadata_array trailing_metadata_recv;
  grpc_metadata_array_init(&trailing_metadata_recv);
  grpc_status_code status;
  char *details = NULL;
  size_t details_capacity = 0;

  grpc_op ops[6];
  memset(ops, 0, sizeof(ops));
  grpc_op *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_CLOSE_FROM_CLIENT;
  op->flags = 0;
  op->reserved = NULL;
  op++;
  op->op = GRPC_OP_RECV_INITIAL_METADATA;
  op->data.recv_initial_metadata = &initial_metadata_recv;
  op->flags = 0;
  op->reserved = NULL;
  op++;
  op->op = GRPC_OP_RECV_MESSAGE;
  op->data.recv_message = &response_payload_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->data.recv_status_on_client.status_details_capacity = &details_capacity;
  op->flags = 0;
  op->reserved = NULL;
  op++;
  grpc_call_error error =
      grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(1), NULL);
  int requested_calls = 1;
  GPR_ASSERT(GRPC_CALL_OK == error);

  grpc_mock_endpoint_put_read(
      &exec_ctx, mock_endpoint,
      gpr_slice_from_copied_buffer((const char *)data, size));

  grpc_event ev;
  while (1) {
    grpc_exec_ctx_flush(&exec_ctx);
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    switch (ev.type) {
      case GRPC_QUEUE_TIMEOUT:
        goto done;
      case GRPC_QUEUE_SHUTDOWN:
        break;
      case GRPC_OP_COMPLETE:
        requested_calls--;
        break;
    }
  }

done:
  if (requested_calls) {
    grpc_call_cancel(call, NULL);
  }
  for (int i = 0; i < requested_calls; i++) {
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
  }
  grpc_completion_queue_shutdown(cq);
  for (int i = 0; i < requested_calls; i++) {
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
  }
  grpc_call_destroy(call);
  grpc_completion_queue_destroy(cq);
  grpc_metadata_array_destroy(&initial_metadata_recv);
  grpc_metadata_array_destroy(&trailing_metadata_recv);
  gpr_free(details);
  grpc_channel_destroy(channel);
  if (response_payload_recv != NULL) {
    grpc_byte_buffer_destroy(response_payload_recv);
  }
  grpc_shutdown();
  counters = grpc_memory_counters_snapshot();
  grpc_memory_counters_destroy();
  GPR_ASSERT(counters.total_size_relative == 0);
  return 0;
}
Exemple #5
0
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  grpc_test_only_set_slice_hash_seed(0);
  struct grpc_memory_counters counters;
  if (squelch) gpr_set_log_function(dont_log);
  if (leak_check) grpc_memory_counters_init();
  grpc_init();
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_executor_set_threading(&exec_ctx, false);

  grpc_resource_quota *resource_quota =
      grpc_resource_quota_create("server_fuzzer");
  grpc_endpoint *mock_endpoint =
      grpc_mock_endpoint_create(discard_write, resource_quota);
  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
  grpc_mock_endpoint_put_read(
      &exec_ctx, mock_endpoint,
      grpc_slice_from_copied_buffer((const char *)data, size));

  grpc_server *server = grpc_server_create(NULL, NULL);
  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
  grpc_server_register_completion_queue(server, cq, NULL);
  // TODO(ctiller): add registered methods (one for POST, one for PUT)
  // void *registered_method =
  //    grpc_server_register_method(server, "/reg", NULL, 0);
  grpc_server_start(server);
  grpc_transport *transport =
      grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 0);
  grpc_server_setup_transport(&exec_ctx, server, transport, NULL, NULL);
  grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);

  grpc_call *call1 = NULL;
  grpc_call_details call_details1;
  grpc_metadata_array request_metadata1;
  grpc_call_details_init(&call_details1);
  grpc_metadata_array_init(&request_metadata1);
  int requested_calls = 0;

  GPR_ASSERT(GRPC_CALL_OK ==
             grpc_server_request_call(server, &call1, &call_details1,
                                      &request_metadata1, cq, cq, tag(1)));
  requested_calls++;

  grpc_event ev;
  while (1) {
    grpc_exec_ctx_flush(&exec_ctx);
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    switch (ev.type) {
      case GRPC_QUEUE_TIMEOUT:
        goto done;
      case GRPC_QUEUE_SHUTDOWN:
        break;
      case GRPC_OP_COMPLETE:
        switch (detag(ev.tag)) {
          case 1:
            requested_calls--;
            // TODO(ctiller): keep reading that call!
            break;
        }
    }
  }

done:
  if (call1 != NULL) grpc_call_unref(call1);
  grpc_call_details_destroy(&call_details1);
  grpc_metadata_array_destroy(&request_metadata1);
  grpc_server_shutdown_and_notify(server, cq, tag(0xdead));
  grpc_server_cancel_all_calls(server);
  for (int i = 0; i <= requested_calls; i++) {
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
  }
  grpc_completion_queue_shutdown(cq);
  for (int i = 0; i <= requested_calls; i++) {
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
  }
  grpc_server_destroy(server);
  grpc_completion_queue_destroy(cq);
  grpc_shutdown();
  if (leak_check) {
    counters = grpc_memory_counters_snapshot();
    grpc_memory_counters_destroy();
    GPR_ASSERT(counters.total_size_relative == 0);
  }
  return 0;
}